IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SDL Discussion :

Déplacement diagonal


Sujet :

SDL

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2013
    Messages
    1
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2013
    Messages : 1
    Points : 1
    Points
    1
    Par défaut Déplacement diagonal
    Bonjour !

    J'ai un petit soucis avec mon jeu pour le déplacement de mon personnage. J'arrive à le faire bouger en diagonale lorsque 2 touches sont pressées mais le problème, c'est que le personnage s'arrête lorsque je relâche la deuxième touche. En gros voila ce qu'il se passe :

    - J'appuis sur "flèche haut", le personnage va vers le haut.
    - J'appuis sur "flèche droite" sans relâcher "flèche haut" -> le personnage se déplace en diagonale (en haut à droite)
    - Je relâche "flèche droite" sans relâcher "flèche haut" - > le personnage s’arrête alors que flèche haut est toujours pressées.

    Voici le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    while (continuer)
    {
            SDL_WaitEvent(&event);
            Uint8 *keystates = SDL_GetKeyState( NULL );
     
            if (keystates[ SDLK_UP ])
            {
                positionPerso.y--;
            }
     
            if (keystates[ SDLK_DOWN ])
            {
                positionPerso.y++;
            }
     
            if (keystates[ SDLK_RIGHT ])
            {
                positionPerso.x++;
            }
     
            if (keystates[ SDLK_LEFT ])
            {
                positionPerso.x--;
            }
     
    SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format,255 , 255, 255));
    SDL_BlitSurface(Perso, NULL, ecran, &positionPerso);
    SDL_Flip(ecran);
     
    }
    Je pense avoir identifié ce qui cloche, mais le problème c'est que je suis en train de m'arracher les cheveux pour savoir comment le contourner !

    En gros, lorsque que je relâche la deuxième touche, il se rappelle pas pas que la première touche est toujours pressés. Et donc, ça bloque sur le WaitEvent.

    Avez vous des idées pour m'aider à résoudre ce problèmes ?

    Merci d'avance pour vos futures réponses !

    Kerast

  2. #2
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 908
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 908
    Points : 220 169
    Points
    220 169
    Billets dans le blog
    126
    Par défaut
    Bonjour,

    C'est un problème assez classique de la SDL et une des raisons que je n'aime pas beaucoup leurs SDL_Event. Vous pouvez contourner cela en utilisant le système d'états -> http://loka.developpez.com/tutoriel/...nements/#LIV-C

    Sinon, il faut que vous mainteniez un tableau d'états des touches vous même. Lorsque vous recevez l'événement d'une touche appuyée, vous allez l'indiquer dans votre tableau. Une fois que vous avez capté tous les événements, il n'y a plus qu'à parcourir le tableau et déplacer le joueur selon les valeurs du tableau.

  3. #3
    Expert éminent sénior
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 226
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cyber-paléontologue

    Informations forums :
    Inscription : Mai 2010
    Messages : 3 226
    Points : 10 188
    Points
    10 188
    Par défaut
    Citation Envoyé par LittleWhite Voir le message
    Bonjour,

    C'est un problème assez classique de la SDL et une des raisons que je n'aime pas beaucoup leurs SDL_Event.
    J'ai pas testé beaucoup de lib I/O pour le clavier mais pour freeglut par exemple il y a aussi ce problème , d'ou pourquoi il faut mieux créer un tableau (et puis ça permet d’être complètement autonome de la lib au cas ou en veut la changer..

  4. #4
    Membre régulier Avatar de c1702
    Homme Profil pro
    Inscrit en
    Mai 2009
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2009
    Messages : 22
    Points : 90
    Points
    90
    Par défaut
    Bonjour,

    Citation Envoyé par LittleWhite Voir le message
    C'est un problème assez classique de la SDL et une des raisons que je n'aime pas beaucoup leurs SDL_Event.
    J'utilise la SDL depuis un petit moment déjà et je n'ai jamais rencontré ce genre de problèmes. Et ce n'est jamais arrivé non plus sur aucune des plateformes sur lesquelles mes programmes ont été portés (windows, linux, mac, amiga os, pandora, dingoo). A mon avis, le problème vient plutôt d'une mauvaise utilisation de la lib.

    Deux petites remarques sur ton code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Uint8 *keystates = SDL_GetKeyState( NULL );
    Ca, ça se fait une fois au début du programme. Ca n'est pas grave de le faire dans ta boucle, mais ça ne sert à rien (le buffer clavier interne de la SDL ne change pas de place au cours du programme).

    SDL_WaitEvent est une fonction bloquante. Donc, on ne s'en sert jamais (pas plus que SDL_EnableKeyRepeat, si c'est ce que tu as fait). Sinon comment géreras-tu le reste du jeu ? Déplacement des monstres, animations... (Et si tu pensais aux timers/thread, c'est une très mauvaise idée à oublier au plus vite). A la place, utilise SDL_PollEvent, et une pseudo synchro VBL avant le SDL_Flip().

    Pour rejoindre ce que disaient les autres posteurs, un buffer clavier perso peut effectivement être utile et ce n'est pas bien cher à mettre en place.

    Clément.

    Edit :
    Un petit exemple bricolé rapidement en partant du code d'exemple de la SDL (d'où la majeure partie des commentaires en anglais) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
     
    #include <stdlib.h>
    #include <SDL.h>
     
    typedef	uint8_t		u8;
    typedef	int32_t		s32;
    typedef	uint32_t	u32;
    #define	FPS	(1000/50)
    #define	SPD	(3)
     
    int main(int argc, char **argv)
    {
    	// initialize SDL video
    	if (SDL_Init(SDL_INIT_VIDEO) < 0)
    	{
    		fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError() );
    		exit(1);
    	}
    	// make sure SDL cleans up before exit
    	atexit(SDL_Quit);
     
    	// create a new window
    	SDL_Surface *pScreen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE);
    	if (pScreen == NULL)
    	{
    		fprintf(stderr, "Unable to set up video: %s\n", SDL_GetError());
    		exit(1);
    	}
     
    	// load an image
    	SDL_Surface *pBmp = SDL_LoadBMP("cb.bmp");
    	if (pBmp == NULL)
    	{
    		fprintf(stderr, "Unable to load bitmap: %s\n", SDL_GetError());
    		exit(1);
    	}
     
    	// centre the bitmap on screen
    	SDL_Rect dstrect;
    	s32	nPosX, nPosY;
    	nPosX = (pScreen->w - pBmp->w) / 2;
    	nPosY = (pScreen->h - pBmp->h) / 2;
     
    	// Ptr sur le buffer clavier de la SDL.
    	u8	*pKeys = SDL_GetKeyState(NULL);
     
    	// program main loop
    	u32	nTimePrev = SDL_GetTicks();
    	int done = 0;
    	while (done == 0)
    	{
    		// message processing loop
    		SDL_Event event;
    		while (SDL_PollEvent(&event))
    		{
    			// check for messages
    			switch (event.type)
    			{
    			// exit if the window is closed
    			case SDL_QUIT:
    				done = 1;
    				break;
     
    			// check for keypresses
    			case SDL_KEYDOWN:
    				// exit if ESCAPE is pressed
    				if (event.key.keysym.sym == SDLK_ESCAPE) done = 1;
    				break;
    			} // end switch
    		} // end of message processing
     
    		// Keys.
    		if (pKeys[SDLK_UP]) nPosY -= SPD;
    		if (pKeys[SDLK_DOWN]) nPosY += SPD;
    		if (pKeys[SDLK_LEFT]) nPosX -= SPD;
    		if (pKeys[SDLK_RIGHT]) nPosX += SPD;
     
    		// DRAWING STARTS HERE
     
    		// clear screen
    		SDL_FillRect(pScreen, NULL, SDL_MapRGB(pScreen->format, 0, 0, 0));
     
    		// draw bitmap
    		dstrect.x = nPosX;
    		dstrect.y = nPosY;
    		SDL_BlitSurface(pBmp, NULL, pScreen, &dstrect);
     
    		// DRAWING ENDS HERE
     
    		// Régulation simpliste du framerate.
    		u32	nTimeCur = SDL_GetTicks();
    		if (nTimeCur - nTimePrev < FPS) SDL_Delay(FPS - (nTimeCur - nTimePrev));
    		nTimePrev = SDL_GetTicks();
     
    		// finally, update the screen :)
    		SDL_Flip(pScreen);
    	} // end main loop
     
    	// free loaded bitmap
    	SDL_FreeSurface(pBmp);
     
    	// all is well ;)
    	printf("Exited cleanly\n");
    	return 0;
    }
    Regarde ce que ça donne chez toi, mais je pense que le déplacement devrait fonctionner correctement.

Discussions similaires

  1. [API][MFC]Graphisme - Déplacement d'un image ???
    Par Alcarbone dans le forum MFC
    Réponses: 12
    Dernier message: 26/11/2003, 21h28
  2. Déplacement ou positionnement d'une fenêtre
    Par agl dans le forum C++Builder
    Réponses: 3
    Dernier message: 10/11/2003, 09h29
  3. Déplacement d'Objets
    Par NaDiA_SoFt dans le forum C++Builder
    Réponses: 6
    Dernier message: 20/09/2003, 14h28
  4. Déplacement "automatique" du curseur
    Par Amenofis dans le forum Composants VCL
    Réponses: 2
    Dernier message: 08/01/2003, 18h57
  5. Limiter le déplacement de la souris
    Par el_bouleto dans le forum C++Builder
    Réponses: 4
    Dernier message: 08/11/2002, 23h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo