Welcome to MorphOS-Storage, a webserver dedicated to MorphOS users. ©2016-2024 Meta-MorphOS.org
Description:Breaker 2.1 port by ACE - Need PowerSDL
Developer/Porter:Ace - Pur3lam3rs
Readme:

Casse Briques de type Arkanoid.
Done by Cl�ment CORDE.
Contact : c1702@yahoo.com

Portage Morphos par Ace of Da Pur3lam3rs group.
aceofbonal@gmail.com
For an unkown reason fullscreen display is not working
> Histoire :

Il y a de �a quelques ann�es, j'ai travaill� dans le jeu vid�o (fort mauvaise exp�rience du reste). N'ayant jamais programm� de casse briques, je comptais � la base juste programmer un petit casse briques pour moi dans mon coin, et c'est ce que j'ai fait. Un de mes coll�gues avait l'air int�ress� par le projet, donc je lui ai propos� de lui donner les sources pour qu'il puisse voir coment j'avais proc�d�. Ce m�me coll�gue m'a sugg�r� de mettre mes sources en ligne, car selon lui, �a pourrait int�resser du monde. Je suis un peu sceptique sur ce point, mais si �a peut servir � quelqu'un un, tant mieux !

Je ne pense pas qu'il y ait rien de r�volutionnaire dans ce code, mais il contient quelques principes qui pourront peut-�tre donner une orientation � des gens commen�ant la programmation (attention, je ne me pose pas comme expert pour autant !) : Comment g�rer des sprites, des anims, des monstres, des tirs, etc... Du moins, c'est une fa�on de faire les choses. Et puis il y a quand m�me quelques petites astuces !


> License :

Je n'ai pas la pr�tention que ce code soit bon, puissant, ou quoi que ce soit. En revanche, il fonctionne. Je distribue les sources pour que les gens puissent s'en inspirer, peut-�tre y trouver des astuces, voire r�utiliser une partie du code. Dans ce dernier cas, il est bien entendu que cel� doit rester dans un cadre non commercial ! Dans le cas contraire, vous �tes pri�s de me contacter avant.

Et pour ceux � qui ce code aura �t� utile, un p'tit greeting quelque part, c'est toujours sympa ! (^_^)


> Copyrights :

Non, pas les miens ! :)

Comme j'ai fait �a pour moi et que je ne suis pas graphiste, j'ai r�cup�r� des graphs comme j'ai pu, afin d'en avoir le moins possible � dessiner moi m�me. Pour un casse briques, Arkanoid parassait tout indiqu�. Mais ceci veut dire qu'une partie des graphismes sont probablement sous copyright (Taito ?). Comme le but n'est absolument pas de faire du profit, on va esp�rer que je ne serai pas emb�t�.

