Problème avec la gestion d'évenement en SDL (à mon avis)

SirThanos Messages postés 1 Date d'inscription dimanche 18 janvier 2009 Statut Membre Dernière intervention 5 mai 2010 - 5 mai 2010 à 20:33
pop70 Messages postés 181 Date d'inscription mardi 6 avril 2010 Statut Membre Dernière intervention 7 janvier 2012 - 6 mai 2010 à 19:05
Bonjour,

Ca fait un petit moment que je n'avance plus dans mon code car j'ai un probléme, à mon avis, venant du SDL_EVENT.
Je suis en train de faire un Mario Sokoban (un TP proposé sur le Site Du Zero), il est putôt finit, et j'aimerai l'améliorer.
Donc j'ai voulu faire un menu, qui ressemble plus à un menu de jeu, c'est à dire qu'on choisi "l'action que l'on veut faire" avec les touche HAUT, BAS, et ENTRER (et DROITE et GAUCHE au pire).

Je peux me déplacer dans le menu, et faire entrer et tout vas bien... le seul souci c'est quand le jeu commence. Les touches HAUT et BAS garde leur fonction de "menu", alors que je voudrais qu'elles (les touches) prennent la fonction de jeu (comme déplacer le personnage). Donc en gros quand j'appuis sur DROIT ET GAUCHE il se passe rien... Et quand j'appuis sur BAS, ça m'améne au menu Quitter.

Pour essayer de résoudre le probléme je me suis dit qu'il fallait changer le nom de la variable SDL_EVENT, mais ça n'a rien changer...

J'vous laisse le main.c et le jeu.c j'pense que les autres n'ont rien à voir avec le probléme ...

Si vous pouvez m'aidez ou me mettre sur le bon chemein, je prends =)

main.c :
#include <stdlib.h>
#include <stdio.h>
#include <G:\CodeBlocks\SDL-1.2.14\include\SDL.h>
#include <G:\CodeBlocks\SDL-1.2.14\include\SDL_Image.h>

#include "constante.h"
#include "jeu.h"
#include "fichiers.h"

