
 Casse Briques de type Arkanoid.
 Done by Clment CORDE.
 Contact : c1702@yahoo.com


> Histoire :

 Il y a de a quelques annes, j'ai travaill dans le jeu vido (fort mauvaise exprience 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 collgues avait l'air intress par le projet, donc je lui ai propos de lui donner les sources pour qu'il puisse voir coment j'avais procd. Ce mme collgue m'a suggr de mettre mes sources en ligne, car selon lui, a pourrait intresser 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 rvolutionnaire dans ce code, mais il contient quelques principes qui pourront peut-tre donner une orientation  des gens commenant la programmation (attention, je ne me pose pas comme expert pour autant !) : Comment grer des sprites, des anims, des monstres, des tirs, etc... Du moins, c'est une faon de faire les choses. Et puis il y a quand mme quelques petites astuces !


> Copyrights :

 Non, pas les miens ! :)

 Comme j'ai fait a pour moi et que je ne suis pas graphiste, j'ai rcupr des graphs comme j'ai pu, afin d'en avoir le moins possible  dessiner moi mme. 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 esprer que je ne serai pas embt.

 Les monstres, les explosions, les contours des niveaux et la base de la raquette viennent de la version Atari ST.
 Les arrire plans viennent du site StrategyWiki (http://strategywiki.org/wiki/Arkanoid/Walkthrough).
 La fonte a t trouve sur le site de Daniel Guldkrans (http://www.algonet.se/~guld1/freefont.htm), et lgrement retouche par mes soins pour les besoins du jeu.
 Tous les autres graphismes par moi mme.

 Petite prcision : Le but n'tait pas de faire un clone strict d'Arkanoid, mme si au final a y ressemble. Donc ne vous tonnez pas s'il y a quelques diffrences.


> Questions :

 Je rpondrai par mail (c1702@yahoo.com) autant que possible  d'ventuelles questions, mais veillez  prciser un objet bien clair. La raison est que je reois 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 vido et blitter dedans, en 256 couleurs parce que c'est ce que je voulais, que les modes 256 couleurs sont faciles  grer 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 (mme si a ne doit pas tre bien sorcier). Sinon, tout est fait  la main.


> Son :

 Il n'y a pas de son dans ce jeu. La raison ? Je n'ai absolument aucun matriel pour crer, diter ou ripper du son. Maintenant, si quelqu'un veut m'en envoyer et si j'ai un peu de temps, je verrai comment l'inclure dans le projet.


> 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 rpertoires soient les mmes que les miens, le projet ne se lirait de toutes faons probablement pas.

 Crez un nouveau projet SDL, copiez tous les fichiers sources ainsi que le rpertoire "gfx" dans le rpertoire 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 compils.

 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 emche de refaire les inclusions vous mmes ! :)

 Le jeu est cod en C. Pourquoi pas en C++ ? Parce que je voulais faire les choses d'une certaine faon, 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 mthodes et tout et tout, rien ne vous en empche (le code est assez compartiment, a ne devrait pas tre trop violent).


> Code :

 * Nomenclature utilise :

 Variables numriques prcdes de 'n'.
 Pointeurs prcds de 'p'.
 Variables gnrales prcdes de 'g'.
 Puis noms de variables commenant 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 plutt i, j, k, ix, iy...


> Petits problmes :

 * Le scroll du dcor dans les menus :
 Je ne peux pas expliquer pourquoi, mais sur certaines machines, le scroll n'est pas smooth (J'ai le problme sur ma vieille machine, sur laquelle je dveloppe). 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 supporte 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 problmes avec les config double cran, de plus en plus courantes (problme 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 rfrence de la balle au centre), si une partie de la balle est dans une brique incassable, dj, le recalage est pnible  faire. Si en plus de a la balle tait entre deux briques incassables suffisement rapproches et que l'espace entre les deux briques devient infrieur  celui du diamtre de la balle, l, a devient ingrable (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". Problme 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 ? Crer les niveaux de faon  viter les problmes est une solution utilise dans les jeux vido plus frquement 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 mme 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 spare en blocs de 16x20, chaque bloc reprsentant un niveau. L'espace utile est 15x17. Chaque point reprsente une brique : Couleurs 1  10 pour les briques normales, 16  18 pour les briques spciales.

 Les 2 dernires lignes (soit une table de 32 lments) reprsentent une table de bonus distribus au hasard dans le niveau (voir sur la partie droite du fichier BMP pour explications, couleurs  partir de 128). Avec ce systme, on peut choisir quelles items tombent selon le niveau. Par exemple, on peut limiter le nombre d'items diffrents dans les premiers niveaux et l'augmenter au fur et  mesure.

 Les niveaux sont capturs 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 gnrs 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 gnr 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), adapts  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 trs/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 trs difficile, mais aussi trs chiant.


