Un des éléments les plus importants dans un jeu vidéo (2D), ce sont sans doute les sprites. Rien à voir avec une boisson pétillante, il s'agit du terme consacré pour les objets graphiques librement déplaçable à l'écran, y compris le personnage principal, les adversaires, mais aussi certains power-ups ou des effets spéciaux.
Les sprites ont besoin de données graphiques (des valeurs de couleurs) tout comme les décors, et ces données sont de nouveau constituées de "tiles". On va utiliser surtout des blocs de 16x16 pixels ici (et donc constitués de 2x2 tiles) mais la DS peut en réalité utiliser des sprites de 8x8 à 64x64 pisxels (avec quelques restrictions quand-même).
Mettre à jour la mémoire vidéo pour que les sprites s'affichent à l'écran (quels graphismes, quels réglages, etc) est délégué à la classe SpritePage dans la libgeds, et la fonction "sync()" de GuiEngine fera le nécessaire pour mettre à jour les coordonnées en respectant les timings de la puce vidéo (et faire en sorte que ça ne clignote pas, par exemple).
le brol de la SpriteRam | la SpritePage, aussi organisé que vous |
class Hero : private UsingSprites { NOCOPY(Hero); const SpritePage *page; unsigned x, y; oamno_t oam; public: Hero(const SpritePage *pg) : page(pg), x(128), y(96), oam((oamno_t) gResources->allocate(RES_OAM)) { page->setOAM((blockno_t)2, sprites); } void move(int dx, int dy) { x += dx; y += dy; iprintf("(%u,%u)", x, y); page->changeOAM(sprites + oam, x, y, (blockno_t) 4); } };
- se souvenir des coordonnées (le bon mot pour parler de la position à l'écran) actuelles;
- une SpritePage qui sait comment mettre à jour les entrées de la "MAO" (ou Mémoire des Attributs d'Objets -- Object Attribute Memory -- le terme de Nintendo pour parler des blocs de contrôle des sprites);
- avoir réservé une entrée de MAO et en retenir le numéro.
En disant que notre classe dérive de "UsingSprites", on obtient l'accès au tableau des MAOs (le tableau 'sprites[]') que le moteur de jeu va utiliser pendant la fonction sync(), mais aussi au gestionnaire de ressources (`gResources`) qui nous donne notre numéro de MAO. Du coup, la SpritePage a tout ce qu'il lui faut pour faire son travail.
void setactive() { SpriteRam myRam(WIDGETS_CHARSET(512)); SpriteSet mySet(&myRam, BG_PALETTE); mySet.Load("efs:/bg.spr"); /*+*/ sprSet.Load("efs:/hero.spr"); // rest of MetaWindow::setActive() as defined in previous tutorial /*+*/ hero = new Hero(sprSet.getpage(PAGE0)); }
Puis il n'y a plus qu'à tester l'état de la croix directionnelle (et les transmettre par des appels à la fonction 'move()') pour pouvoir déplacer le personnage en réaction aux mouvements imprimés par le joueur. Bon, ne vous attendez pas à quelque-chose de fluide ici: j'utilise toujours l'interface utilisateur prévue pour les éditeurs du projet "GEDS" qui ne produit un 'évèment DPAD' que lorsqu'on appuie sur une nouvelle direction. On arrangera ça la semaine prochaine avec les Animators.
if (keys & KEY_UP) { hero->move(0, -4); } if (keys & KEY_DOWN) { hero->move(0, 4); } if (keys & KEY_LEFT) { hero->move(-4, 0); } if (keys & KEY_RIGHT) { hero->move(4, 0); }
No comments:
Post a Comment