Vally8

Gestion des évenements et du clavier

Au menu du troisième tutorial : la gestion des évenements avec SDL, et en particulier le clavier.

Comme ce tutorial est assez court, j'en profite pour un peu enrichir l'exemple précedant.

Entrons maintenant dans le vif du sujet, Lorsque vous initialisez SDL avec un mode vidéo, vous créez une nouvelle fenêtre dans laquelle vous ne pouvez pas lire les entrées clavier avec les fonctions standart du C comme scanf ou getchar
Pour cela, SDL gère pour nous le clavier et nous transmet les informations par l'intermédiaire d'un gestionnaire d'évenement.
Ce gestionnaire permet également de recevoir des messages sur la gestion de la souris, des joysticks, s'ils ont été initialisés, et encore bien d'autres choses.

Passons maitenant au fonctions qui permettent de récuperer et d'analyser ces messages :
D'abord, la fonction SDL_WaitEvent qui attend qu'un message soit disponible, remplit une structure de message avec et nous rend la main.
Cette fonction retourne 0 si une erreur s'est produite lors de l'attente
La structure SDL_Event sert à récuperer le message, en fait c'est une gigantesque union au sens C du terme, qui possède des champs pour tous les cas de figure.

Sachant cela, la gestion des messages sous SDL se passe couramment de cette facon :

  • On commence par récuperer les messages en attente grace, par exemple, à la fonction SDL_WaitEvent (nous verrons une autre fonction de récupèration des messages dans le prochain tutorial).

  • Puis, à l'aide du champ "type" de la structure SDL_Event, nous savons de quel type de message il s'agit, SDL_Event met alors à notre disposition d'autres champs qui permettent de préciser quel est la nature du message.
    Par exemple, s'il s'agit d'un message de clavier, il faudra ensuite savoir quelle touche à été pressée...
  • On traite l'évenement selon ce que l'on veut faire dans notre programme.
  • On boucle sur la fonction de récupèration des messages.
Tout cela, jusqu'à ce qu'on souhaite quitter (appuis sur la touche ESCAPE par exemple), ou que l'on recoit le message "SDL_QUIT".

Voila le source complet de ce troisième tutorial :



#include <stdio.h>
#include <stdlib.h>
#include "SDL.h"


SDL_Surface *loadBmp(const char *fichier)
{
	SDL_Surface *image;

	/* Chargement du bitmap "fichier" en memoire dans la surface image */
	image = SDL_LoadBMP(fichier);
	if ( image == NULL )
	{
		fprintf(stderr, "Echec de chargement du fichier %s : %s.\n", fichier, SDL_GetError());
		return NULL;
	}
	
	/* Verification du format de l'image */
	if ( (image->w != 160) || (image->h != 160) )
	if ( image == NULL )
	{
		fprintf(stderr, "L'image du fichier %s doit être de taille 160*160 pixels.\n", fichier);
		SDL_FreeSurface(image);
		return NULL;
	}
	
	return image;
}


int main()
{

	SDL_Surface *ecran, *images[3];
	SDL_Event event;
	int image_courante = 0;

	atexit(SDL_Quit);
	
	/* initialisation de SDL_Video */
	if (SDL_Init(SDL_INIT_VIDEO) < 0)
	{
		fprintf(stderr, "Echec d'initialisation de SDL.\n");
		return 1;
	}
	printf("Bonjour le monde, SDL est initialisé avec succès.\n");
	
	
	/* creation d'une fenetre avec une zone d'affichage de 160*160 pixels,
	 une profondeur de bits egale à celle du serveur X ou de l'explorateur */
	ecran = SDL_SetVideoMode(160, 160, 0, SDL_ANYFORMAT);
	if ( ecran == NULL )
	{
		fprintf(stderr, "Echec de creation de la fenetre de 160*160 : %s.\n", SDL_GetError());
		return 1;
	}
	
	if ( !(images[0] = loadBmp("image1.bmp")) )
	{
		/* on libère SDL et on quitte */
		SDL_Quit();
		return 1;
	}
	
	if ( !(images[1] = loadBmp("image2.bmp")) )
	{
		/* on libère l'image déjà chargée */
		SDL_FreeSurface(images[0]);
		
		/* on libère SDL et on quitte */
		SDL_Quit();
		return 1;
	}

	if ( !(images[2] = loadBmp("image3.bmp")) )
	{
		/* on libère les images déjà chargées */
		SDL_FreeSurface(images[0]);
		SDL_FreeSurface(images[1]);
		
		/* on libère SDL et on quitte */
		SDL_Quit();
		return 1;
	}
	

	
	/* Copie de l'image à l'écran */
	SDL_BlitSurface(images[image_courante], NULL, ecran, NULL);
	
	/* Mise à jour de la zone d'affichage de la fenetre */
	SDL_UpdateRect(ecran, 0, 0, 0, 0);
	
	/* attente de l'appuis sur une touche pour quitter */
	while (SDL_WaitEvent(&event))
	{
		switch (event.type)
		{
		case SDL_KEYDOWN:
			switch (event.key.keysym.sym)
			{
			case SDLK_ESCAPE:
				/* On libère toutes les images chargées */
				SDL_FreeSurface(images[0]);
				SDL_FreeSurface(images[1]);
				SDL_FreeSurface(images[2]);
			
				/* on libère SDL et on quitte */
				SDL_Quit();
				exit(0);
				break;
				
			case SDLK_SPACE:
				printf("Bienvenus dans l'espace.\n");
				break;
				
			case SDLK_DOWN:
				/* On change l'image à afficher */
				image_courante--;
				if (image_courante < 0)
					image_courante = 2;
				
				/* Copie de l'image à l'écran */
				SDL_BlitSurface(images[image_courante], NULL, ecran, NULL);
	
				/* Mise à jour de la zone d'affichage de la fenetre */
				SDL_UpdateRect(ecran, 0, 0, 0, 0);
				break;
				
			case SDLK_UP:
				/* On change l'image à afficher */
				image_courante++;
				if (image_courante > 2)
					image_courante = 0;
	
				/* Copie de l'image à l'écran */
				SDL_BlitSurface(images[image_courante], NULL, ecran, NULL);
	
				/* Mise à jour de la zone d'affichage de la fenetre */
				SDL_UpdateRect(ecran, 0, 0, 0, 0);
				break;
				
			default:
				printf("Une touche à été pressée.\n");
			}
			break;
			
		case SDL_KEYUP:
			switch (event.key.keysym.sym)
			{
			case SDLK_SPACE:
			case SDLK_DOWN:
			case SDLK_UP:
				break;
				
			default:
				printf("Une touche à été relachée\n");
			}
			break;
			
		case SDL_QUIT:
			/* On libère toutes les images chargées */
			SDL_FreeSurface(images[0]);
			SDL_FreeSurface(images[1]);
			SDL_FreeSurface(images[2]);
			
			/* on libère SDL et on quitte */
			SDL_Quit();
			exit(0);
			break;
			
		default:
			;
		}
	}

	SDL_FreeSurface(images[0]);
	SDL_FreeSurface(images[1]);
	SDL_FreeSurface(images[2]);
	
	SDL_Quit();
	return 0;
}


voila le lien avec le fichier source, le makefile et les images : clavier.tar.bz2

un problème ??? On peut en parler sur le forum

Retour à l'accueil
compteur

Valid HTML 4.01! Valid CSS Valid RSS feed.