int main(int argc, char *argv[])
{
    SDL_Surface* ecran NULL, *menuJouer NULL, *menuQuitter = NULL;
    SDL_Event eventMenuPrincipale;
    int continuer 1, menuPosition 1;

    SDL_Rect positionMenu;

    if (SDL_Init(SDL_INIT_VIDEO) == -1)
    {
        fprintf(stderr, "Erreur d'initialisation de la SDL : %s\n", SDL_GetError());
        exit(EXIT_FAILURE);
    }

    ecran = SDL_SetVideoMode(LARGEUR_FENETRE, HAUTEUR_FENETRE, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
    if (ecran == NULL)
    {
        fprintf(stderr, "Impossible de charger le mode vidéo : %s\n", SDL_GetError());
        exit(EXIT_FAILURE);
    }

    SDL_ShowCursor (SDL_DISABLE);

    SDL_WM_SetIcon(IMG_Load("sprites_mario_sokoban/caisse.jpg"), NULL);
    SDL_SetVideoMode(LARGEUR_FENETRE, HAUTEUR_FENETRE, 32, SDL_HWSURFACE);
    SDL_WM_SetCaption("Mario Sokoban", NULL);

    menuJouer = IMG_Load("sprites_mario_sokoban/menu(jouer).jpg");
    positionMenu.x = 0;
    positionMenu.y = 0;
    SDL_BlitSurface(menuJouer, NULL, ecran, &positionMenu);

    SDL_Flip(ecran);

    while(continuer)
    {
        continuer = 1;
        SDL_WaitEvent(&eventMenuPrincipale);
        switch(eventMenuPrincipale.type)
        {
            case SDL_QUIT:
                continuer = 0;
                break;
        }
        switch(eventMenuPrincipale.key.keysym.sym)
        {
            case SDLK_ESCAPE:
                continuer = 0;
                break;
            case SDLK_DOWN:
                menuPosition = 0;
                menuQuitter = IMG_Load("sprites_mario_sokoban/menu(Quitter).jpg");
                positionMenu.x = 0;
                positionMenu.y = 0;
                SDL_BlitSurface(menuQuitter, NULL, ecran, &positionMenu);
                SDL_Flip(ecran);
                break;
            case SDLK_UP:
                menuPosition = 1;
                menuJouer = IMG_Load("sprites_mario_sokoban/menu(Jouer).jpg");
                positionMenu.x = 0;
                positionMenu.y = 0;
                SDL_BlitSurface(menuJouer, NULL, ecran, &positionMenu);
                SDL_Flip(ecran);
                break;
            case SDLK_RETURN:
                switch (menuPosition)
                {
                    case 0:
                        continuer = 0;
                        break;
                    case 1:
                        jouer(ecran);
                        break;
                    default:
                        break;
                }

            default:
                break;
        }
    }

    SDL_Quit();

    return EXIT_SUCCESS;
}





jeu.c :
#include <stdlib.h>
#include <stdio.h>
#include <G:\CodeBlocks\SDL-1.2.14\include\SDL.h>
#include <G:\CodeBlocks\SDL-1.2.14\include\SDL_Image.h>

#include "constante.h"
#include "jeu.h"

void jouer(SDL_Surface* ecran)
{
    SDL_Surface *mario[4] = {NULL};
    SDL_Surface *mur NULL, *caisse NULL, *caisseOk = NULL, *objectif = NULL, *marioActuel = NULL;
    SDL_Rect position, positionJoueur;
    SDL_Event event;

    int continuer 1, objectifRestants 0, i = 0, j = 0;
    int carte[NB_BLOCS_LARGEUR][NB_BLOCS_HAUTEUR] = {0};

    mur = IMG_Load("sprites_mario_sokoban/mur.jpg");
    caisse = IMG_Load("sprites_mario_sokoban/caisse.jpg");
    caisseOk = IMG_Load("sprites_mario_sokoban/caisse_ok.jpg");
    objectif = IMG_Load("sprites_mario_sokoban/objectif.png");
    mario[BAS] = IMG_Load("sprites_mario_sokoban/mario_bas.gif");
    mario[HAUT] = IMG_Load("sprites_mario_sokoban/mario_haut.gif");
    mario[GAUCHE] = IMG_Load("sprites_mario_sokoban/mario_gauche.gif");
    mario[DROITE] = IMG_Load("sprites_mario_sokoban/mario_droite.gif");

    marioActuel = mario[BAS];

    if(!chargerNiveau(carte))
        exit(EXIT_FAILURE);

        for (i = 0 ; i < NB_BLOCS_LARGEUR ; i++)
        {
            for (j = 0 ; j < NB_BLOCS_LARGEUR ; j++)
            {
                if (carte[i][j] == MARIO)
                {

                    positionJoueur.x = i;
                    positionJoueur.y = j;
                    carte[i][j] = VIDE;
                }
            }
        }

    SDL_EnableKeyRepeat(100, 100);

    while (continuer)
    {
        SDL_WaitEvent(&event);
switch(event.type)
{
    case SDL_QUIT:
        continuer = 0;
        break;
    case SDL_KEYDOWN:
        switch (event.key.keysym.sym);
        {
            case SDLK_ESCAPE:
                continuer = 0;
                break;
            case SDLK_UP:
                marioActuel = mario[HAUT];
                deplacerJoueur(carte, &positionJoueur, HAUT);
                break;
            case SDLK_DOWN:
                marioActuel = mario[BAS];
                deplacerJoueur(carte, &positionJoueur, BAS);
                break;
            case SDLK_RIGHT:
                marioActuel = mario[DROITE];
                deplacerJoueur(carte, &positionJoueur, DROITE);
                break;
            case SDLK_LEFT:
                marioActuel = mario[GAUCHE];
                deplacerJoueur(carte, &positionJoueur, GAUCHE);
                break;
        }
        break;
}

        SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 255, 255, 255));

        objectifRestants = 0;

        for (i = 0 ; i < NB_BLOCS_LARGEUR ; i++)
        {
            for (j = 0 ; j < NB_BLOCS_HAUTEUR ; j++)
            {
                position.x = i * TAILLE_BLOC;
                position.y = j * TAILLE_BLOC;

                switch(carte[i][j])
                {
                    case MUR:
                        SDL_BlitSurface(mur, NULL, ecran, &position);
                        break;
                    case CAISSE:
                        SDL_BlitSurface(caisse, NULL, ecran, &position);
                        break;
                    case CAISSE_OK:
                        SDL_BlitSurface(caisseOk, NULL, ecran, &position);
                        break;
                    case OBJECTIF:
                        SDL_BlitSurface(objectif, NULL, ecran, &position);
                        objectifRestants = 1;
                        break;
                }
            }
        }

        if (!objectifRestants)
            continuer = 0;

        position.x = positionJoueur.x * TAILLE_BLOC;
        position.y = positionJoueur.y * TAILLE_BLOC;
        SDL_BlitSurface(marioActuel, NULL, ecran, &position);
        SDL_Flip(ecran);
    }

    SDL_EnableKeyRepeat(0, 0);

    SDL_FreeSurface(mur);
    SDL_FreeSurface(caisse);
    SDL_FreeSurface(caisseOk);
    SDL_FreeSurface(objectif);
    for (i = 0 ; i < 4 ; i++)
        SDL_FreeSurface(mario[i]);

}

