Actor Stdio : étape 3 Les flèches du clavier permettent de déplacer le héros de quelques pixels.
Principe
Il s'agit maintenant de faire bouger le héros dans une des 4 directions (haut, bas, gauche ou droite), en accélérant, pendant un certain temps.
Lire le clavier
Pour commencer, il faut connaitre l'état du clavier. SDL nous fournis des évenements sous forme de pile, au fur et a mesure qu'ils arrivent. Ce qui m'interesse ici c'est plutot de savoir si, au début de chaque frame, une touche particulière est actuellement préssée ou pas. Selon l'état de l'acteur, (déja en train d'avancer, en attente, ...), on pourra alors démarrer un mouvement (ou pas).
Je crée donc une classe InputManager qui va centraliser l'état des différentes touches (et d'un éventuel joystick, on verra plus tard). Comme je veux rester indépendant de la SDL et que c'est la SDL qui va me fournir ces infos, je rajoute des constantes pour non-SDL pour représenter les touches.
L'InputManager sera donc rempli par le SDL2Renderer pour faire le lien entre SDL et nos constantes. Du coup, l'InputManager et toutes les autres classes ne connaitrons rien de la SDL (sauf le SDL2Renderer, bien sûr).
Dans la classe SDL2Renderer, je renomme waitForExit en processEventsAndWaitForExit, et j'ajoute le correspondance pour chaque SDL_Event vers les notre InputManager.
Evidement, plutot que d'écrire les correspondance à la main sous forme de if, il faudra gérer plus intelligement toutes les touches, plus tard.
Actor au clavier
Je passe maintenant à l'Actor un pointeur vers mon InputManager pour qu'il puisse y accéder lors de l'appel à move.
L'Actor va simplement vérifier - à chaque tour de boucle - l'état des touches qui l'intéresse (flèche droite ou gauche) pour modifier sa vélocité, son accélération et le sens. A ce propos, il sera interessant d'avoir un système de configuration pour pouvoir modifier les touches.
J'ai rajouté pas mal de log pour y voir plus clair, il faudra s'occuper de créer une classe qui pourra filtrer tout ces logs proprement.
Ca marche. Ce qui marche pour x va marcher pour y. Mais avant de travailler sur le déplacement vertical, je vais refactorer.
Vector
Je vais rassembler les position, velocités et compagnie dans des objets Vector histoire de simplifier.
La classe Vector nous servira probablement beaucoup. Pour l'instant je ne gère que les positions x, y. On verra pour z plus tard. Je stocke les propriétés sous forme de float.
Centralisation des calculs
Je crée des fonctions pour pouvoir mutualiser les calculs. Il va falloir sortir tout ca dans une classe, plus tard.
Et voila !
Pas mal ! Je trouve que l'accélération est assez chic...
Il y a un petit bug lorsqu'on appuie brievement sur left ou up. Mais ça ira pour l'instant.
Mission accomplie (j'ai désactivé le dessin du fond pour la capture) !
Version animée
- Notes pour plus tard
- Une classe (ou au moins une fonction) qui s'occupe d'associer les constantes SDL et l'InputManager, probablement à partir d'un dictionnaire (pour éviter les nombreux if).
- Une petite classe de log qui permet d'activer/désactiver une partie des messages.
- Une classe générique de configuration qui permettra de changer le choix des touches pour les déplacements (et bien d'autres choses).
- Repenser et simplifier le calcul de l'accélération et des mouvements.
- Documentation :
- Toutes les touches de la lib. SDL : sdl.beuc.net/sdl.wiki/SDLKey
- Code source sur Github :
- Cette étape : github.com/nbrignol/actor-stdio/releases/tag/STEP_0003
- Tous les commits : github.com/nbrignol/actor-stdio/commits/master