> Jeu :

 Pour les rebonds sur la raquette, je me suis inspir de ce que j'ai vu sur Arkanoid I : La balle est renvoye 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 dpart (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 dbut, et finalement, j'ai implment 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 compltement invent.

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


> Sprites :

 Les sprites sont capturs au lancement du jeu, depuis des fichiers BMP.

 Les sprites dans ce jeu sont trs simples, ils ne possdent mme pas de zone de collision en plus de leur rectangle englobant. La bonne ide que nous utilisions dans le jeu vido tait de passer par le format PSD (photoshop), qui permet de rajouter des couches alpha  volont, et est assez simple  dcoder (en 256 couleurs !). On peut alors rajouter des zones de collisions diffrentes et plein d'autres choses utiles. Dans ce jeu, hormis les balles (qui sont testes au pixel), tout est relativement carr et je n'avais pas vraiment besoin de zones de collisions supplmentaires. Je me suis donc content d'un BMP, que SDL permet de lire facilement. (Note: Un loader de PSD est en prparation. Je m'en servirai dans un prochain projet).

 Dans un "vrai" jeu vido, on ne capturerait pas les sprites de cette faon. On gnrerait des fichiers avec un outil, ce qui permet entre autres de les compresser. Comme le rsultat de la capture sera tout le temps le mme, le faire en temps rel prsente peu d'intrt. 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  dbugger des programmes externes en plus.

 Techniquement, quand un sprite est captur, on gnre un masque inverse (un rectangle de la mme 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 diffrence entre un sprite et une animation. Bien sr, les animations sont composes de sprites, mais les gestions sont compltement spares.

 - 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 cts haut et gauche indiquent le point de rfrence du sprite. L'arrire 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 "chanage" (un sprite  un numro relatif au sprite qui le prcde).

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

 - Rajouter d'une animation :

 Une fois que vous avez intgr tous les sprites, il faut dfinir une anim. Ca se passe dans les fichiers "anims.cpp" et "anims.h".

 Dans "anims.cpp", on dfinit une table.

 La structure est trs simple :
 1 clef d'animation (nous y reviendrons plus tard), puis
 nombre de frames d'affichage, numro du sprite  afficher (ceci rpt autant de fois que ncessaire).
 On peut aussi rajouter des codes de contrle, suivi d'une valeur (qui dpend du code).

 Seulement 4 codes dfinis 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 libr.
 e_Anm_Kill : Fin d'une anim. Renvoie -1 et libre le slot (ex: dust).

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

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

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

 La diffrence, AnmSetIfNew() initialise une anim seulement si l'animation passe en paramtre 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 rcuprer  tout moment (AnmGetKey()), on peut s'en servir pour diffrencier 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'empcher 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 compose 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 suprieure  celle du repos, l'anim est mise en place. Jusque l, on n'en pas besoin de priorits, d'accord. Mais quand doit on remettre l'anim de repos ? Avec ce systme, on peut appeler AnmSetIfNew() tout le temps, l'anim de repos ne sera remise en place que lorsque l'anim de tir sera termine. La gestion est simplifie : Par dfaut, 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 suprieure (un hit ou la mort, par exemple).

 Ce systme ne rgle pas tous les problmes, 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 particulires, on utilise la table pData[64], qui laisse 64 octets de donnes spcifiques 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 mmoire est infini !

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

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

 Note : Il faut faire super attention  la taille des structures spcifiques, si elles sont trop grandes, il y aura un phnomne de recouvrement (la fin des donnes d'un slot qui dbordent sur le slot suivant), et une belle merde  dbugger... La fonction MstCheckStructSizes()  la fin du fichier monsters.cpp sert  a. Pour ne plus compiler les asserts en release, il faut spcifier -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 gnral), et ceux qu'il faut liminer (les ennemis le feront eux-mmes).


> Tirs :

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

 Ici, la gestion des tirs qui sortent de l'cran est simplifie 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 mme 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 concerns feront le test, c'est plus rapide, et beaucoup plus simple.

 Le petit truc intressant  regarder, c'est la variable gnFireLastUsed dans les routines FireGetSlot() et FireReleaseSlot(), qui permet d'acclrer la recherche d'un slot libre au lieu de scanner la table depuis le dbut  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 grer facilement plein de petits effets facilement. La premire personne qui avait utilis a l'avait fait pour afficher des "poussires" (dust en anglais) pour un personnage  la rception 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 fume derrire 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 dgats, donc pas besoin de gnrer un nouveau tir)...

 Le systme est customisable  volont. On peut imaginer donner une direction et une vitesse aux dusts, si ncssaire.


> 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 dcors doivent tre organises en consquence. Regardez la palette du dcor n1 (qui contient toutes les palettes des dcors). Chaque dcor utilise au max 6 couleurs pour sa partie claire. On rserve 6 couleurs de plus pour les ombres. Enfin, on rserve encore 6 couleurs pour les ombres des ombres (J'y reviendrai plus tard). Total : 18 couleurs rserves pour chaque level.

 Pour afficher une ombre, on commence comme pour un sprite, on fait un trou sur la destination l o doit tre affiche l'ombre. Puis on rcupre les pixels de l'emlacement du trou sur l'image ORIGINALE du dcor (pas le double buffer), auxquels on ajoute 6 et on poke a sur la destination.

 Rsultat :
 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 mmes couleurs que les ombres, et hop, le tour est jou.
 Une couleur claire devient une ombre, une ombre reste une ombre.

 Avec cette mthode, 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 mthodes pour prendre en compte les ombres.
 - Soit  chaque fois que j'affichais un sprite, j'en affichais un autre dcal avec le flag d'ombre. Avantage : On peut sur chaque ombre mettre un dcalage diffrent. Inconvnient : Il y a un double appel  la fonction SprDisplay(), donc plus de sprites  trier. De plus, les ombres tant affiches toujours derrire 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 premire pour afficher toutes les ombres (en dessous des autres sprites, donc), et une seconde pour les sprites normaux. Inconvnient : Toutes les ombres ont le mme dcalage (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 trs facilement repasser de la mthode 2  la mthode 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 trs 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 (cd changer la couleur 0 eu dbut de la routine et la remettre  sa valeur aprs). Au dbut, je pensais faire a avec SDL_GetTicks(), en en mettant un avant et un aprs le bout de code  timer. Manque de bol, les bouts de code  tester sont souvent tellement petits ou tellement rapides que la diffrence vaut trs souvent 0.

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

>>>
#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 ! :)


> Prcalculs :

 J'ai juste prcalcul une table de sinus et de cosinus, sur 256 valeurs.

 Il y a d'autres prcalculs faisables :

 Une table de SCR_Width lments et une de SCR_Height lments, pour savoir immdiatement 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),  dfaut d'tre pratique. Je pensais faire les tables sus-cites 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 rsultats ont t surprenants. Le gain tait quasiment nul, et je me demande mme si on ne perdait pas (le temps utilis par les divs est contstant, avec la table, a varie d'un peu mieux  carrment pire). => Table supprime.

 Une table de SCR_Width lments pour les angles de tirs du boss. Il y a un atan2() calcul en temps rl, 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 mme sur mon vieux coucou. Donc...

 La table des briques fait 15 lments de large. Forcment, c'est pas terrible, il aurait mieux valu 16. Je pensais peut-tre tendre la table utilise 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 trouvs dans des tutoriels sur internet. Le problme, c'est que je rcupre 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 rfrence 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 couls depuis l'appel prcdent avant de rendre la main. Ceci car bien sr, on ne peut pas avoir accs directement au vblank, surtout en mode fentr ! :)

 Evidement, c'est une gestion simpliste et qui suppose qu'on ne va pas perdre de frames. Si a arrive, ce n'est pas gr. Il faudrait alors relancer toute la gestion du jeu (pour prendre en compte tous les dplacements 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 mme, l'affichage est spar 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 systme d'exploitation un court instant, et de soulager le processeur. Vous pouvez regarder avec le gestionnaire de tches de windows l'utilisation du processeur, avec et sans cette ligne. C'est assez parlant.

 Aprs, si on veut faire autrement, on peut mettre en place un timer sous IRQ qui avance un compteur de frames gnral qui sera pratique pour savoir combien de frames ont t rates.


