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 :

[SDL] Problème dans la gestion d'évènements en SDL.


Sujet :

SDL

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2
    Points : 1
    Points
    1
    Par défaut [SDL] Problème dans la gestion d'évènements en SDL.
    Bonjour à tous

    Au cours de cette nuit, j'ai décidé d'attaquer un petit programme en SDL, simple (si possible) et marrant. Etant débutant, j'ai donc décidé de faire un programme genre mini-paint, qui dessine à partir de la souris lorsque le bouton de celle-ci reste enfoncé. En y rajoutant un peu de fantaisie : une courbe symétrique par rapport à la diagonale de la fenêtre se dessine en même temps que la courbe que l'on dessine avec la souris.

    Seulement, aïe aïe, les ennuis arrivent rapidement. C'est dans la gestion du clic que cela ne va pas : j'ai beau cliquer et recliquer, ça ne veut pas dessiner. Pourtant, le programme m'a l'air entièrement fonctionnel... c'est certainement quelque chose que je ne maitrise pas.

    Comme un bon code source parle mieux que n'importe quoi d'autre... le voici :
    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
     
    #include <cstdlib>
    #include <stdlib.h>
    #include <SDL/SDL.h>
     
    int main (int argc, char** argv)
    {
        int cont=1;
        long i=0;
     
        SDL_Event event;
        SDL_Rect posPx1, posPx2, posTrait1[10000];
        SDL_Surface *trait1[10000]={0};
     
        //Démarrage SDL, subsystem video uniquement.
        if (SDL_Init(SDL_INIT_VIDEO) < 0 )
        {
            printf("Unable to init SDL: %s\n", SDL_GetError());
            return 1;
        }
     
        //La SDL quittera à la fin du programme.
        atexit(SDL_Quit);
     
        //Petites options du programme.
        SDL_WM_SetCaption("Psychedelic symetric", NULL);
        SDL_ShowCursor(SDL_DISABLE);
     
        //Création et paramétrage de la surface écran.
        SDL_Surface *screen = SDL_SetVideoMode(640, 640, 32, SDL_HWSURFACE|SDL_DOUBLEBUF);
        if (!screen)
        {
            printf("Unable to set video: %s\n", SDL_GetError());
            return 1;
        }
     
        //Création et coloration de mes deux surfaces "pixel".
        SDL_Surface *px1 = SDL_CreateRGBSurface(SDL_HWSURFACE, 1, 1, 32, 0,0,0,0);
        SDL_Surface *px2 = SDL_CreateRGBSurface(SDL_HWSURFACE, 1, 1, 32, 0,0,0,0);
        SDL_FillRect(px1, NULL, SDL_MapRGB(screen->format, 255, 255, 255));
        SDL_FillRect(px2, NULL, SDL_MapRGB(screen->format, 255, 255, 255));
     
        //Gestion des évènements.
        while(cont)
        {
            SDL_WaitEvent(&event);
            switch(event.type)
            {
                //Sortie du programme.
                case SDL_QUIT:
                    cont=0;
                    break;
     
                //Le pixel px1 est à la même position que la souris.
                //Le pixel px2 est le symétrique de la souris par rapport à la diagonale de l'écran.
                case SDL_MOUSEMOTION:
                    posPx1.x = event.motion.x;
                    posPx1.y = event.motion.y;
                    posPx2.x = event.motion.y;
                    posPx2.y = event.motion.x;
                    break;
     
                //Quand on clique, puis qu'on bouge la souris, une surface doit se créer dans trait1[i]
                //à la même position que la souris (matérialisée par px1). La surface ne doit pas se déplacer
                //par la suite.
                //Plus tard, la condition sera paramétrée de façon à ce que des surfaces soient
                //ainsi créées tant que le bouton de la souris n'a pas été relâché.
                //Il en sera de même pour px2, avec un autre tableau nommé trait2.
                case SDL_MOUSEBUTTONDOWN:
                    if(event.button.button == SDL_BUTTON_LEFT)
                    {
                        SDL_PollEvent(&event);
                        if(event.type == SDL_MOUSEMOTION)
                        {
                            trait1[i] = SDL_CreateRGBSurface(SDL_HWSURFACE, 1, 1, 32, 0,0,0,0);
                            posTrait1[i].x = posPx1.x;
                            posTrait1[i].y = posPx1.y;
                            SDL_BlitSurface(trait1[i], NULL, screen, &posTrait1[i]);
                            i++;
                        }
                    }
                    break;
     
     
            }
     
            //Remplissage de l'écran.
            SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));
            //Blittage des surfaces px1 et px2, rafraîchissement de l'écran.
            SDL_BlitSurface(px1, NULL, screen, &posPx1);
            SDL_BlitSurface(px2, NULL, screen, &posPx2);
            SDL_Flip(screen);
        }
     
        //Libération des surfaces.
        SDL_FreeSurface(screen);
        SDL_FreeSurface(px1);
        SDL_FreeSurface(px2);
        for(i=0 ; i<10000 ; i++)
            SDL_FreeSurface(trait1[i]);
     
     
        return 0;
    }
    Vous avez le code intégral... hé oui, j'ai tout fait dans la main, honte à moi

    J'espère que le code est assez parlant et que vous verrez vite ce qui cloche.

    Merci beaucoup pour votre aide future

  2. #2
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Bonjour,

    Quelques commentaires sur ce code :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
        SDL_Rect posPx1, posPx2, posTrait1[10000];
        SDL_Surface *trait1[10000]={0};
    Ce maximum 10000 n'est pas très pratique, il vaut mieux avoir une macro du style :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    #define MAX_PTS 10000
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
        //Démarrage SDL, subsystem video uniquement.
        if (SDL_Init(SDL_INIT_VIDEO) < 0 )
        {
            printf("Unable to init SDL: %s\n", SDL_GetError());
            return 1;
        }
    Il vaut mieux préférer EXIT_FAILURE que retourner 1.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
        //Création et coloration de mes deux surfaces "pixel".
        SDL_Surface *px1 = SDL_CreateRGBSurface(SDL_HWSURFACE, 1, 1, 32, 0,0,0,0);
        SDL_Surface *px2 = SDL_CreateRGBSurface(SDL_HWSURFACE, 1, 1, 32, 0,0,0,0);
        SDL_FillRect(px1, NULL, SDL_MapRGB(screen->format, 255, 255, 255));
        SDL_FillRect(px2, NULL, SDL_MapRGB(screen->format, 255, 255, 255));
    Il faut tester le retour de SDL_CreateRGBSurface et utiliser les surfaces pour le format pas celui du screen.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
            SDL_WaitEvent(&event);
    Il faut tester le retour de SDL_WaitEvent.


    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
     
                case SDL_MOUSEBUTTONDOWN:
                    if(event.button.button == SDL_BUTTON_LEFT)
                    {
                        SDL_PollEvent(&event);
                        if(event.type == SDL_MOUSEMOTION)
                        {
                            trait1[i] = SDL_CreateRGBSurface(SDL_HWSURFACE, 1, 1, 32, 0,0,0,0);
                            posTrait1[i].x = posPx1.x;
                            posTrait1[i].y = posPx1.y;
                            SDL_BlitSurface(trait1[i], NULL, screen, &posTrait1[i]);
                            i++;
                        }
                    }
                    break;
    Pas du tout logique et dangereux :
    - SDL_WaitEvent capture les événements, c'est une très mauvaise idée d'avoir plusieurs endroits qui capture les événementes.
    - Pas de test sur SDL_PollEvent
    - Pas de test après SDL_CreateRGBSurface
    - Il faut utiliser autre chose que i pour un compteur aussi important
    [/code]

    Ensuite on arrive ici qui est la section rendu du code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
            //Remplissage de l'écran.
            SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));
            //Blittage des surfaces px1 et px2, rafraîchissement de l'écran.
            SDL_BlitSurface(px1, NULL, screen, &posPx1);
            SDL_BlitSurface(px2, NULL, screen, &posPx2);
            SDL_Flip(screen);
    Problème -> où se trouve le code pour rendre les traits préalablement sauvegardés ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
        //Libération des surfaces.
        SDL_FreeSurface(screen);
    On ne libére pas la surface screen.

    Préférer EXIT_SUCCESS à la place de return 0.

    J'ai fait une version corrigée :

    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
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
     
    #include <stdlib.h>
    #include <stdio.h>
    #include <SDL/SDL.h>
     
    #define MAX_PTS 10000
    int main (int argc, char** argv)
    {
        int cont=1, pressed = 0;
        long j=0, traitcnt = 0;
     
        SDL_Event event;
        SDL_Rect posPx1, posPx2, posTrait1[MAX_PTS];
        SDL_Surface *trait1[MAX_PTS]={0};
     
        //Démarrage SDL, subsystem video uniquement.
        if (SDL_Init(SDL_INIT_VIDEO) < 0 )
        {
            printf("Unable to init SDL: %s\n", SDL_GetError());
            return EXIT_FAILURE;
        }
     
        //La SDL quittera à la fin du programme.
        atexit(SDL_Quit);
     
        //Petites options du programme.
        SDL_WM_SetCaption("Psychedelic symetric", NULL);
        SDL_ShowCursor(SDL_DISABLE);
     
        //Création et paramétrage de la surface écran.
        SDL_Surface *screen = SDL_SetVideoMode(640, 640, 32, SDL_HWSURFACE|SDL_DOUBLEBUF);
        if (!screen)
        {
            printf("Unable to set video: %s\n", SDL_GetError());
            return EXIT_FAILURE;
        }
     
        //Création et coloration de mes deux surfaces "pixel".
        SDL_Surface *px1 = SDL_CreateRGBSurface(SDL_HWSURFACE, 1, 1, 32, 0,0,0,0);
        SDL_Surface *px2 = SDL_CreateRGBSurface(SDL_HWSURFACE, 1, 1, 32, 0,0,0,0);
     
        if((px1 == NULL) || (px2 == NULL)) {
            printf("Unable to create surfaces: %s\n", SDL_GetError());
            return EXIT_FAILURE;
        }
     
        SDL_FillRect(px1, NULL, SDL_MapRGB(px1->format, 255, 255, 255));
        SDL_FillRect(px2, NULL, SDL_MapRGB(px2->format, 255, 255, 255));
     
        //Gestion des évènements.
        while(cont)
        {
            if(SDL_WaitEvent(&event) == 0) {
    		printf("Error with SDL_WaitEvent: %s\n", SDL_GetError());
    	}
     
            switch(event.type)
            {
                //Sortie du programme.
                case SDL_QUIT:
                    cont=0;
                    break;
     
                    //Le pixel px1 est à la même position que la souris.
                    //Le pixel px2 est le symétrique de la souris par rapport à la diagonale de l'écran.
                case SDL_MOUSEMOTION:
                    posPx1.x = event.motion.x;
                    posPx1.y = event.motion.y;
                    posPx2.x = event.motion.y;
                    posPx2.y = event.motion.x;
                    if(pressed == 1) {
                        if( traitcnt < MAX_PTS ) {
                            trait1[traitcnt] = SDL_CreateRGBSurface(SDL_HWSURFACE, 1, 1, 32, 0,0,0,0);
                            if(trait1[traitcnt] != NULL) {
                                SDL_FillRect(trait1[traitcnt], NULL, SDL_MapRGB(trait1[traitcnt]->format, 255, 255, 255));
                                posTrait1[traitcnt].x = posPx1.x;
                                posTrait1[traitcnt].y = posPx1.y;
                                traitcnt++;
                            }
                        }
                    }
                    break;
     
                    //Quand on clique, puis qu'on bouge la souris, une surface doit se créer dans trait1[i]
                    //à la même position que la souris (matérialisée par px1). La surface ne doit pas se déplacer
                    //par la suite.
                    //Plus tard, la condition sera paramétrée de façon à ce que des surfaces soient
                    //ainsi créées tant que le bouton de la souris n'a pas été relâché.
                    //Il en sera de même pour px2, avec un autre tableau nommé trait2.
                case SDL_MOUSEBUTTONDOWN:
                    if(event.button.button == SDL_BUTTON_LEFT) {
                        pressed = 1;
                    }
                    break;
                case SDL_MOUSEBUTTONUP:
                    pressed = 0;
                    break;
     
     
            }
     
            //Remplissage de l'écran.
            SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));
            //Blittage des surfaces px1 et px2, rafraîchissement de l'écran.
            SDL_BlitSurface(px1, NULL, screen, &posPx1);
            SDL_BlitSurface(px2, NULL, screen, &posPx2);
     
            for(j=0;j<traitcnt;j++) {
                SDL_BlitSurface(trait1[j], NULL, screen, &posTrait1[j]);
            }
     
            SDL_Flip(screen);
        }
     
        //Libération des surfaces.
        SDL_FreeSurface(px1);
        SDL_FreeSurface(px2);
        for(j=0 ; j<MAX_PTS ; j++) {
            SDL_FreeSurface(trait1[j]);
        }
     
        return EXIT_SUCCESS;
    }
    Jc

  3. #3
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2
    Points : 1
    Points
    1
    Par défaut
    Ouahou

    Je m'attendais honnêtement pas à une réponse corrigée si claire, précise, efficace... le programme marche !
    J'ai bien revu toutes mes erreurs, effectivement je débute vraiment et je passe à côté de certaines choses. Ici, tu me montres avec précision ce qui ne va pas, et c'est fantastique !

    Ca c'est de l'accueil

    Encore, merci beaucoup, je vais continuer et finir le programme en tenant compte de mes erreurs passées

  4. #4
    Membre actif Avatar de ironzorg
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    288
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 288
    Points : 245
    Points
    245
    Par défaut
    Si tu veux faire un programme avec lignes de commande, utilise ça:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int main (int argc, char* argv[])

Discussions similaires

  1. Réponses: 5
    Dernier message: 02/09/2013, 12h01
  2. A* et SDL (probléme dans closed)
    Par fastzombi dans le forum C++
    Réponses: 4
    Dernier message: 19/01/2007, 11h34
  3. Problème dans la gestion du CTreeCtrl
    Par vanitom dans le forum Visual C++
    Réponses: 9
    Dernier message: 28/09/2006, 14h29
  4. Problème avec la gestion des événements
    Par CynO dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 17/10/2005, 10h07
  5. Réponses: 2
    Dernier message: 11/05/2005, 13h23

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