Les monstres, les explosions, les contours des niveaux et la base de la raquette viennent de la version Atari ST.
Les arri�re plans viennent du site StrategyWiki (http://strategywiki.org/wiki/Arkanoid/Walkthrough).
La fonte a �t� trouv�e sur le site de Daniel Guldkrans (http://www.algonet.se/~guld1/freefont.htm), et l�g�rement retouch�e par mes soins pour les besoins du jeu.
Tous les autres graphismes par moi m�me.

Les sons ont �t� trouv�s sur diff�rents sites distribuant des WAVs libres de droit, puis ont �t� modifi�s/acc�l�r�s/coup�s par moi m�me.
Seul un son utilis� est peut-�tre sous copyright (Taito ?), il s'agit de l'extra life, provenant de la borne d'arcade Arkanoid, et ripp� pour moi par Mr Stan.

Petite pr�cision : Le but n'�tait pas de faire un clone strict d'Arkanoid, m�me si au final �a y ressemble. Donc ne vous �tonnez pas s'il y a quelques diff�rences.


> Touches :

r: Switch 1x/2x (d�faut).
f: Switch Full screen/Windowed.


> Questions :

Je r�pondrai par mail (c1702@yahoo.com) autant que possible � d'�ventuelles questions, mais veillez � pr�ciser un objet bien clair. La raison est que je re�ois pas mal de spam, et qu'�videment, je ne lis pas ce spam avant de l'effacer. Alors si vous m'envoyez un mail, �vitez de mettre en objet 'viagra' !


> SDL :

Le jeu utilise SDL au minimum. Je suppose qu'on doit pouvoir faire plein de trucs super avec SDL, mais ce n'�tait pas mon but. Je n'avais pas cod� quelque chose ressemblant � un jeu depuis longtemps, je voulais donc voir si je n'avais pas tout oubli�. Donc en gros, je me sers de SDL pour obtenir un buffer en vid�o et blitter dedans, en 256 couleurs parce que c'est ce que je voulais, que les modes 256 couleurs sont faciles � g�rer et ont des palettes. SDL me sert aussi � lire les images au format BMP parce que je n'avais pas envie de faire un loader de BMP (m�me si �a ne doit pas �tre bien sorcier). Sinon, tout est fait � la main.


> Son :

J'ai fait le minimum : Il s'agit de la routine d'exemple SDL � peine modifi�e pour g�rer deux canaux et une priorit�. La priorit� permet de ne pas avoir � se soucier des sons qu'on lance : Une explosion � une priorit� plus �lev�e qu'un bruit de rebond. Donc le rebond ne coupera pas le son de l'explosion. (Bon, y'a deux canaux quand m�me !).


> Compilation :

J'utilise Code::Blocks sous Windows XP, avec gcc et SDL.

Je n'ai pas inclus le fichier projet pour la raison suivante : Comme il y a peu de chances que vos r�pertoires soient les m�mes que les miens, le projet ne se lirait de toutes fa�ons probablement pas.

Cr�ez un nouveau projet SDL, copiez tous les fichiers sources ainsi que le r�pertoire "gfx" dans le r�pertoire du projet, incluez tous les fichiers sources au projet, et �a devrait fonctionner.

Options de compilation :
-Wall : Voir tous les warnings.
-O3 : Optimisation du code pour la vitesse.
-DNDEBUG (= #define NDEBUG) : En mode release, pour que les asserts ne soient plus compil�s.

Le fichier "includes.h". Oui, je sais, il parait que �a ne se fait pas. Moi je trouve �a pratique parce que �a ne me fait inclure qu'un fichier ".h" dans chaque ".c". L'effet chiant, c'est que quand on touche un ".h", on est bon pour recompiler tout le projet. Mais bon, ledit projet n'est pas �norme. Et puis si vous voulez, rien ne vous em�che de refaire les inclusions vous m�mes ! :)

Le jeu est cod� en C. Pourquoi pas en C++ ? Parce que je voulais faire les choses d'une certaine fa�on, et que je n'avais pas grand chose � gagner � utiliser du C++. Maintenant si �a vous amuse de tout repasser en C++, avec des classes, des m�thodes et tout et tout, rien ne vous en emp�che (le code est assez compartiment�, �a ne devrait pas �tre trop violent).

Un "Makefile" est inclus pour une compilation sous Linux. J'ai essay� rapidement avec une Debian 5, et �a semblait marcher correctement.


> Code :

* Nomenclature utilis�e :

Variables num�riques pr�c�d�es de 'n'.
Pointeurs pr�c�d�s de 'p'.
Variables g�n�rales pr�c�d�es de 'g'.
Puis noms de variables commen�ant par une majuscule.

Exemples :
u32 nMonEntier;
u32 pMonTableau[NB_ELEMENTS];
u32 *pPtr;
u32 **ppPtr; < pp car pointeur de pointeur.
u32 gnMonEntierGeneral;
etc...

Exceptions : Les indices de boucle. L� c'est plut�t i, j, k, ix, iy...


> Petits probl�mes :

* Le scroll du d�cor dans les menus :
Je ne peux pas expliquer pourquoi, mais sur certaines machines, le scroll n'est pas smooth (J'ai le probl�me sur ma vieille machine, sur laquelle je d�veloppe). J'ai l'impression que le refresh n'attend pas le vblank et tombe n'importe quand. Je ne suis pas un un expert de SDL, mais � lire l'explication de SDL_FLIP(), c'est peut-�tre que l'init hardware du 320x240 en 256 couleurs n'est pas support�e par le hard, et qu'alors le SDL_Flip() se comporte comme un SDL_UpdateRect() et n'attend pas le retrace ? Pour enlever les scrollings, commentez la ligne "#define MENU_Bkg_Mvt 1" en haut du fichier "menu.cpp".

* Le mode full-screen (F10) :
Semble poser des probl�mes avec les config double �cran, de plus en plus courantes (probl�me SDL ?). Si vous n'avez qu'un �cran (comme moi), �a devrait fonctionner.

* Briques incassables et grosses balles :
Voil� deux choses difficilement mixables. Je m'explique, quand une balle grossit (point de r�f�rence de la balle au centre), si une partie de la balle est dans une brique incassable, d�j�, le recalage est p�nible � faire. Si en plus de �a la balle �tait entre deux briques incassables suffisement rapproch�es et que l'espace entre les deux briques devient inf�rieur � celui du diam�tre de la balle, l�, �a devient ing�rable (graphiquement, �a ne peut pas marcher). Donc, dans les niveaux ou il y a des briques incassables, je n'ai pas mis de bonus "grosse balle". Probl�me regl�. Vous vous dites que c'est une solution de lamer ? Je vous pose alors la question : Si je ne vous l'avais pas dit, l'auriez-vous remarqu� ? Cr�er les niveaux de fa�on � �viter les probl�mes est une solution utilis�e dans les jeux vid�o plus fr�quement que ce qu'on imagine.


> Niveaux :

Pour les niveaux, je n'avais pas l'envie ni le temps de faire un �diteur de niveaux. En m�me temps, je n'allais certainement pas non plus remplir plus de 30 tables de nombres � la main, comme certains le font. Je suis donc pass� par un fichier BMP (levels.bmp).

La planche est s�par�e en blocs de 16x20, chaque bloc repr�sentant un niveau. L'espace utile est 15x17. Chaque point repr�sente une brique : Couleurs 1 � 10 pour les briques normales, 16 � 18 pour les briques sp�ciales.

Les 2 derni�res lignes (soit une table de 32 �l�ments) repr�sentent une table de bonus distribu�s au hasard dans le niveau (voir sur la partie droite du fichier BMP pour explications, couleurs � partir de 128). Avec ce syst�me, on peut choisir quelles items tombent selon le niveau. Par exemple, on peut limiter le nombre d'items diff�rents dans les premiers niveaux et l'augmenter au fur et � mesure.

Les niveaux sont captur�s de gauche � droite et de haut en bas. Si le premier point rencontr� dans un bloc 16x20 n'est pas de couleur 0, le niveau est captur�.

Toutes les tables sont g�n�r�s par le projet "brk_lev", dans le fichier "stdout.txt" et incluses dans le fichier "levels.h". Le code est simplissime � comprendre, vous verrez d'ailleurs que je me suis seulement content� de rajouter une routine (CreateLevels()) dans le code de base g�n�r� quand on cr�� un projet "SDL".

Il faut juste penser � mettre le "#define LEVEL_Max xx" dans breaker.h.

Les niveaux sont ceux du premier Arkanoid (merci au site strategywiki pour le layout), adapt�s � la taille de l'aire de jeu (qui est plus large ici), et aussi au fait que la balle ici est plus grosse que celle d'Arkanoid, ce qui rendait certains niveaux tr�s/trop difficiles. Par exemple le niveau 3, la balle ne s'engageait pas dans un interstice de 1 brique de haut. Du coup, non seulement �a devenait tr�s difficile, mais aussi tr�s chiant.


> Jeu :

Pour les rebonds sur la raquette, je me suis inspir� de ce que j'ai vu sur Arkanoid I : La balle est renvoy�e selon la position � laquelle elle touche la raquette. Le mouvement n'est pas pris en compte, donc ne vous acharnez pas � mettre de l'effet.

J'ai laiss� au joueur le choix du niveau de d�part (comme sur Amiga !). Je l'ai limit� sur les 12 premiers niveaux, mais vous pouvez recompiler en mettant : #define LEVEL_SELECT_Max (LEVEL_Max - 1) au lieu de #define LEVEL_SELECT_Max (12 - 1) dans breaker.h, ce qui permet alors de commencer � n'importe quel niveau.

Note � propos des briques qui reviennent : Je pensais faire �a au d�but, et finalement, j'ai impl�ment� le truc juste � la fin. Du coup, il n'y en a qu'une au niveau 2, et c'est tout. Mais �a fonctionne.


> Doh :

Plusieurs petits trucs � dire.

D'abord, je n'ai jamais atteint ce niveau en jouant � l'�poque, donc je ne sais pas comment se comportait ce monstre. C'est donc un comportement compl�tement invent�.

Je n'avais pas de sprites pour le boss. Sur un des �crans du site strategywiki, j'ai r�cup�r� une frame ou Doh avait la bouche ouverte. J'ai tant bien que mal dessin� une image o� il a la bouche ferm�e. Par contre, faire l'anim de transition, c'est un peu trop difficile pour moi. L� encore, si quelqu'un se d�voue, je suis preneur ! :)


> Sprites :

Les sprites sont captur�s au lancement du jeu, depuis des fichiers BMP.

Les sprites dans ce jeu sont tr�s simples, ils ne poss�dent m�me pas de zone de collision en plus de leur rectangle englobant. La bonne id�e que nous utilisions dans le jeu vid�o �tait de passer par le format PSD (photoshop), qui permet de rajouter des couches alpha � volont�, et est assez simple � d�coder (en 256 couleurs !). On peut alors rajouter des zones de collisions diff�rentes et plein d'autres choses utiles. Dans ce jeu, hormis les balles (qui sont test�es au pixel), tout est relativement carr� et je n'avais pas vraiment besoin de zones de collisions suppl�mentaires. Je me suis donc content� d'un BMP, que SDL permet de lire facilement. (Note: Un loader de PSD est en pr�paration. Je m'en servirai dans un prochain projet).

