Au sanglier codeur

Gérons les évènements

Introduction

Bien, maintenant nous savons organiser notre jeu. Mais ça ne relevait pas vraiment de la création d'un moteur, n'est-ce pas ?
Vous vous souvenez, nous avions toujours à passer un SDL_Event à nos objets qui devaient se débrouiller avec, donnant lieu à d'inombrables switchs.
Il y a moyen d'enfermer tout ce bazar dans une classe bien propre de l'extérieur, dont on pourra interroger une instance pour savoir si telle touche du clavier est enfoncée (ou pas), quelle est la position de la souris, etc etc.

Prérequis : POO, évènements avec la SDL.

D'abord, une nouvelle manière de gérer les évènements

Vous connaîssez sans doute un schéma de ce type pour gérer les évènements :

while(continuer)
{
	while(SDL_PollEvent(&evt)
	{
		switch(evt.type)
		{
			/* ... */
		}	
	/* ... */
	}
/* ... */		
SDL_BlitSurface();
}

Mais il en existe un autre.
En effet nous allons simplement passer en revue tous les objets contenus dans notre liste, et appeller leur fonction de mise à jour.
Ce sont eux qui vont alors gérer les évènements comme ils l'entendent...
Il faudra donc leur passer le dernier évènement survenu (s'il en est survenu un).
Néanmoins, ça n'est pas très pratique et ça risque de donner du code redondant.

Il existe une technique plus simple et plus efficace : récupérer l'état du clavier.
Il existe une fonction de la SDL qui renvoie un tableau de booléen, avec chaque case correspondant à une touche du clavier.
Si la case du tableau == 1, la touche correspondante est enfoncée; sinon la touche est relachée.
A partir de ce tableau (le même existe pour la souris), on peut donc gérer les évènements en passant l'état du clavier aux objets : ils vérifient alors si les touches qui les intéressent sont enfoncées (ou pas), et réagisent en conséquence (ou pas).
De même pour les boutons de la souris, et la position de cette dernière.

Du coup, la seule gestion des évènements dont on s'occupe pour le moment va être de quitter le jeu au cas où un SDL_QUIT survient.
Mais nous allons d'abord encapsuler tout ça dans une classe... de type singleton. ;)

Ensuite, on encapsule ça dans une classe

Cette classe produira des objets qui seront un peu comme les tableaux de touches qu'on a vus.
La différence est qu'elle contiendra à la fois l'état du clavier, de la souris, la position de celle ci, et un booléen pour savoir si jamais le jeu doit être quitté ou pas.

Il faut donc un tableau pour les touches, un pour les boutons de souris, un rect pour la position de la souris, et un booléen pour savoir si le jeu doit être quitté.
Après, il suffit de faire une fonction MiseAJour qui traite un évènement de la pile, et modifie ses attributs en conséquences, et des accesseurs pour les différents attributs.
Simple, non ? Je vous laisse voir la doc de la sdl : SDL_GetKeyState(), SDL_GetMouseState(int *x, int *y), SDL_PollEvent(SDL_Event*), SDL_WaitEvent(SDL_Event*), SDL_Event.

class CEventsHandler : /* ... Singleton ... */
{
public:
	int* getKeys();
	int* getMouseButtons();
	SDL_Rect getMousePos();
	bool getMustQuit();
	void update();

	/* ... */

private:
	int *keys;
	int *mouse;
	bool mustQuit;
	SDL_Rect mousePos;
};

Et enfin, un exemple d'utilisation

/* Events est un pointeur sur notre gestionnaire d'evenements */

//Fleches directionnelles
if( (events->getKeys())[SDLK_LEFT] )
{
	avancer();
}
else if( (events->getKeys())[SDLK_RIGHT] )
{
	reculer();
}

//Croix de la fenetre
if( events->getMustQuit() )
{
	exit(EXIT_SUCCESS);
}

//Bouton droit de la souris
if( (events->getMouseButtons())[1] )
{
	std::cout << (events->getMousePos()).x << " : " << (events->getMousePos()).y << std::endl;
}

Et voilà, il suffit de demander au eventsHandler si jamais telle touche est appuyée, ou quoi, et de réagir en conséquence.
Du coup, on peut subdiviser la gestion des évènements entre tous les objets, et finis les switch d'évènements énormes \o/

Conclusion

Vous connaissez maintenant un nouveau schéma de gestion des évènements, plus adapté aux objets séparés.
L'implémenter dans une classe n'a pas été particulièrement difficile, néanmoins, ça nous fera gagner beaucoup de temps par la suite lorsque la gestion des évènements se complexifiera.
Nous vous invitons à lire la documentation de la SDL, pages SDL_EVENT, SDL_GetKeyState, SDL_GetMouseState, pour de plus amples informations, et à coder ça à votre manière. ;)


Valid XHTML 1.0 Strict - Le Sanglier Codeur, par GuilOooo & Kevin Leonhart - Remonter en haut - Valid CSS !