Partage
  • Partager sur Facebook
  • Partager sur Twitter

[C / SDL] Démineur

    17 juin 2006 à 10:58:21

    Pour un projet de démineur, je me suis fixé comme objectif de refaire celui de Win (en version portable, pour tous nos amis linuxiens, dont je fait d'ailleur partie).
    Vous n'êtes pas sans ignorer que lorsque l'on clique sur une des cases sans relacher la case "descend" (comme si on appuyait sur un bouton). Et lorsque l'on bouge la souris, toujours sans relacher le clic, la case qui s'"enfonce" suit le curseur.
    Et ca j'arrive pas à le refaire.
    Voici la partie à modifier:

    SDL_Event event;
            int bouclePrincipale = 1;
            SDL_Rect positionClique, positionSurvolee;

            int a, b; // variable de parcours de tableau

           
            while(bouclePrincipale)
            {
                    SDL_WaitEvent(&event);

                    x = (event.button.x / TAILLECASE);
                    y = (event.button.y / TAILLECASE);
                    positionClique.x = x * TAILLECASE;
                    positionClique.y = y * TAILLECASE;

                    positionSurvolee.x = (event.motion.x / TAILLECASE) * TAILLECASE;
                    positionSurvolee.y = (event.motion.y / TAILLECASE) * TAILLECASE;

                   
                    switch(event.type)
                    {
                            case SDL_QUIT:
                                    bouclePrincipale = 0;
                            break;
                            case SDL_KEYDOWN:
                                    switch(event.key.keysym.sym)
                                    {
                                            case SDLK_ESCAPE:
                                                    bouclePrincipale = 0;
                                                    break;
                                            default:
                                                    break;
                                    }
                            break;
                            case SDL_MOUSEBUTTONUP:
                                    if(event.button.button == SDL_BUTTON_LEFT)
                                    {
                                            if(cases[x][y].mine == MINE)
                                            {
                                                    cases[x][y].surface = *mineRouge;
                                                   
                                                    // penser a afficher toutes les mines lorsque l'on clique sur une
                                            }
                                            else if(cases[x][y].mine == NOMINE)
                                            {
                                                    cases[x][y].surface = *caseAppuyee;
                                            }
                                    SDL_BlitSurface(&cases[x][y].surface, NULL, ecran, &positionClique);
                                    }
                            break;
                            case SDL_MOUSEBUTTONDOWN:
                                    if(event.button.button == SDL_BUTTON_RIGHT)
                                    {
                                            switch(cases[x][y].etat)
                                            {
                                                    case FREE:
                                                            cases[x][y].etat = INTERRO;
                                                            SDL_BlitSurface(interro, NULL, ecran, &positionClique);
                                                    break;
                                                    case INTERRO:
                                                            cases[x][y].etat = FLAG;
                                                            SDL_BlitSurface(flag, NULL, ecran, &positionClique);
                                                    break;
                                                    case FLAG:
                                                            cases[x][y].etat = FREE;
                                                            SDL_BlitSurface(caseNormale, NULL, ecran, &positionClique);
                                                    break;
                                            }
                                   
                                    }
                            break;
                            case SDL_MOUSEMOTION:
                                    if(event.button.button == SDL_BUTTON_LEFT && cases[x][y].etat == FREE)
                                    {
                                            SDL_BlitSurface(caseAppuyee, NULL, ecran, &positionSurvolee);
                                            SDL_Flip(ecran);
                                            for(x=0; x<NOMBRECASE; x++)
                                            {
                                                    for(y=0; y<NOMBRECASE; y++)
                                                    {
                                                            SDL_BlitSurface(&cases[x][y].surface, NULL, ecran, &cases[x][y].position);
                                                    }
                                            }
                                    }
                           
                            break;
                                           
                            default:
                            break;
                    }
            SDL_Flip(ecran);
            }


    Je vous file également le code (au moins pour voir a quoi correspondent les variables ^^ ):

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <SDL/SDL.h>
    #include <SDL/SDL_image.h>


    // ----------------- Settings --------------- //
    #define NOMBRECASE 10
    #define TAILLECASE 25 // les cases feront 25x25 px
    #define HAUTEUR (NOMBRECASE * TAILLECASE)
    #define LARGEUR (NOMBRECASE * TAILLECASE)
    #define NOMBREMINE 20
    #define MIN 0
    #define MAX 9

    typedef struct carte carte;
    struct carte
    {
            int mine;
            int etat;
            SDL_Surface surface;
            SDL_Rect position;
    };

    enum {NOMINE, MINE};
    enum {FREE, FLAG, INTERRO};
    // ---------------- **Settings** -------------- //




    int main(int argc, char *argv[])
    {
            // ------------------------ Initialisation ------------------------------ //
            SDL_Init(SDL_INIT_VIDEO);
            SDL_WM_SetCaption("Démineur", NULL);

                    // --------------------- Variables et affectation ----------------------- //
                    SDL_Surface *ecran, *caseNormale, *caseAppuyee, *mine, *mineRouge, *flag, *interro;
           
                    ecran = SDL_SetVideoMode(LARGEUR, HAUTEUR, 32, SDL_HWSURFACE|SDL_DOUBLEBUF);
                    SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 0, 0, 0));

                    caseNormale = IMG_Load("case_demineur.png");
                   
                    caseAppuyee = SDL_CreateRGBSurface(SDL_HWSURFACE, TAILLECASE, TAILLECASE, 32, 0, 0, 0, 0);
                    SDL_FillRect(caseAppuyee, NULL, SDL_MapRGB(ecran->format, 200, 200, 200));
           
                    mine = IMG_Load("mine.png");
                    mineRouge = IMG_Load("mine_rouge.png"); // la mine sur laquelle on clique
                   
                    flag = IMG_Load("flag.png"); //le drapeau signalant une mine

                    interro = IMG_Load("interro.png"); // le point d'interrogation


                    carte cases[NOMBRECASE][NOMBRECASE]; // la "carte" du démineur

                   
                    // ----------------------- **variables et affectation** --------------------- //
                   
                    // ------------------- Les cases ------------------ //
                    int x, y;

                   
                   
                           
                    for(x=0; x<NOMBRECASE; x++)
                    {
                            for(y=0; y<NOMBRECASE; y++)
                            {
                                    cases[x][y].mine = NOMINE;
                                    cases[x][y].etat = FREE;
                                    cases[x][y].position.x = x * TAILLECASE;
                                    cases[x][y].position.y = y * TAILLECASE;
                                    cases[x][y].surface = *caseNormale;
                                    SDL_BlitSurface(&cases[x][y].surface, NULL, ecran, &cases[x][y].position);
                            }
                    }
                    SDL_Flip(ecran);
                    // ------------------- **les cases** ------------------ //

            // ----------------------------------- **Initialisation** ------------------------------- //
           

            // ------------------------------------- Les mines ------------------------------------- //

            SDL_Rect positionMine[NOMBREMINE];

           

            srand(time(NULL)); // on initialyse l'alea


            int i = 0;
            long nombreAleatoireX, nombreAleatoireY;

            while(i<NOMBREMINE)     
            {
                    nombreAleatoireX = (rand() % (MAX - MIN + 1)) + MIN;
                    nombreAleatoireY = (rand() % (MAX - MIN + 1)) + MIN;
                    if(cases[nombreAleatoireX][nombreAleatoireY].mine == MINE)
                            continue;
                    else
                    {
                            cases[nombreAleatoireX][nombreAleatoireY].mine = MINE;
                            positionMine[i].x = nombreAleatoireX * TAILLECASE;
                            positionMine[i].y = nombreAleatoireY * TAILLECASE;
                            i++;
                    }
            }

            SDL_Flip(ecran);
            // ----------------------------------- **Les mines** -----------------------------------//
           

            // --------------------------------- boucle ppale ---------------------------------- //

            SDL_Event event;
            int bouclePrincipale = 1;
            SDL_Rect positionClique, positionSurvolee;

            int a, b; // variable de parcours de tableau

           
            while(bouclePrincipale)
            {
                    SDL_WaitEvent(&event);

                    x = (event.button.x / TAILLECASE);
                    y = (event.button.y / TAILLECASE);
                    positionClique.x = x * TAILLECASE;
                    positionClique.y = y * TAILLECASE;

                    positionSurvolee.x = (event.motion.x / TAILLECASE) * TAILLECASE;
                    positionSurvolee.y = (event.motion.y / TAILLECASE) * TAILLECASE;

                   
                    switch(event.type)
                    {
                            case SDL_QUIT:
                                    bouclePrincipale = 0;
                            break;
                            case SDL_KEYDOWN:
                                    switch(event.key.keysym.sym)
                                    {
                                            case SDLK_ESCAPE:
                                                    bouclePrincipale = 0;
                                                    break;
                                            default:
                                                    break;
                                    }
                            break;
                            case SDL_MOUSEBUTTONUP:
                                    if(event.button.button == SDL_BUTTON_LEFT)
                                    {
                                            if(cases[x][y].mine == MINE)
                                            {
                                                    cases[x][y].surface = *mineRouge;
                                                   
                                                    // penser a afficher toutes les mines lorsque l'on clique sur une
                                            }
                                            else if(cases[x][y].mine == NOMINE)
                                            {
                                                    cases[x][y].surface = *caseAppuyee;
                                            }
                                    SDL_BlitSurface(&cases[x][y].surface, NULL, ecran, &positionClique);
                                    }
                            break;
                            case SDL_MOUSEBUTTONDOWN:
                                    if(event.button.button == SDL_BUTTON_RIGHT)
                                    {
                                            switch(cases[x][y].etat)
                                            {
                                                    case FREE:
                                                            cases[x][y].etat = INTERRO;
                                                            SDL_BlitSurface(interro, NULL, ecran, &positionClique);
                                                    break;
                                                    case INTERRO:
                                                            cases[x][y].etat = FLAG;
                                                            SDL_BlitSurface(flag, NULL, ecran, &positionClique);
                                                    break;
                                                    case FLAG:
                                                            cases[x][y].etat = FREE;
                                                            SDL_BlitSurface(caseNormale, NULL, ecran, &positionClique);
                                                    break;
                                            }
                                   
                                    }
                            break;
                            case SDL_MOUSEMOTION: // =========== Le problème se trouve par là
                                    if(event.button.button == SDL_BUTTON_LEFT && cases[x][y].etat == FREE)
                                    {
                                            SDL_BlitSurface(caseAppuyee, NULL, ecran, &positionSurvolee);
                                            SDL_Flip(ecran);
                                            for(x=0; x<NOMBRECASE; x++)
                                            {
                                                    for(y=0; y<NOMBRECASE; y++)
                                                    {
                                                            SDL_BlitSurface(&cases[x][y].surface, NULL, ecran, &cases[x][y].position);
                                                    }
                                            }
                                    }
                           
                            break;
                                           
                            default:
                            break;
                    }
            SDL_Flip(ecran);
            }

            // -------------------------- **Boucle ppale**------------------------------------- //
           
            // --------------------------- Phase de Nettoyage ---------------------------------- //
                                           
            SDL_Quit();
            return EXIT_SUCCESS;
            // ------------------------------- **phase de nettoyage** ------------------------ //
    }

    • Partager sur Facebook
    • Partager sur Twitter
      18 juin 2006 à 21:18:09

      L'événement SDL_MOUSEBUTTONDOWN n'est renvoyé qu'une fois au moment de l'enfoncement du bouton de la souris et non pas toute la durée pendant laquelle le bouton reste enfoncé. Je pense qu'il faudrait que tu fasses une variable "enfonce" que tu met à 1 dès qu'il y a une SDL_MOUSEBUTTONDOWN et qui ne se remet à 0 que lorsqu'il y aura un SDL_MOUSEBUTTONUP. La variable vaudra donc 1 pendant toute la durée de l'enfoncement, soit entre le moment où le bouton descent et celui où il remonte.

      J'espère t'avoir aidé.

      PS : J'ai aussi commencé un démineur qui est d'ailleurs bien avancé ( il ne reste plus qu'à gérer e fait de gagner ou de perdre autrement tout fonctionne) mais j'ai perdu la motivaton de le continuer alors si ça t'interresses je peux te le filer si tu veux y jeter un oeil.
      • Partager sur Facebook
      • Partager sur Twitter
        18 juin 2006 à 21:23:13

        Cette solution me semble etre la bonne (je suis pas sur le bon pc, je testerai plus tard).
        Merci de ta réponse!
        Tu me proposait de me filer ton code... Je veux bien y jeter un oeil. Soit tu le fout dans ce topic pour que tout le monde en profite (ce qui est mieux), soit tu me l'envoie par MP...
        • Partager sur Facebook
        • Partager sur Twitter

        [C / SDL] Démineur

        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
        × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
        • Editeur
        • Markdown