> Fichiers :

 Liste des fichiers et leur fonction :

sprites.cpp	Moteur / Gestion des sprites.
sprites.h

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

anims.cpp	Les tables d'animations de sprites.
anims.h		Les dclarations des dites tables.

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

monsters.cpp	Les monstres du jeu.
monsters.h

ctypes.h	Dclarations des types u8, s8, etc...

includes.h	Includes et dfinitions de structs.

dust.cpp	Gestion des dusts.
dust.h

fire.cpp	Gestion des tirs.
fire.h

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

frame.cpp	Gestion du frame rate.
frame.h

breaker.cpp	Tout le jeu.
breaker.h

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

menu.cpp	Gestion des diffrents menus et des high-scores.
menu.h

preca.cpp	Diffrentes routines utilises pour des prcalculs.
preca.h

main.cpp	Main, boucle du jeu, boucle des menus, gestion des vnements.

gfx		Rpertoire 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 contrler que le fichier n'est pas corrompu.


> Conclusion :

 J'ai russi  faire ce que je voulais faire, a s'est bien pass, et je suis plutt content du rsultat (a n'a pas l'air trop bugg ! (^_^)). Bien sr, a ressemble  un jeu d'il y a 15 ans, mais au dbut, je l'ai fait pour moi!

 J'espre n'avoir pas trop oubli de choses essentielles en entrant dans les dtails, et que tout a pourra servir  quelqu'un.

 J'espre aussi que certains s'amuseront avec le jeu ! :) (Mme si pour moi, la partie amusante tait plutt le codage !).


--End of file--