Dans un "vrai" jeu vid�o, on ne capturerait pas les sprites de cette fa�on. On g�n�rerait des fichiers avec un outil, ce qui permet entre autres de les compresser. Comme le r�sultat de la capture sera tout le temps le m�me, le faire en temps r�el pr�sente peu d'int�r�t. Ceci �viterait aussi d'avoir � saisir � la main les "e_Spr_xxx" du fichier "sprites.h". Mais ceci prend du temps, et je voulais faire un truc simple, sans avoir � d�bugger des programmes externes en plus.

Techniquement, quand un sprite est captur�, on g�n�re un masque inverse (un rectangle de la m�me taille que le sprite) : Pour chaque pixel du sprite, 0xFF s'il n'y a rien a afficher, 0 si il y a un pixel. Au moment de l'affichage, on fait un trou � l'emplacement du sprite avec un AND du fond et du masque inverse, puis on poke les pixels du sprite avec un OR entre le sprite et le fond (trou�).

* Comment rajouter des sprites ?

L�, il faut bien faire une diff�rence entre un sprite et une animation. Bien s�r, les animations sont compos�es de sprites, mais les gestions sont compl�tement s�par�es.

- Rajout d'un sprite :

Pour commencer simplement, dans une planche existante (�a sera plus simple pour les palettes), rajoutez votre sprite. Il doit �tre contenu dans un rectangle de couleur 0 (le violet CGA). Les encoches sur les c�t�s haut et gauche indiquent le point de r�f�rence du sprite. L'arri�re plan de la planche doit �tre de couleur 255.