void deplacerJoueur (int carte [][NB_BLOCS_HAUTEUR], SDL_Rect *pos, int direction)
{
    switch (direction)
    {
        case HAUT:
            if (pos->y - 1 < 0)
                break;
            if (carte[pos->x][pos->y - 1] == MUR)
                break;
            if ((carte[pos->x][pos->y - 1] == CAISSE || carte[pos->x][pos->y - 1] == CAISSE_OK) &&
                (pos->y - 2 < 0 || carte[pos->x][pos->y - 2] == MUR || carte[pos->x][pos->y - 2]
                CAISSE || carte[pos->x][pos->y - 2] CAISSE_OK))
                break;

            deplacerCaisse(&carte[pos->x][pos->y - 1], &carte[pos->x][pos->y - 2]);

            pos->y--;
            break;
        case BAS:
            if (pos->y + 1 < 0)
                break;
            if (carte[pos->x][pos->y + 1] == MUR)
                break;
            if ((carte[pos->x][pos->y + 1] == CAISSE || carte[pos->x][pos->y + 1] == CAISSE_OK) &&
                (pos->y + 2 < 0 || carte[pos->x][pos->y + 2] == MUR || carte[pos->x][pos->y + 2]
                CAISSE || carte[pos->x][pos->y + 2] CAISSE_OK))
                break;

            deplacerCaisse(&carte[pos->x][pos->y + 1], &carte[pos->x][pos->y + 2]);

            pos->y++;
            break;
        case DROITE:
            if (pos->y - 1 < 0)
                break;
            if (carte[pos->x - 1][pos->y] == MUR)
                break;
            if ((carte[pos->x - 1][pos->y] == CAISSE || carte[pos->x - 1][pos->y] == CAISSE_OK) &&
                (pos->x - 2 < 0 || carte[pos->x - 2][pos->y] == MUR || carte[pos->x - 2][pos->y]
                CAISSE || carte[pos->x - 2][pos->y] CAISSE_OK))
                break;

            deplacerCaisse(&carte[pos->x - 1][pos->y], &carte[pos->x - 2][pos->y]);

            pos->x--;
            break;
        case GAUCHE:
            if (pos->x + 1 >= NB_BLOCS_LARGEUR)
                break;
            if (carte[pos->x + 2][pos->y] == MUR)
                break;
            if ((carte[pos->x][pos->y + 1] == CAISSE || carte[pos->x][pos->y + 1] == CAISSE_OK) &&
                (pos->x + 2 >NB_BLOCS_LARGEUR || carte[pos->x + 2][pos->y] MUR || carte[pos->x + 2][pos->y]
                CAISSE || carte[pos->x + 2][pos->y] CAISSE_OK))
                break;

            deplacerCaisse(&carte[pos->x + 1][pos->y], &carte[pos->x + 2][pos->y]);

            pos->x++;
            break;
    }
}

void deplacerCaisse(int *premiereCase, int *secondeCase)
{
    if (*premiereCase CAISSE || *premiereCase CAISSE_OK)
    {
        if (*secondeCase == OBJECTIF)
            *secondeCase = CAISSE_OK;
        else
            *secondeCase = CAISSE;

        if (*premiereCase == CAISSE_OK)
            *premiereCase = OBJECTIF;
        else
            *premiereCase = VIDE;
    }

}


Cordialment, SirThanos.

1 réponse

pop70 Messages postés 181 Date d'inscription mardi 6 avril 2010 Statut Membre Dernière intervention 7 janvier 2012 10
6 mai 2010 à 19:05
Le problème est que les touches du menu principale sont activées dans la même boucle que celle de la fonction jouer. Donc quand tu passe à "jouer", le programme exécute les instructions des touches du menu principale avant celle du jeu , puis zappe celles du jeu car les touches ne sont plus activés... Donc, une solution serait de placer un boolean qui différencierait le menu du jeu.

Du genre :


bool Menu = 1;  /* Indique qu'il est dans le menu */

while(continuer)
    {
...

if (Menu)  /* Ne contole le clavier pour le menu que si il est dedans. */
{

        switch(eventMenuPrincipale.type)
        {
            case SDL_QUIT:
...
                break;
        }
        switch(eventMenuPrincipale.key.keysym.sym)
        {
            case SDLK_ESCAPE:
...
                break;
            case SDLK_DOWN:
...
                break;
            case SDLK_UP:
 ...
                break;
            case SDLK_RETURN:
                switch (menuPosition)
                {
                    case 0:
                        continuer = 0;
                        break;
                    case 1:
                        jouer(ecran);  /* Passe dans "jouer" */
Menu = 0;        /* Indique que ce n'est plus le menu */
                        break;
                    default:
...
                        break;
                }

            default:
...
                break;
        }

}

    }



Voilà, à mon avis cela devrait éliminer le problème.

(Il faut surtout placer le boolean au dessus du while pour qu'il ne se remette pas à 1.)

Pop70
0
Rejoignez-nous