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 :

Comment ne pas enregistrer plusieurs fois une touche ?


Sujet :

SDL

  1. #1
    Membre du Club Avatar de Jordinateur
    Profil pro
    Inscrit en
    Février 2007
    Messages
    119
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 119
    Points : 51
    Points
    51
    Par défaut Comment ne pas enregistrer plusieurs fois une touche ?
    Bonjour à tous

    J'ai terminé un petit programme qui gère les sprites.
    Mais en fait, j'ai un petit problème auquel je ne trouves pas de solution :

    Lorsque l'on appuis plusieurs fois de suite sur une touche, l'appuis sur cette touche est mémorisé, et donc si j'appuis dix fois de suite sur la touche droite, le personnage se déplacera 10 cases plus loin alors que je ne fais rien pendant qu'il se déplace.
    Et moi j'aimerais justement que l'appuis sur ces touches ne sois pas mémorisé ; c'est-à-dire que lorsque mon personnage se déplace, aucune touche ne peut être pressée.

    Je ne sais pas si vous avez compris mon problème en tout cas voici mon 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
    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
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    #ifndef SPRITE_C
    #define SPRITE_C
    #include "sprite.h"
    #endif /*SPRITE_C*/
     
    SDL_Surface *window = NULL;
    SDL_Surface *MainChara = NULL;
    SDL_Rect CoordMainChara;
    SDL_Rect MainCharaSprite;
    unsigned char run = 0;
     
    int main (int argc, char *argv[])
    {
        //Initialisation des bibliothèques
        initLib();
        atexit(freeLib);
     
        //Creation de la fenêtre SDL
        createWindow();
     
        //Chargement de l'image a bliter + Blitage
        initializeSprite();
     
        //Boucle principale + évenementielle
        mainBuckle();
    }
     
    void initLib(void)
    {
        //Initialisation de la SDL
        if(SDL_INIT_VIDEO < 0) {
            fprintf(stderr, "Erreur lors de l'initialisation du mode video de la SDL");
            exit(EXIT_FAILURE);
        }
    }
     
    void freeLib(void)
    {
        SDL_Quit();
    }
     
    void createWindow(void)
    {
        window = SDL_SetVideoMode(LONGUEUR, HAUTEUR, RESOLUTION, SDL_HWSURFACE | SDL_DOUBLEBUF);
        if(window < 0) {
            fprintf(stderr, "Erreur lors de la création de la fenêtre");
            exit(EXIT_FAILURE);
        }
    }
     
    void initializeSprite(void)
    {
        MainChara = IMG_Load("IMAGE/1.png");
        if(MainChara==NULL) {
            fprintf(stderr, "Erreur lors de l'allocation pour la surface 'MainChara'");
            exit(EXIT_FAILURE);
        }
        CoordMainChara.x = 0;
        CoordMainChara.y = 0;
        MainCharaSprite.w = 32;
        MainCharaSprite.h = 48;
        MainCharaSprite.x = 0;
        MainCharaSprite.y = 0;
        SDL_BlitSurface(MainChara, &MainCharaSprite, window, &CoordMainChara);
        SDL_Flip(window);
    }
     
    void moveChara(long y, long x, long direction, int previousTime)
    {
        SDL_FillRect(window, NULL, SDL_MapRGB(window->format, 0, 0, 0));
        //CoordMainChara.y += y;
        //CoordMainChara.x += x;
        int i=0;
        while(i<4)
        {
            int actualTime = SDL_GetTicks();
            if (actualTime - previousTime >= 130)
            {
            //SDL_Delay(150);
     
            //On change la ligne d'animation selon la touche pressée
            changeSprite(direction);
     
            //On déplace progressivement le personnage pour avoir une impression de fluidité
            progressiveMove(direction);
     
            //CoordMainChara.y += y/4;
            SDL_FillRect(window, NULL, SDL_MapRGB(window->format, 0, 0, 0));
            SDL_BlitSurface (MainChara, &MainCharaSprite, window, &CoordMainChara);
            SDL_Flip(window);
            previousTime = actualTime;
            i++;
            }
        }
     
        //SDL_BlitSurface (MainChara, &MainCharaSprite, window, &CoordMainChara);
    }
     
    void progressiveMove(long direction2)
    {
        int j = 0;
     
        while(j<8)
        {
            if(direction2==DOWN)
                CoordMainChara.y += 1 + run*10;
     
            else if(direction2==LEFT)
                CoordMainChara.x -= 1 + run;
     
            else if(direction2==RIGHT)
                CoordMainChara.x += 1 + run;
     
            else if(direction2==UP)
                CoordMainChara.y -= 1 + run;
     
            SDL_FillRect(window, NULL, SDL_MapRGB(window->format, 0, 0, 0));
            SDL_BlitSurface(MainChara, &MainCharaSprite, window, &CoordMainChara);
            SDL_Flip(window);
            SDL_Delay(10);
            j++;
        }
    }
     
    void changeSprite(long direction3)
    {
        if (direction3==DOWN) {
                MainCharaSprite.y = 0;
                MainCharaSprite.x += 32;
                if (MainCharaSprite.x >= 32*4)
                    MainCharaSprite.x = 0;
        }
     
        else if(direction3==LEFT) {
            MainCharaSprite.y = 48;
            MainCharaSprite.x += 32;
            if (MainCharaSprite.x >= 32*4)
                MainCharaSprite.x = 0;
        }
     
        else if(direction3==RIGHT) {
            MainCharaSprite.y = 48*2;
            MainCharaSprite.x += 32;
            if (MainCharaSprite.x >= 32*4)
                MainCharaSprite.x = 0;
        }
     
        else if(direction3==UP) {
            MainCharaSprite.y = 48*3;
            MainCharaSprite.x += 32;
        }
        if (MainCharaSprite.x >= 32*4)
        MainCharaSprite.x = 0;
    }
     
    void mainBuckle (void)
    {
        SDL_Event event;
        unsigned char Continue = 1;
        SDL_EnableKeyRepeat(200, 0);
     
        //Boucle principale
        do
        {
            //Boucle évenementielle
            while(SDL_PollEvent(&event))
            {
                switch (event.type)
                {
                    case SDL_QUIT:Continue = 0; break;
                    case SDL_KEYDOWN:
                        switch(event.key.keysym.sym)
                        {
                            case SDLK_ESCAPE:Continue = 0; break;
                            case SDLK_UP: moveChara(-32, 0, UP, 0); break;
                            case SDLK_LEFT: moveChara(0, -32, LEFT, 0); break;
                            case SDLK_RIGHT: moveChara(0, +32, RIGHT, 0); break;
                            case SDLK_DOWN: moveChara(+32, 0, DOWN, 0); break;
                        }
                    break;
                }
                SDL_Flip(window);//Echange de buffers
            }
        } while (Continue);
     
    }
    Et apputez voir 10 fois de suite par exemple sur la touche droite et j'espère que vous comprenez ce que je veux dire.


    Merci à ceux qui essaieront de m'aider !

  2. #2
    Membre averti Avatar de Kujara
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    262
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Décembre 2006
    Messages : 262
    Points : 358
    Points
    358
    Par défaut
    Solution simple : un booleen quelque part, que tu met a true quand ton perso avance, et tu n'execute la donction moveChara que si ce booleen est false.

  3. #3
    Membre du Club Avatar de Jordinateur
    Profil pro
    Inscrit en
    Février 2007
    Messages
    119
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 119
    Points : 51
    Points
    51
    Par défaut
    Bien merci d'avoir répondu mais en fait j'ai fais ceci :
    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
    void moveChara(long y, long x, long direction, int previousTime)
    {
        charaIsMoving = 0;
        SDL_FillRect(window, NULL, SDL_MapRGB(window->format, 0, 0, 0));
        //CoordMainChara.y += y;
        //CoordMainChara.x += x;
        int i=0;
        while(i<4)
        {
            int actualTime = SDL_GetTicks();
            if (actualTime - previousTime >= 130)
            {
            //SDL_Delay(150);
     
            //On change la ligne d'animation selon la touche pressée
            changeSprite(direction);
     
            //On déplace progressivement le personnage pour avoir une impression de fluidité
            progressiveMove(direction);
     
            //CoordMainChara.y += y/4;
            SDL_FillRect(window, NULL, SDL_MapRGB(window->format, 0, 0, 0));
            SDL_BlitSurface (MainChara, &MainCharaSprite, window, &CoordMainChara);
            SDL_Flip(window);
            previousTime = actualTime;
            i++;
            }
     
        }
        charaIsMoving = 1;
     
    }
    J'ai donc rajouté un booléen qui dit que la fonction moveChara est en train de se déroulé et la condition qui va avec dans une autre fonction qui gère les événements(le booléen est une variable générale).

    Simplement je me rend compte que se booléen ne sert à rien.
    Effectivement, le programme, sans threads ne peux "être" dans plusieurs fonction à la fois : ce qui veut dire que si la fonction moveChara est en train de se dérouler, la boucle d'événements ne peux pas se dérouler !
    J'en conclut donc que si la boucle d'événement ne se déroule pas pendant moveChara, la variable event prendra la valeur de la touche en même temps aparemment, qui elle-même sera utilisée plus tard puisqu'elle aura toujours la valeurs de la touche appuyée. C'est là seule chose qui me parait logique...
    J'espère que vous avez suivit ...
    En tout cas cette méthode ne marche pas... Si quelqu'un aurait une autre solution !

  4. #4
    screetch
    Invité(e)
    Par défaut
    ce que tu peux faire c'est "poller" avec SDL_PollEvent(&event) plusieurs evenements grace a la fonction SDL_PeepEvents

    donc dans ce cas tu peux interroger la base sur les evenements en cours et ne prendre que le premier (ou plutot le dernier, c'est plus agreable pour le joueur)

    une autre facon de faire est de rassembler tous les evenements dansu ne structure representant le clavier avec un tableau de booleens en gros; dans la fonction principale tu mets a jour toute les touches appuyées puis tu passes le tableau de touches a ta fonction MoveChara qui agira en consequences.

  5. #5
    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
    Attention, ce programme est voué à l'echec. La première régle de base dans la programmation SDL (et WinAPI d'ailleurs) et de ne pas bloquer le contrôle au sein d'une fonction.

    Il faut que le programme revienne périodiquement à la boucle événementielle.

    Du coup, ceci :
    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
    void moveChara(long y, long x, long direction, int previousTime)
    {
        charaIsMoving = 0;
        SDL_FillRect(window, NULL, SDL_MapRGB(window->format, 0, 0, 0));
        //CoordMainChara.y += y;
        //CoordMainChara.x += x;
        int i=0;
        while(i<4)
        {
            int actualTime = SDL_GetTicks();
            if (actualTime - previousTime >= 130)
            {
            //SDL_Delay(150);
     
            //On change la ligne d'animation selon la touche pressée
            changeSprite(direction);
     
            //On déplace progressivement le personnage pour avoir une impression de fluidité
            progressiveMove(direction);
     
            //CoordMainChara.y += y/4;
            SDL_FillRect(window, NULL, SDL_MapRGB(window->format, 0, 0, 0));
            SDL_BlitSurface (MainChara, &MainCharaSprite, window, &CoordMainChara);
            SDL_Flip(window);
            previousTime = actualTime;
            i++;
            }
     
        }
        charaIsMoving = 1;
     
    }
    est une erreur grave de conception de programme. Si tu commences à vouloir avoir plusieurs personnages, tu vas faire comment ? bloquer le processus pour chaque personnage l'un derrière l'autre ?

    Il faut concevoir de combien tu veux bouger le joueur, la dernière fois que tu l'as bougé et à chaque iteration, tu mets à jour sa position et les compteurs internes.

    Si le joueur appuie plusieurs fois sur une touche direction, soit tu ignores car le perso est encore en mouvement, soit tu cumules.

    Jc

  6. #6
    Membre du Club Avatar de Jordinateur
    Profil pro
    Inscrit en
    Février 2007
    Messages
    119
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 119
    Points : 51
    Points
    51
    Par défaut
    screetch :
    J'ai pas tout compris désolé
    Je ne connais pas la fonction SDL_PeepEvent j'irais me renseigné quand j'aurais fini mes devoirs (o yé on commence à faire des commentaires de textes ))

    Sinon pour la structure c'est pas bête j'essayerais peut-être

    fearyourself :
    Ba je connaissais pas cette règle !
    Mais quand tu dis "ne pas bloquer les contrôles dans une fonction" sa veut dire que je ne dois pas attendre les événements dans une fonction à part c'est ça ? (au cas où il y aurait un quiproco )

    Et sinon jvois pas trop ce que tu veux dire quand avec l'histoire des personnage...

    Si le joueur appuie plusieurs fois sur une touche direction, soit tu ignores car le perso est encore en mouvement, soit tu cumules.
    C'est justement ce que je n'arrives pas à faire


    Je suis désolé de comprendre aussi peu de choses !

  7. #7
    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
    Citation Envoyé par Jordinateur Voir le message
    Mais quand tu dis "ne pas bloquer les contrôles dans une fonction" sa veut dire que je ne dois pas attendre les événements dans une fonction à part c'est ça ? (au cas où il y aurait un quiproco )
    Exactement.

    Et sinon jvois pas trop ce que tu veux dire quand avec l'histoire des personnage...
    Il faut que tu stockes dans ton personnage sa position actuelle, sa position finale et le temps qu'il va prendre pour y arriver. Ensuite c'est une question d'interpolation.

    Une autre solution est de se souvenir de la position de départ, de la direction , du dernier temps de mis-à-jour et cela suffira pour créer le mouvement.

    A chaque itération, tu appelles une fonction de mis-à-jour qui modifiera la position du perso.

    Jc

  8. #8
    Membre du Club Avatar de Jordinateur
    Profil pro
    Inscrit en
    Février 2007
    Messages
    119
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 119
    Points : 51
    Points
    51
    Par défaut
    Il faut que tu stockes dans ton personnage sa position actuelle, sa position finale et le temps qu'il va prendre pour y arriver. Ensuite c'est une question d'interpolation.

    Une autre solution est de se souvenir de la position de départ, de la direction , du dernier temps de mis-à-jour et cela suffira pour créer le mouvement.

    A chaque itération, tu appelles une fonction de mis-à-jour qui modifiera la position du perso.
    Mais en fait c'est ce que j'ai fais aussi sauf avec un booléen. Et sa n'a pas marché : j'apellais seulement la fonction quand le mouvement était terminé mais je ne sais pas pourquoi elle se réexécutait autant de fois que j'avais appuyé sur la touche directionnelle !
    Alors je ne penses pas que sa marcherait aussi si je faisais comme ça : admettons que j'apelle par exemple la fonction lorsque newX == x+32, ce qui voudrais donc dire que pendant le temps où newX est inférieur à 32, la pression d'une touche directionnelle n'apellerais pas la fonction ; or c'est ce que j'ai fais justement avec ce booléen, mais seulement une fois la fonction exécutée elle se réexécute autant de fois que j'ai appuyé sur une touche directionnelle...Ce qui se passera logiquement aussi avec ta solution je pense

  9. #9
    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
    Citation Envoyé par Jordinateur Voir le message
    mais seulement une fois la fonction exécutée elle se réexécute autant de fois que j'ai appuyé sur une touche directionnelle...Ce qui se passera logiquement aussi avec ta solution je pense
    Non, car moi je sors de la fonction de mise à jour afin de traiter les messages en attente. Du coup, pendant le mouvement du joueur, je peux traiter le message de mouvement et choisir de l'ignorer.

    Jc

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    58
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 58
    Points : 63
    Points
    63
    Par défaut
    Citation Envoyé par Jordinateur Voir le message
    [...] mais je ne sais pas pourquoi elle se réexécutait autant de fois que j'avais appuyé sur la touche directionnelle !
    La méthode que tu utilise, ne te donne pas l'état du clavier 'en temps réel', les touches sont stockées dans un buffer et la méthode effectue une lecture du buffer (du moins si mes souvenir sont bon).

    Si tu veux résoudre ton problème tu peux tenter d'utiliser des méthodes du type SDL_GetKeyState : (http://www.libsdl.org/docs/html/sdlgetkeystate.html)

    Cela donne l'état instantané du clavier. Cependant je te conseille plutôt de suivre les conseils de fearyourself et de ne pas bloquer l'execution de ton programme car à terme, cela risque de poser problème.

  11. #11
    Membre du Club Avatar de Jordinateur
    Profil pro
    Inscrit en
    Février 2007
    Messages
    119
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 119
    Points : 51
    Points
    51
    Par défaut
    Oui mais comment dois-je faire ceci ?!
    Je ne vois pas vraiment ce que vous voulez dire par "ne pas bloquer de ton programme"...

    Car de toute façon mon programme sera bloqué par une boucle principale et événementielle !

  12. #12
    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
    Citation Envoyé par Jordinateur Voir le message
    Oui mais comment dois-je faire ceci ?!
    Je ne vois pas vraiment ce que vous voulez dire par "ne pas bloquer de ton programme"...

    Car de toute façon mon programme sera bloqué par une boucle principale et événementielle !
    Non ce qu'il faut c'est que le programme revienne périodiquement à la boucle générale et à la boucle événementielle.

    Si tu gardes cela comme régle générale, tu vas forcément tendre vers un code qui ressemblerait à ce que je conseille.

    Jc

  13. #13
    Membre du Club Avatar de Jordinateur
    Profil pro
    Inscrit en
    Février 2007
    Messages
    119
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 119
    Points : 51
    Points
    51
    Par défaut
    Et comment je dois faire sa ?!

    Je comprend mais alors vraiment rien

    En résumé je dois appeler les événements dans la fonction main sans bloquer pour autant le programme... Mais sans boucle c'esxt pas possible de vérifier la condition en permanence !

    Je suis complètement perdu !!

  14. #14
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    58
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 58
    Points : 63
    Points
    63
    Par défaut
    Je vais tenter de t'expliquer le problème du blocage mais c'est pas forcement évident et je connais pas de tutoriels sur le sujet.

    En gros, l'idée c'est de supprimer dans ton programme la boucle : 'while(i<4)' et l'attente associée de manière a ce que : "le programme revienne périodiquement à la boucle événementielle".

    Pour un bien, la boucle événementielle doit être executée environ (et il s'agit d'un minimum) 15 fois par seconde , quelquesoit l'état du programmme. Dans ton cas lors d'un déplacement il y a un délai de 4*130 = 520 ms (au minimum) entre deux iteration de la boucle événementielle, c'est beaucoup trop.

    En fait tu peux t'arranger pour que, lorsceque ton programme patiente 130 ms avant de bouger ton sprite, il revienne à la boucle evenementielle.

  15. #15
    Membre du Club Avatar de Jordinateur
    Profil pro
    Inscrit en
    Février 2007
    Messages
    119
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 119
    Points : 51
    Points
    51
    Par défaut
    Ha mais oui !! J'ai tout compris là !
    Je suis bête en plus sa m'était déjà arrivé !
    En fait il ne faut pas mettre de boucle en dehors de la boucle principal sinon après les évènements ne peuvent pas être appellés ! C'est pour ça que ça me fait ça !!!

    Bon jvais voir ce que jpeux faire !
    Je pense que je vais tout recoder corectement (à la base en fait c'était juste un code pour tester la gestion des sprites avec SDL, j'avais pas prévu les déplacements donc c'est un peu mal codé !)

    Je vous tiens au courant sur ce topic !

  16. #16
    Expert éminent sénior
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 360
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 360
    Points : 20 378
    Points
    20 378
    Par défaut
    Citation Envoyé par Jordinateur Voir le message
    screetch :

    fearyourself :
    Ba je connaissais pas cette règle !
    Mais quand tu dis "ne pas bloquer les contrôles dans une fonction" sa veut dire que je ne dois pas attendre les événements dans une fonction à part c'est ça ? (au cas où il y aurait un quiproco )

    Et sinon jvois pas trop ce que tu veux dire quand avec l'histoire des personnage...
    Les événements se gèrent dans le main() je conseille vivement de chercher tous les tutoriels sur SDL.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
     while(i<4)
        {
            int actualTime = SDL_GetTicks();
            if (actualTime - previousTime >= 130)
            {
    tu emploies un while ce qui est une grosse erreur et SDL_GetTicks() s'emploie tjs dans le main() en général
    Dans le main on initialise une variable temps1 comme tu le fais puis on appelle
    SDL_GetTicks() pour calculer le delta de temps.
    Si le delta de temps = certaine valeur alors on réactualise le personnage.

    Je te conseille vivement de chercher dans les tutos de SDL sinon j'avais fait un petit programme cherche sur les forums

  17. #17
    Membre du Club Avatar de Jordinateur
    Profil pro
    Inscrit en
    Février 2007
    Messages
    119
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 119
    Points : 51
    Points
    51
    Par défaut
    Un programme sur quoi ? bah en attendant j'irais voir si jtrouve des tutos et ton programme.

  18. #18
    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
    Ok j'ai pris un peu le temps d'implémenter une version très simplifiée d'un système comme tu le voudrais.

    Il faudrait l'étendre pour être plus général :

    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
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <SDL.h>
     
    #define WIDTH 640
    #define HEIGHT 480 
     
    typedef struct sElem {
        SDL_Rect pos;
        SDL_Surface *surf;
        int ax;
        int ay;
        int mouvement;
    }SElem;
     
    int Gestion_Clavier(SElem *elem, int key)
    {
        switch(key) 
        {
            case SDLK_UP:
                if(elem->mouvement == 0) {
                    elem->mouvement = 40;
                    elem->ay = -1;
                }
                break;
            case SDLK_DOWN:
                if(elem->mouvement == 0) {
                    elem->mouvement = 40;
                    elem->ay = 1;
                }
                break;
            case SDLK_RIGHT:
                if(elem->mouvement == 0) {
                    elem->mouvement = 40;
                    elem->ax = 1;
                }
                break;
            case SDLK_LEFT:
                if(elem->mouvement == 0) {
                    elem->mouvement = 40;
                    elem->ax = -1;
                }
                break;
            case 'q':
                return 0;
     
            default:
                break;
        }
        return 1;
    }
     
    void Elem_Update(SDL_Surface* screen, SElem *elem)
    {
        int newposx = elem->pos.x + elem->ax;
        int newposy = elem->pos.y + elem->ay;
     
        elem->mouvement--;
     
        if((newposx < 0) || (newposx + elem->surf->w > screen->w)) {
            elem->mouvement = 0;
        }
     
        if((newposy < 0) || (newposy + elem->surf->h > screen->h)) {
            elem->mouvement = 0;
        }
     
        if(elem->mouvement <= 0) {
            elem->mouvement = 0;
            elem->ax = 0;
            elem->ay = 0;
        }
        else {
            elem->pos.x = newposx;
            elem->pos.y = newposy;
        }
    }
     
    void Elem_Draw(SDL_Surface *screen, SElem *elem)
    {
        SDL_BlitSurface(elem->surf, NULL, screen, &(elem->pos));
    }
     
    void Elem_Init(SElem *elem, SDL_Surface *screen)
    {
        SDL_Surface *tmp;
     
        memset(elem, 0, sizeof(*elem));
     
        elem->pos.x = screen->w / 2;
        elem->pos.y = screen->h - 50;
     
        tmp = SDL_CreateRGBSurface(SDL_HWSURFACE, 32, 32, screen->format->BitsPerPixel,
                                            screen->format->Rmask,
                                            screen->format->Gmask,
                                            screen->format->Bmask,
                                            screen->format->Amask);
     
        if(tmp == NULL) {
            fprintf(stderr, "Probleme avec la creation de la surface\n");
            exit(EXIT_FAILURE);
        }
     
        elem->surf = SDL_DisplayFormat(tmp);
        SDL_FreeSurface(tmp);
        SDL_FillRect(elem->surf, NULL, SDL_MapRGB(elem->surf->format, 255, 0, 0));
    }
     
    int main(void)
    {
        int cont = 1;
        SElem monelem;
        SDL_Event event;
     
        SDL_Surface *screen;
     
        /* Initialisation de la SDL */
        if(SDL_Init(SDL_INIT_VIDEO)!=0) {
            fprintf(stderr, "Probleme pour initialiser SDL: %s\n", SDL_GetError());
            return EXIT_FAILURE;
        }
     
     
        //Ouvrir une fenetre
        screen = SDL_SetVideoMode(WIDTH, HEIGHT, 32, SDL_DOUBLEBUF);
        if(screen==NULL) {
            fprintf(stderr, "Probleme pour ouvrir la fenetre SDL: %s\n", SDL_GetError());
            return EXIT_FAILURE;
        }
     
        /* Initialisation de l'element */
        Elem_Init(&monelem, screen);
     
        while(cont != 0) {
            /* Gere les evenements */
            while(SDL_PollEvent(&event)) {
                switch(event.type) 
                {
                    case SDL_QUIT:
                        cont = 0;
                        break;
                    case SDL_KEYUP:
                        /* Une touche */
                        cont = Gestion_Clavier(&monelem, event.key.keysym.sym);
                        break;
                    default:
                        break;
                }
            }
     
            /* Gere l'element */
            Elem_Update(screen, &monelem);
     
            /* Efface ecran */
            SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));
     
            /* Affiche l'element */
            Elem_Draw(screen, &monelem);
     
            /* Flip */
            SDL_Flip(screen);
        }
     
        SDL_Quit();
        return EXIT_SUCCESS;
    }
    Pose des questions sur ce que tu ne comprends pas.

    Jc

  19. #19
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    58
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 58
    Points : 63
    Points
    63
    Par défaut
    C'est codé super proprement en tout cas.

    Seule petite 'critique', la vitesse du sprite est dépendante des performances de la machine mais c'est facile à corriger.

  20. #20
    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
    Citation Envoyé par Bibicy Voir le message
    C'est codé super proprement en tout cas.
    Merci

    Seule petite 'critique', la vitesse du sprite est dépendante des performances de la machine mais c'est facile à corriger.
    Je sais, je n'ai pas eu le temps de faire jouer le temps à la place, c'est un code qui montre l'exemple mais il y a des choses à changer c'est clair.

    Jc

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 1
    Dernier message: 10/02/2009, 21h30
  2. Réponses: 4
    Dernier message: 21/11/2007, 12h19
  3. Réponses: 10
    Dernier message: 18/07/2007, 17h36
  4. Réponses: 5
    Dernier message: 05/01/2006, 18h43
  5. comment ne pas enregistrer dans le fichier log?
    Par trotters213 dans le forum MS SQL Server
    Réponses: 14
    Dernier message: 21/03/2005, 14h56

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