Il faut ensuite le rajouter dans la liste qui se trouve dans le fichier "sprites.h", au bon endroit (ordre de capture), et mettre � jour le "cha�nage" (un sprite � un num�ro relatif au sprite qui le pr�c�de).

Voil�, le sprite est int�gr�. On peut d�j� l'afficher : Pour ce faire, utilisez la fonction :
void SprDisplay(u32 nSprNo, s32 nPosX, s32 nPosY, u32 nPrio);
avec :
nSprNo = Le num�ro du sprite (e_Spr_<qque chose>).
nPosX, nPosY = Position sur l'�cran (et (0,0) = coin sup�rieur gauche).
nPrio = Priorit�, de 0 (en dessous de tout) � 255 (au dessus de tout).

- Rajouter d'une animation :

Une fois que vous avez int�gr� tous les sprites, il faut d�finir une anim. Ca se passe dans les fichiers "anims.cpp" et "anims.h".

Dans "anims.cpp", on d�finit une table.

La structure est tr�s simple :
1 clef d'animation (nous y reviendrons plus tard), puis
nombre de frames d'affichage, num�ro du sprite � afficher (ceci r�p�t� autant de fois que n�cessaire).
On peut aussi rajouter des codes de contr�le, suivi d'une valeur (qui d�pend du code).

5 codes sont d�finis pour le moment :
e_Anm_Jump : Saut dans une anim.
e_Anm_Goto : Initialise une autre anim.
e_Anm_End : Fin d'une anim, AnmGetImage() renverra SPR_NoSprite, et le flag e_AnmFlag_End sera positionn� (interrogation avec AnmCheckEnd()). Le slot d'anim n'est pas lib�r�.
e_Anm_Kill : Fin d'une anim. Renvoie -1 et lib�re le slot (ex: dust).
e_Anm_Sfx : Joue un son. Ca peut �tre tr�s pratique : Si l'anim est d�clench�e, elle jouera aussi le son qui lui est associ�, et sans toucher une ligne de code.

Il faut ensuite d�clarer la table dans "anims.h" : extern u32 gAnm_<Nom de l'anim>[];

Apr�s, on peut l'utiliser : On initialise une anim dans un slot, et � chaque frame on fait un AnmGetImage() du slot, qui renverra le num�ro du sprite � afficher.

Initialisation :
NoDeSlot = AnmSet(gAnm_<Nom de l'anim>, NoDeSlot ou -1 pour une nouvelle anim);
Il y a aussi AnmSetIfNew().

La diff�rence, AnmSetIfNew() initialise une anim seulement si l'animation pass�e en param�tre est nouvelle ET si la clef d'animation le permet (priorit� au moins �gale � celle de l'anim en cours).

Mais c'est quoi, cette clef d'animation ?

D'abord, comme on peut la r�cup�rer � tout moment (AnmGetKey()), on peut s'en servir pour diff�rencier des anims.

Pas clair ? Exemple : Les anims du joueur ont pour la plupart une clef e_AnmKey_Null. Quand il est en train de mourir (et qu'il faut l'emp�cher de bouger), l'anim a alors une clef e_AnmKey_PlyrDeath. Dans la routine Brk_MovePlayer du fichier "breaker.cpp", on teste la mort avec la ligne suivante :
if (AnmGetKey(gBreak.nPlayerAnmNo) == e_AnmKey_PlyrDeath) ...

La clef d'animation est compos�e de deux parties : Une priorit� (16 bits de poids fort) et un identifiant (16 bits de poids faible).

L� ou �a peut devenir utile, exemple :
Un personnage est au repos. Bouton de tir, anim de tir avec une priorit� sup�rieure � celle du repos, l'anim est mise en place. Jusque l�, on n'en pas besoin de priorit�s, d'accord. Mais quand doit on remettre l'anim de repos ? Avec ce syst�me, on peut appeler AnmSetIfNew() tout le temps, l'anim de repos ne sera remise en place que lorsque l'anim de tir sera termin�e. La gestion est simplifi�e : Par d�faut, on essayera de mettre une anim de repos. Si le perso doit tirer, on essaye de mettre l'anim de tir. Si on peut, le perso tire, et cette anim de pourra �tre interrompue que par une anim de priorit� sup�rieure (un hit ou la mort, par exemple).

Ce syst�me ne r�gle pas tous les probl�mes, mais c'est une aide sympathique.


> Monstres :

Voil� comment �a se passe : La gestion se passe dans mst.cpp. Le code des monstres proprement dits se trouve dans monsters.cpp.

Gestion : Il y a une table contenant x slots (comme pour les tirs, les dusts...). Chaque slot correspond � un monstre.

Chaque slot a une taille fixe, voir la struct SMstCommon dans mst.h. On voit dans cette structure que les monstres ont un certain nombre de variables communes. Pour les variables particuli�res, on utilise la table pData[64], qui laisse 64 octets de donn�es sp�cifiques pour chaque monstre. Si 64 octets vous semble peu, je vous le dis tout ce suite, c'est au contraire surdimensionn�. Mais sur un PC, l'espace m�moire est infini !

Ensuite, on a les monstres. Ils ont une fonction d'initialisation, et une fonction principale (appel�e toutes les frames quand le monstre est actif).

Lorsqu'ils ont besoin de variables sp�cifiques, on fait pointer une structure sp�cifique sur la zone pData. Ca se passe comme �a :
SMstDoh *pSpe = (SMstDoh *)pMst->pData;

Note : Il faut faire super attention � la taille des structures sp�cifiques, si elles sont trop grandes, il y aura un ph�nom�ne de recouvrement (la fin des donn�es d'un slot qui d�bordent sur le slot suivant), et une belle merde � d�bugger... La fonction MstCheckStructSizes() � la fin du fichier monsters.cpp sert � �a. Pour ne plus compiler les asserts en release, il faut sp�cifier -DNDEBUG au compilateur.

Les monstres fonctionnent avec une phase, je vous laisse regarder, je trouve �a pratique.

Pour d'autres types de jeu, un shoot'em up par exemple, il y a une gestion � rajouter : la gestion des ennemis qui arrivent (avec le scroll en g�n�ral), et ceux qu'il faut �liminer (les ennemis le feront eux-m�mes).


> Tirs :

Une table avec des slots, et un FireManage() a appeler � chaque frame.

Ici, la gestion des tirs qui sortent de l'�cran est simplifi�e du fait que les tirs du joueur ne font que monter, et que les tirs du boss ne font que descendre.

Ce qu'il faut savoir pour les tirs, c'est que ce ne sont pas les tirs qui testent les monstres, ce sont les monstres qui testent les tirs. Et ce n'est pas la m�me chose. Par exemple, le monstre "porte" (pour sortir d'un niveau) ne viendra jamais tester les tirs. Dans d'autres contextes, des monstres "endormis" (inactifs) ou en train de mourir ne viendront pas non plus tester les tirs. Seuls les monstres concern�s feront le test, c'est plus rapide, et beaucoup plus simple.

Le petit truc int�ressant � regarder, c'est la variable gnFireLastUsed dans les routines FireGetSlot() et FireReleaseSlot(), qui permet d'acc�l�rer la recherche d'un slot libre au lieu de scanner la table depuis le d�but � chaque fois. Ce truc est utilis� � chaque fois qu'il y a une table de ce type (tirs, dusts, etc...).


> Dusts :

Juste un petit point sur ces fameux "dusts". Qu'est ce que c'est ?

En fait, � l'�poque ou je travaillais dans le jeu, on utilisait �a pour g�rer facilement plein de petits effets facilement. La premi�re personne qui avait utilis� �a l'avait fait pour afficher des "poussi�res" (dust en anglais) pour un personnage � la r�ception d'un saut. Le nom est rest�.

Cette liste est bien pratique : Les dusts ont leur vie propre, et on ne s'en occupe plus jamais. On peut y mettre n'importe quoi, comme de la fum�e derri�re un missile par exemple... Dans ce jeu, j'y mets les anims de disparition des briques, les explosions des ennemis (qui ne font pas de d�gats, donc pas besoin de g�n�rer un nouveau tir)...

Le syst�me est customisable � volont�. On peut imaginer donner une direction et une vitesse aux dusts, si n�c�ssaire.


> Opacit� (ombres) :

J'ai fait les ombres au plus simple : Technique du shade bob, � savoir un add (ici, +6).

Il faut penser un peu au truc avant de le faire, parce que les palettes des d�cors doivent �tre organis�es en cons�quence. Regardez la palette du d�cor n�1 (qui contient toutes les palettes des d�cors). Chaque d�cor utilise au max 6 couleurs pour sa partie claire. On r�serve 6 couleurs de plus pour les ombres. Enfin, on r�serve encore 6 couleurs pour les ombres des ombres (J'y reviendrai plus tard). Total : 18 couleurs r�serv�es pour chaque level.

Pour afficher une ombre, on commence comme pour un sprite, on fait un trou sur la destination l� o� doit �tre affich�e l'ombre. Puis on r�cup�re les pixels de l'emlacement du trou sur l'image ORIGINALE du d�cor (pas le double buffer), auxquels on ajoute 6 et on poke �a sur la destination.

R�sultat :
Les couleurs normales se retrouvent 6 couleurs plus loin dans la palette, soit la couleur des ombres.
Les couleurs des ombres se retrouvent 6 couleurs plus loin, soit dans les palettes des ombres des ombres, qui sont les m�mes couleurs que les ombres, et hop, le tour est jou�.
Une couleur claire devient une ombre, une ombre reste une ombre.

Avec cette m�thode, on peut superposer plusieurs ombres, �a fonctionnera toujours, puisque la source est toujours l'image ORIGINALE.

Ca � l'air compliqu�, mais c'est juste un jeu de AND, OR et NOT. Regardez dans la fonction SprDisplayLock() (fichier sprites.cpp).

La routine, en fonction d'un flag, affiche soit une ombre, soit un sprite normal.

Ensuite, j'avais le choix entre plusieurs m�thodes pour prendre en compte les ombres.
- Soit � chaque fois que j'affichais un sprite, j'en affichais un autre d�cal� avec le flag d'ombre. Avantage : On peut sur chaque ombre mettre un d�calage diff�rent. Inconv�nient : Il y a un double appel � la fonction SprDisplay(), donc plus de sprites � trier. De plus, les ombres �tant affich�es toujours derri�re tous les autres sprites, on les trie un peu pour rien...
- Soit, et c'est ce que j'ai choisi de faire, je rajoutais le flag ombre quand je voulais afficher un sprite et son ombre. Chaque sprite, ombr� ou non n'est donc tri� qu'une fois. Le SprDisplayAll() fait deux passes : Une premi�re pour afficher toutes les ombres (en dessous des autres sprites, donc), et une seconde pour les sprites normaux. Inconv�nient : Toutes les ombres ont le m�me d�calage (puisque donn� dans la fonction SprDisplayAll()). Avantage : Gestion super simple, juste un flag � rajouter (avec un OR) quand on veut une ombre. Pas de double appel � SprDisplay(). Enfin, �a permet de rajouter des ombres dans les dusts (disparition de brique) sans rien retoucher � la routine de gestion des dusts. J'ai simplement rajout� le flag ombre dans l'anim en question.

On peut tr�s facilement repasser de la m�thode 2 � la m�thode 1, il suffit de retirer la boucle pour afficher les ombres de la fonction SprDisplayAll().

Note : Pour ceux qui voudraient faire de la "vraie" opacit� sur une image 256 couleurs, il faut passer par des CLUT (Color Look Up Table, cherchez avec google). Ce n'est pas tr�s compliqu� � mettre en oeuvre, mais dans ce projet �a ne m'apportait rien.


> Pour "timer" une routine :

Evidement, maintenant on ne peut plus timer une routine au raster (c�d changer la couleur 0 eu d�but de la routine et la remettre � sa valeur apr�s). Au d�but, je pensais faire �a avec SDL_GetTicks(), en en mettant un avant et un apr�s le bout de code � timer. Manque de bol, les bouts de code � tester sont souvent tellement petits ou tellement rapides que la diff�rence vaut tr�s souvent 0.

Donc je fais �a avec le bout de code ci dessous (windows only), qui est beacoup plus pr�cis :

>>>
#include <windows.h>

Dans la fonction :

LARGE_INTEGER a,b,c;
QueryPerformanceFrequency(&c);
QueryPerformanceCounter(&a);

[Partie � timer]

QueryPerformanceCounter(&b);
printf("%d %d %d\n", (int)(b.QuadPart - a.QuadPart), (int)a.QuadPart, (int)b.QuadPart);
<<<

Ca peut servir ! :)


> Pr�calculs :

J'ai juste pr�calcul� une table de sinus et de cosinus, sur 256 valeurs.

Il y a d'autres pr�calculs faisables :

Une table de SCR_Width �l�ments et une de SCR_Height �l�ments, pour savoir imm�diatement sur quelle brique on va taper � la position (x,y). Ceci �viterai plein de divisions (et les divisions, c'est mal !). Note : Pourquoi n'ai-je pas choisi une taille de briques maline, comme 16 pixels par exemple ? Comme c'est pour PC et que les PC ont plein de megahertz, j'ai pris une taille que je trouvais jolie (24 pixels), � d�faut d'�tre pratique. Je pensais faire les tables sus-cit�es par la suite, mais en fait �a ne rame pas du tout. Donc je ne l'ai pas fait.
Note additionnelle : J'ai essay� de mettre en place cette table, et les r�sultats ont �t� surprenants. Le gain �tait quasiment nul, et je me demande m�me si on ne perdait pas (le temps utilis� par les divs est contstant, avec la table, �a varie d'un peu mieux � carr�ment pire). => Table supprim�e.

Une table de SCR_Width �l�ments pour les angles de tirs du boss. Il y a un atan2() calcul� en temps r��l, pas trop terrible pour la vitesse. La aussi, j'ai fait l'essai en real-time en pensant faire une table par la suite, et en fait, �a passe m�me sur mon vieux coucou. Donc...

La table des briques fait 15 �l�ments de large. Forc�ment, c'est pas terrible, il aurait mieux valu 16. Je pensais peut-�tre �tendre la table utilis�e ingame � 16 (avec 1 colonne qui ne servirait � rien) pour �viter plein de multiplications par 15, mais une fois de plus, �a ne rame pas...


> Frame rate :

Pour la gestion du frame rate, je me suis inspir� de plusieurs bouts de code trouv�s dans des tutoriels sur internet. Le probl�me, c'est que je r�cup�re les fichiers frame.c et frame.h d'un projet � l'autre, alors je ne me rappelle absolument plus d'o� �a provient. Si quelqu'un se reconnait ici, qu'il me contacte, je mettrai une r�f�rence vers son site avec plaisir.

Le principe, c'est qu'en gros, la fonction FrameWait() attend qu'un certain nombre de cycles d'horloge se soient �coul�s depuis l'appel pr�c�dent avant de rendre la main. Ceci car bien s�r, on ne peut pas avoir acc�s directement au vblank, surtout en mode fen�tr� ! :)

Evidement, c'est une gestion simpliste et qui suppose qu'on ne va pas perdre de frames. Si �a arrive, ce n'est pas g�r�. Il faudrait alors relancer toute la gestion du jeu (pour prendre en compte tous les d�placements et autres), mais sauter l'affichage (qui prend du temps) une fois. C'est d'ailleurs pour �a que dans la gestion du jeu en lui m�me, l'affichage est s�par� de la gestion (bon ok, sauf pour les monstres).

Petit truc sur le SDL_Delay(3); dans la boucle : C'est ce qui permet au jeu de rendre la main au syst�me d'exploitation un court instant, et de soulager le processeur. Vous pouvez regarder avec le gestionnaire de t�ches de windows l'utilisation du processeur, avec et sans cette ligne. C'est assez parlant.

Apr�s, si on veut faire autrement, on peut mettre en place un timer sous IRQ qui avance un compteur de frames g�n�ral qui sera pratique pour savoir combien de frames ont �t� rat�es.


> Fichiers :

Liste des fichiers et leur fonction :

sprites.c Moteur / Gestion des sprites.
sprites.h

animspr.c Moteur / Gestion des animations de sprites.
animspr.h

anims.c Les tables d'animations de sprites.
anims.h Les d�clarations des dites tables.

mst.c Moteur / Gestion des monstres.
mst.h

monsters.c Les monstres du jeu.
monsters.h

ctypes.h D�clarations des types u8, s8, etc...

includes.h Includes et d�finitions de structs.

dust.c Gestion des dusts.
dust.h

fire.c Gestion des tirs.
fire.h

font.c Routines d'affichage de texte.
font.h

frame.c Gestion du frame rate.
frame.h

breaker.c Tout le jeu.
breaker.h

levels.h Niveaux du jeu, fichier inclus directement dans breaker.cpp.

menu.c Gestion des diff�rents menus et des high-scores.
menu.h

preca.c Diff�rentes routines utilis�es pour des pr�calculs.
preca.h

main.c Main, boucle du jeu, boucle des menus, gestion des �v�nements.

gfx R�pertoire contenant tous les graphismes du jeu.

high.scr Le fichier des high-scores (binaire, recr�� si manquant).
Il y a un petit checksum dessus, ce qui permet de contr�ler que le fichier n'est pas corrompu.


> Conclusion :

J'ai r�ussi � faire ce que je voulais faire, �a s'est bien pass�, et je suis plut�t content du r�sultat (�a n'a pas l'air trop bugg� ! (^_^)). Bien s�r, �a ressemble � un jeu d'il y a 15 ans, mais au d�but, je l'ai fait pour moi!

J'esp�re n'avoir pas trop oubli� de choses essentielles en entrant dans les d�tails, et que tout �a pourra servir � quelqu'un.

J'esp�re aussi que certains s'amuseront avec le jeu ! :) (M�me si pour moi, la partie amusante �tait plut�t le codage !).


--End of file--

Upload Date:Jun 21 2020
Category:Games/BrickBreaker
Download:Breaker_2.1.lha
Md5:dfe6fab4e9a02e288e8eb25bdb7d44c4
Size:482 KB
Downloads:373
Screenshot(s)
 
History
Last Comments