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 :

De très légères saccades ?


Sujet :

SDL

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 11
    Points : 1
    Points
    1
    Par défaut De très légères saccades ?
    J'ai commencé à me servir de SDL il y a quelques jours, et je remarque seulement maintenant lorsque je déplace une simple image à l'aide du clavier de très légères saccades ttes les 1/2-1 seconde environ, alors que sinon c'est parfaitement fluide.(le mot "saccade" est presque exagéré, c'est presque un petit "saut" comme si le deplacement (ou l'affichage de l'image) n'etait pas totalement constant). Je n'ai aucune idée d'où ça vient, j'ai consulté plusieurs tutos, j'ai pensé au framerate, mais je gère les fps correctement je crois (du type if (SDL_Getticks()-previous_time>DELAY) { boucle(); } else SDL_Delay(1);
    Je me suis dit que ça venait peut-être de SDL_Delay() qui n'est pas très précis alors j'ai essayé aussi en laissant SDL gérer le framerate avec SDL_framerate.h , c'est exactement pareil.

    Ca ne vient pas de la gestion des touches non plus (j'ai essayé en déplaçant simplement l'image de droite à gauche sans l'action des touches et c'est pareil).

    A part ça je suis sous Linux..

    Voilà c'est peu d'infos mais si vous avez une idée merci de m'en faire part. J'éditerai le post pour mettre un lien vers mes sources et le programme compilé pour voir.

    Voilà j'ai fait un nouveau projet histoire de garder le strict nécessaire (ça ressemble plus à un copier-coller de divers tutos qu'à autre chose).
    Sources
    Executable
    (se placer dans le répertoire de l'executable pour le lancer histoire qu'il trouve les images..)

    Dites-moi si vous voyez aussi ces petites saccades..

    Edit : pour ceux qui auraient la flemme de télécharger de le .zip, voici le "code" (mais seul le main.cpp est important) :
    main.cpp :
    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
    #include <stdlib.h>
    #include <stdio.h>
    #include <time.h>
     
    #include <SDL/SDL_image.h>
    #include "main.h"
    #include "controls.cpp"
    #include "graphics.cpp"
     
    int main(int argc, char *argv[])
    {
        int x=0,y=0;
     
        SDL_Init(SDL_INIT_VIDEO); // Initialisation de la SDL
     
        screen=SDL_SetVideoMode(W_SCREEN, H_SCREEN, 32, (SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_ANYFORMAT)); // Ouverture de la fenêtre
     
        LoadImages();
     
        for(;;)
        {
            if (SDL_GetTicks()-ticks >= DELAY)
            {
                ticks=SDL_GetTicks();
     
                DrawImage(bg, 0, 0, screen, 0, 0, W_SCREEN, H_SCREEN,0xFF00FF);
                DrawImage(tux, 0, 0, screen, x, y, 32, 32,0xFF00FF);
     
                if (keyboard.continu_key&KEY_LEFT) x--;
                if (keyboard.continu_key&KEY_UP) y--;
                if (keyboard.continu_key&KEY_RIGHT) x++;
                if (keyboard.continu_key&KEY_DOWN) y++;
     
                process_events();
                SDL_Flip(screen);
     
                if (quit==1) break;
            }
            else SDL_Delay(1);
        }
     
        SDL_Quit(); // Arrêt de la SDL
     
        return EXIT_SUCCESS; // Fermeture du programme
    }
    main.h :
    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
    #define W_SCREEN 320
    #define H_SCREEN 240
    #define LEFTCLICK 1
    #define RIGHTCLICK 2
    #define KEY_UP 1
    #define KEY_RIGHT 2
    #define KEY_DOWN 4
    #define KEY_LEFT 8
    #define FPS 60
    #define DELAY (1000/FPS)
     
    struct sMouse
    {
        int button;
        int x, y;
    } mouse;
     
    struct sKeyboard
    {
        int continu_key;
        int pressed_key;
    } keyboard={0,0};
     
    int MouseButton=0;
    int ticks=0;
    int t_fps=0;
    int quit=0;
     
    SDL_Surface *bg,*tux,*screen;
    controls.cpp :
    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
    void process_events()
    {
        SDL_Event event;
     
        mouse.button=0;
        keyboard.pressed_key=0;
     
        if(SDL_PollEvent(&event))
        {
            switch(event.type)
            {
                case SDL_QUIT:
                    quit=1;
                case SDL_MOUSEBUTTONDOWN:
                    mouse.button=event.button.button;
                    mouse.x=event.button.x;
                    mouse.y=event.button.y;
                    break;
                case SDL_KEYUP:
                    switch (event.key.keysym.sym)
                    {
                        case SDLK_UP: keyboard.continu_key&=~KEY_UP; break;
                        case SDLK_RIGHT: keyboard.continu_key&=~KEY_RIGHT; break;
                        case SDLK_DOWN: keyboard.continu_key&=~KEY_DOWN; break;
                        case SDLK_LEFT: keyboard.continu_key&=~KEY_LEFT; break;
                        default: break;
                    }
                    break;
                case SDL_KEYDOWN:
                    switch (event.key.keysym.sym)
                    {
                        case SDLK_UP: keyboard.pressed_key|=KEY_UP; keyboard.continu_key|=KEY_UP; break;
                        case SDLK_RIGHT: keyboard.pressed_key|=KEY_RIGHT; keyboard.continu_key|=KEY_RIGHT; break;
                        case SDLK_DOWN: keyboard.pressed_key|=KEY_DOWN; keyboard.continu_key|=KEY_DOWN; break;
                        case SDLK_LEFT: keyboard.pressed_key|=KEY_LEFT; keyboard.continu_key|=KEY_LEFT; break;
                        default: break;
                    }
                default:
                    break;
            }
        }
    }
    graphics.cpp :
    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
    void LoadImages()
    {
        bg=IMG_Load("bg.bmp");
        tux=IMG_Load("tux.png");
    }
     
    void DrawImage(SDL_Surface *src, int bmp_x, int bmp_y, SDL_Surface *dest, int screen_x, int screen_y, int size_x, int size_y,int transp)
    {
            SDL_Rect src_blitrect = {bmp_x,bmp_y,size_x,size_y}, dest_blitrect = {screen_x,screen_y,size_x,size_y};
     
            int r,v,b;
            r=transp>>16;
            v=(transp>>8)&0xFF;
            b=transp&0xFF;
     
            SDL_SetColorKey(src, SDL_SRCCOLORKEY, SDL_MapRGB(src->format, r, v, b));
            SDL_BlitSurface(src, &src_blitrect, dest, &dest_blitrect);
    }

  2. #2
    Membre expérimenté
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Points : 1 452
    Points
    1 452
    Par défaut
    Salut,

    je pense que ça peut venir de différentes raison, et qu'avoir les sources ça serait l'idéal.

  3. #3
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 11
    Points : 1
    Points
    1
    Par défaut Edit du premier post
    Voilà j'ai édité il y a les "sources" et l'exécutable.. C'est relativement peu visible mais quand même.. ça me gêne un peu..

  4. #4
    Membre expérimenté
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Points : 1 452
    Points
    1 452
    Par défaut
    Salut,

    j'ai fait quelques modif, sur mon ordi ça améliore un peu les choses

    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
    #include <stdlib.h>
    #include <stdio.h>
    #include <time.h>
     
    #include <SDL/SDL_image.h>
    #include "main.h"
    #include "controls.cpp"
    #include "graphics.cpp"
     
    int x=0,y=0;
     
    Uint32 display(Uint32 delay, void *param)
    {
        if (keyboard.continu_key&KEY_LEFT) x-=1;
        if (keyboard.continu_key&KEY_UP) y-=1;
        if (keyboard.continu_key&KEY_RIGHT) x+=1;
        if (keyboard.continu_key&KEY_DOWN) y+=1;
     
        DrawImage(bg, 0, 0, screen, 0, 0, W_SCREEN, H_SCREEN,0xFF00FF);
        DrawImage(tux, 0, 0, screen, x, y, 32, 32,0xFF00FF);
     
        SDL_Flip(screen);
     
        return 10;
    }
     
    int main(int argc, char *argv[])
    {
        SDL_Init(SDL_INIT_EVERYTHING); // Initialisation de la SDL
     
        screen=SDL_SetVideoMode(W_SCREEN, H_SCREEN, 32, (SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_ANYFORMAT)); // Ouverture de la fenêtre
     
        SDL_AddTimer(10, display, NULL);
     
        LoadImages();
     
        for(;;)
        {
            process_events();
            if (quit==1) break;
            SDL_Delay(1);
        }
     
        SDL_Quit(); // Arrêt de la SDL
     
        return EXIT_SUCCESS; // Fermeture du programme
    }
    J'ai utilisé un SDL_Timer: ça veut dire que toutes les 10 ms, la fonction dans le timer est appelée. Attention, pour pouvoir utiliser les timers, il faut ajouter le flag approprié dans SDL_Init.

    Voici le lien de la doc officielle: http://www.libsdl.org/cgi/docwiki.cgi/SDL_AddTimer

    Et comme il est expliqué, il y a une 'granularité' de 10 ms, ça veut dire qu'en gros il vaut mieux utiliser des valeurs comme 10/20/30/40... ms
    Donc avec 10ms ça rend bien, avec 16 ms moins bien (probablement du fait de cette granularité)

    Enfin c'est vraiment pas grand chose, mais je doute qu'il y ait un autre moyen.

    Sinon, fais attention dans ton main.h, à mettre des parenthèses pour delay:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define DELAY (1000/FPS)
    est plus prudent dans le cas où tu es amené à faire des divisions par DELAY.

    Peut être que d'autres membres ont des meilleures solutions/explications, moi je vois pas grand chose

    Coyotte507

  5. #5
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 11
    Points : 1
    Points
    1
    Par défaut Merci
    Effectivement on n'a plus ce problème de saccades... Mais je ne comprends pas trop d'où venait le problème.. ?
    Et puis ce code est bizarre, je n'ai jamais vu de fonctions de ce genre en C : quand la fonction display est-elle appelée ? On dirait du C++.. ? (je connais peu le C++)
    S'il n'y a pas d'autre solution je ferai comme ça, mais j'aimerais autant comprendre d'où venait le problème.
    Merci beaucoup en tout cas.

  6. #6
    Membre expérimenté
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Points : 1 452
    Points
    1 452
    Par défaut
    Salut,

    le problème venait surement de SDL_Delay(1) qui peut faire un délai plus important (genre 10 ms et quelquefois un peu plus).

    Ce code n'est pas du C++, loin de là.

    En fait (je ne sais pas si tu connais les threads), SDL va faire en sorte que la fonction soit appelée toutes les X ms (en utilisant le truc de l'OS je crois, ce qui est plus précis).

    On passe un pointeur de fonction à une fonction qui crée un thread pour exécuter la fonction dans le pointeur en parallèle du programme principal toutes les X ms

  7. #7
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 11
    Points : 1
    Points
    1
    Par défaut
    Effectivement je ne connais pas les thread. T'aurais des liens à me proposer sur ce sujet ? J'ai jamais fait ce genre de programmation. J'avais jamais rien vu de tel, ni dans des sources ni dans des bouquins de C standard (ça ne fait pas partie du standard en fait, mais faut dire qu'il y a pas grand chose qui en fait partie). Faudrait que je me renseigne, je vois pas du tout comment coder une fonction qui prendrait en argument une fonction elle-même (et non pas une valeur ou un pointeur renvoyé par ladite fonction). Merci

  8. #8
    Membre expérimenté
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Points : 1 452
    Points
    1 452
    Par défaut
    Pour les classes, ça a une syntaxe particulière, je ne les ai jamais utilisés donc je ne peux pas dire, mais tu dois pouvoir trouver sur Google

    Je fais du C++, je pense que y'a moins besoin de les utiliser,et donc que je leur trouve moins d'utilité (bien que je croies que bientôt je vais devoir).

    En C, je pense que ça permet de donner un comportement différent à un objet.
    Je vais essayer de réfléchir à un exemple, ça permet par exemple d'utiliser des fonctions dans des structures, sinon en C++ je vois pas trop, ça va être intéressant de réfléchir dessus .

    Imagine que tu aies un bouton (c'est du C++), et que tu veux qu'à chaque fois que quelqu'un clique sur le bouton, une action soit exécutée.

    Donc tu as une classe Bouton: (j'ai essayé de rapprocher un peu ce code du C, en vrai j'aurais changé quelques petites choses)

    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
    class Bouton
    {
        public:
             SDL_Surface *s;
             int x, y;
     
             /* Le pointeur de fonction, qui va déterminer le comportement que tu
                 veux sur un clic */
             void (*ActionSurClic)(void);
     
             bool dedans(int x, int y) { /* ... */};
             bool gereClic (const SDL_ButtonEvent *bevent)
             {
                  //Si le clic est dedans, on gere l'évènement
                  if ( dedans(bevent->x, bevent->y) )
                  {
                       //On exécute l'action demandée
                       ActionSurClic();
                       return true;
                   }
                   //Sinon on retourne false, on n'a pas géré l'évènement
                   return false;
              }
              /* Autres fonctions, comme initialiser, afficher, ...
           
                  ...
                  ...
               */
    };
    Et ainsi, tu peux changer ce qui arrive quand on clique sur un bouton en fonction de tes besoins. Si par exemple tu as un bouton quitter, et un bouton jouer ils ne vont pas faire la même chose
    Néanmoins il existe d'autre méthodes pour avoir le même effet, comme hériter la classe, enfin comme tu vois j'ai pas beaucoup d'inspiration

    Pour ma part, j'utilise encore quelque chose de différent, qui permet de pas trop surcharger le code (mais c'est très légèrement moins performant).

    Sinon j'ai réfléchi, il y a un autre exemple, plus orienté jeux vidéo, mais un peu complexe à décrire (surtout en C), je verrais demain.

    Bonne nuit

  9. #9
    Expert éminent sénior
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 362
    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 362
    Points : 20 391
    Points
    20 391
    Par défaut
    Je vais éviter de la ramener là-dessus mais si tu veux plus de performances, prends carrément Direct3d ( d3d9 ou d3d10 ) je pense que cela sera plus performant , tu gardes SDL pour une éventuelle version Linux...
    SDL est bien pour débuter et faire des "essais" mais question performances c'est pas toujours au rendez-vous j'en sais quelque chose..
    Je me suis dit que ça venait peut-être de SDL_Delay() qui n'est pas très précis alors j'ai essayé aussi en laissant SDL gérer le framerate avec SDL_framerate.h , c'est exactement pareil.
    faut voir dans les sources comment ils ont implémenté leur timer..en win32 /DX tu peux utiliser QueryPerformanceCounter() mais ce n'est pas portable et dépendant de l'OS

  10. #10
    Membre expérimenté
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Points : 1 452
    Points
    1 452
    Par défaut
    Salut,

    concernant les pointeurs de fonctions, une autre utilisation dans la SDL:

    Il y a une structure pour faire des blits de surface, et il y a plusieurs fonction de blits (il surffit de regarder les sources de la SDL), et donc chaque structure de Blit possède un pointeur de fonction qui permet de réaliser un blit adapté à elle-même.

    En C++, cela pourrait être fait par un héritage et des méthodes virtuelles, mais je n'ai aucune idée de si les performances sont au rendez-vous ou non.

    Concernant l'autre exemple dont j'ai parlé, j'ai essayé de le mettre en pratique ici, via du C++ car j'utilise des maps, et c'est chaud à faire en C
    Il s'agit d'une structure Personnage, qui possède une seule parmi plusieurs capacités: voler, attaquer, fuir, crocheter. Faire ça en C++ c'est simple, il suffit de faire 4 héritages différents.

    Seulement voilà, le personnage peut changer de capacité. Pour le moment en C++ je ne vois pas comment faire ça avec l'héritage simple.

    Voilà le code, en brut:
    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
    #include <cstdlib>
    #include <cstdio>
    #include <map>
     
    using namespace std;
     
    /* Les différentes capacités d'un personnage */
    enum Capacite
    {
         Voler = 0,
         Attaquer = 1,
         Fuir = 2,
         Crocheter = 3
    };
     
    /* Une capacite d'un joueur suis le prototype:
     
        void capacite(void *contexte); */
     
    void voler(void * contexte);
    void attaquer(void * contexte);
    void fuir(void * contexte);
    void crocheter(void *contexte);
     
    /* un typedef utile */
    typedef void (*fct_capacite)(void*);
     
    /* Initialisation de la structure qui contient tous les pointeurs de fonction
     
       Je n'utilise pas un tableau tout simple, parceque sinon le compilateur me hurle dessus,
       et avec un vector ça bugge (évidemment) */
    map<Capacite, fct_capacite> TabCapacites;
     
    void init()
    {
        TabCapacites[Voler] = voler;
        TabCapacites[Attaquer] = attaquer;
        TabCapacites[Fuir] = fuir;
        TabCapacites[Crocheter] = crocheter;
    }
     
    /* Le personnage */
    struct Personnage
    {
         Capacite capacite;
     
         fct_capacite action;
         Personnage() : capacite(Voler){};
         void change_capacite(Capacite nouvelle_capacite);
    };
     
    /* Fonction pour changer de capacité, relativement courte comme l'on voit */
    void Personnage::change_capacite(Capacite nouvelle_capacite)
    {
         capacite = nouvelle_capacite;
         action = TabCapacites[nouvelle_capacite];
    }
     
    /*
        Les fonctions associées aux diverses capacités
     */
    void voler(void *contexte)
    {
        puts("Vol!");
    }
     
    void attaquer(void *contexte)
    {
        puts("Attaque!");
    }
     
    void fuir(void *contexte)
    {
        puts("Fuite!");
    }
     
    void crocheter(void* contexte)
    {
        puts("Crochetage");
    }
     
    int main()
    {
        init();
     
        Personnage monperso;
     
        monperso.change_capacite(Voler);
        monperso.action(NULL); //Affiche "Vol!"
     
        monperso.change_capacite(Attaquer);
        monperso.action(NULL); //Affiche "Attaque!"
     
        return 0;
    }
    et voilà ce que ça aurait donné sans les pointeurs de fonction:

    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
    #include <cstdlib>
    #include <cstdio>
    #include <map>
     
    using namespace std;
     
    /* Les différentes capacités d'un personnage */
    enum Capacite
    {
         Voler = 0,
         Attaquer = 1,
         Fuir = 2,
         Crocheter = 3
    };
     
    /* Une capacite d'un joueur suis le prototype:
     
        void capacite(void *contexte); */
     
    void voler(void * contexte);
    void attaquer(void * contexte);
    void fuir(void * contexte);
    void crocheter(void *contexte);
     
    /* Le personnage */
    struct Personnage
    {
         Capacite capacite;
     
         void action(void *contexte);
         Personnage() : capacite(Voler), action(NULL){};
         void change_capacite(Capacite nouvelle_capacite);
    };
     
    /* Fonction pour changer de capacité, relativement courte comme l'on voit */
    void Personnage::change_capacite(Capacite nouvelle_capacite)
    {
         capacite = nouvelle_capacite;
    }
     
    void Personnage::action(void *contexte)
    {
        switch (capacite)
        {
            case Attaquer:
                attaquer(contexte);
                break;
            case Fuir:
                fuir(contexte);
                break;
            case Crocheter:
                crocheter(contexte);
                break;
            case Voler:
                voler(contexte);
                break;
        }
    }
     
    /*
        Les fonctions associées aux diverses capacités
     */
    void voler(void *contexte)
    {
        puts("Vol!");
    }
     
    void attaquer(void *contexte)
    {
        puts("Attaque!");
    }
     
    void fuir(void *contexte)
    {
        puts("Fuite!");
    }
     
    void crocheter(void* contexte)
    {
        puts("Crochetage");
    }
     
    int main()
    {
        Personnage monperso;
     
        monperso.change_capacite(Voler);
        monperso.action(NULL); //Affiche "Vol!"
     
        monperso.change_capacite(Attaquer);
        monperso.action(NULL); //Affiche "Attaque!"
     
        return 0;
    }
    La différence, c'est que dans ce cas (sans les pointeurs de fonctions), le code est plus court; mais par contre lorsqu'on veut faire une action, on doit trouver quoi faire en fonction de la capacite du personnage (ici un switch), alors qu'avec les pointeurs de fonction, le personnage réagit directement.
    Si il existait plusieurs structures de personnages différentes, genre PersoTypeA, PersoTypeB, ..., alors en plus on ne serait pas obligé de réécrire la méthode action() pour chaque structure.

    Voilà, j'ai essayé de bricoler un exemple, mais je suis conscient que ce n'est peut-être pas le meilleur moyen de faire, et que si tu n'as jamais fait de C++ il doit y avoir plusieurs obscurs.

    Coyotte507

  11. #11
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 11
    Points : 1
    Points
    1
    Par défaut
    Merci bien pour ces exemples ! Ils sont très parlant pour moi. Pas de problème de compréhension, j'ai jamais fait de C++ mais je m'y suis déjà un peu interressé par curiosité. C'est relativement proche des structures qu'on a en C.

    Sinon, j'ai pas vraiment besoin de grosses performances, ce problème résolu SDL me convient bien et puis ça a l'avantage d'être portable. Si j'ai besoin de meilleures performances j'en changerai.

  12. #12
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 11
    Points : 1
    Points
    1
    Par défaut
    J'ai crié victoire trop vite. Les saccades n'ont en fait pas disparu.. Il suffit d'augmenter un peu la vitesse (*2) pour s'en rendre compte. Je crois que ça ne vient définitivement pas de la gestion du temps : en fait même en essayant sans fps, simplement en mettant tout dans une boucle, on a ces saccades (ces ralentissements ou accélérations). Bref le déplacement n'est pas fluide, et je trouve ça vraiment très gênant.
    Ca ne gêne que moi ??? Dans une bibliothèque quand même axée jeux, impossible d'avoir un déplacement de sprites uniforme et constant ???

    Coyotte, est-ce que tu as aussi des ralentissements légers dans tes programmes ? (je suis le seul ou pas ? vous les voyez ?)

    Edit : bon j'ai voulu tester sous windows pour voir si le problème persistait. J'ai voulu lancer un jeu trouvé sur le site de sdl : airpong. Il a exactement le même "problème" : déplacement pas fluide de la barre. Moi ça me choque vraiment, mais on dirait que ça ne dérange personne.. ???

    Edit2 : comme quasiment tout le monde a linux. Je vous invite à regarder le jeu airpong pour windows ( lien ) qui n'est pas de moi mais qui présente ces problèmes de mouvement non uniforme (prêtez attention aux déplacements de la barre que vous contrôlez, vous verrez bien que le mouvement n'est pas fluide mais qu'il y a des "sauts" par moments). J'ai le même problème et pourtant mon code a l'air bon (voir sources au premier post, c'est presque copié d'un tuto).

    Edit3 : j'ai rajouté le code directement dans le post 1 pour ne pas avoir à télécharger les sources, de sorte à peut-être avoir encore un peu d'aide

  13. #13
    Membre expérimenté
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Points : 1 452
    Points
    1 452
    Par défaut
    Salut,

    fais bien attention de spécifier un intervalle multiple de 10 ms.
    Sur mon ordi, ça améliore les choses, mais ça fait pas disparaître totalement.

    Sinon, si tu va sur http://www.devolution.com/~slouken/p...rom/index.html, tu vois un jeu adapté en SDL par le créateur de la SDL qui n'a pas ces problèmes, peut-être qu'en regardant les sources tu auras une réponse.

  14. #14
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 11
    Points : 1
    Points
    1
    Par défaut
    Effectivement j'ai remarqué qu'en mettant 10ms ça se voyait moins mais ça ne disparaît pas.. Je vais jeter un oeil à ces sources.

    Si quelqu'un a une autre idée je suis preneur..

  15. #15
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 11
    Points : 1
    Points
    1
    Par défaut
    Je me sens très seul.. vous me dites que ces saccades sont "normales" ?

    J'ai trouvé un tuto pas mal ici qui dit :
    "Many people make the mistake of thinking that their animation programs will generate frames at a constant rate and animate by moving objects by a fixed distance per frame. You quickly learn that, no matter what you do, sometimes the time between frames is not constant. In fact, it is surprisingly variable. Even if you tie the frame rate to the display refresh rate, you find that the refresh rate is different for each display your program runs on.
    Basing animation on a constant frame rate is a fairy tale that produces jerky animation."

    Il propose des solutions il me semble. Je regarderai ça plus tard.

  16. #16
    Rédacteur

    Avatar de loka
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2004
    Messages
    2 672
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Service public

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 672
    Points : 5 509
    Points
    5 509

  17. #17
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 11
    Points : 1
    Points
    1
    Par défaut
    Merci.. Tes tutos sont très bien faits mais rien ne résoud le problème.
    Bon ben j'ai essayé pas mal de trucs déjà.. Il n'y a RIEN qui change. La seule chose qui semble avoir une influence sur ces saccades c'est le délai : si on met 10 il y a moins d'accoups que si on met 15.. J'ai retourné le trucs dans tous les sens je crois, impossible d'avoir un programme qui boucle régulièrement ou au moins qui en a l'air. Sérieusement, vous avez pas ce problème ? Ou vous vous en foutez ? Comment faites-vous !

    J'ai vu qu'on pouvait régler le mouvement en pixel par secondes, mais au final ça ne change rien, mais si globalement on aura la vitesse désirée, les saccades elles ne s'en vont pas !

    Suis-je le seul à utiliser réellement SDL ici ??? Ou alors je suis vraiment nul mais dans ce cas peut-être quelqu'un peut peut-être m'envoyer ses sources qui font ce que je n'arrive pas à faire : simplement déplacer un sprite à l'écran de manière fluide !

    Edit : j'ai compilé au passage ton http://loka.developpez.com/tutoriel/..._mouvement.zip
    en mettant 50 de FPS : on voit aussi ces saccades..

  18. #18
    Rédacteur

    Avatar de loka
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2004
    Messages
    2 672
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Service public

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 672
    Points : 5 509
    Points
    5 509
    Par défaut
    Citation Envoyé par cabrif Voir le message
    Edit : j'ai compilé au passage ton http://loka.developpez.com/tutoriel/..._mouvement.zip
    en mettant 50 de FPS : on voit aussi ces saccades..
    Pour celui-ci c'est normal, essayes plutôt celui-ci :
    http://loka.developpez.com/tutoriel/...animation2.rar

    Je vais tester ce soir sinon mais je ne me souviens pas de saccades.

    Edit : Je viens de tester mouvement et animation, j'ai eu de très rares et très légères saccades sur mouvement (je suis monté à plus de 100 fps pour tester, le nombre de fps ne semble pas influer sur la fréquence et l'intensité des saccades).
    Je ne pense pas que le problème des saccades viennent de SDL, j'ai eu l'occasion de l'utiliser pour des projets bien plus gros sans problèmes.

    Mon pc est très loin d'être de dernière génération, de même pour ma carte graphique.

    As-tu vérifier si sur ton pc tu n'avais pas des pick d'utilisation de l'UC (ou une utilisation en 'dent de scie') ? Dans ce cas le problème viendrais de ton pc.

    Si ce n'est pas le cas, essayes de faire la même chose en couplant avec OpenGL et si le problème est toujours présent, alors ça ne vient pas de SDL.

  19. #19
    Membre expérimenté
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Points : 1 452
    Points
    1 452
    Par défaut
    Personnellement, je n'utilise pas pour l'instant la SDL pour un jeu vidéo de ce style.

    Au lieu de faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    while (1)
    {
          if (SDL_GetTicks() - lasttime >= DELAY)
          {
               affiche(ecran);
          }
          while (SDL_PollEvent(&event))
          {
               ....
          }
     
          SDL_Delay(1);
    }
    faire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    while (1)
    {
        affiche(ecran);
        while(SDL_PollEvent(&event))
        { 
              ...
         }
     
         SDL_Delay(30);
    }
    Et augmenter la vitesse de ton pingouin (le faire bouger de 4 pixels à chaque frame). Le fait de faire un SDL_Delay(30) augmente la précision relative du délai, et normalement c'est fluide, mais ça commence à devenir haché si ton objet est une forme simple comme un rectangle et va trop vite.

    Si sur ton ordi ça marche pas, il reste la solution brutale de ne pas mettre de délai, et de calculer les coordonnées en fonction du temps écoulé. (sur un prototype de pong j'avais fait ça )

  20. #20
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 11
    Points : 1
    Points
    1
    Par défaut
    J'ai compilé ton test_animation2 : le problème est bien là, il est juste peu visible parce que tu es à 30 fps qu'il y a l'animation du personnage. Si je met 50 fps, que je stoppe l'animation (j'ai juste mis un delai extremement grand pour tester), en déplaçant le sprite on voit nettement ces saccades.. Recompile le en mettant 50 fps et delai d'animation 1000000, bouge ton sprite et tu verras..

    Sinon coyotte je peux pas me contenter d'un délai de 30... ce sera déjà un peu hâché. Et puis ce sera visible pour mon jeu car le sprite n'est pas un perso animé etc mais une forme très simple (une boule) donc ça se voit vraiment...
    Et puis j'ai essayé sans timer du tout, avec une boucle dans laquelle j'exécute le reste du code qu'une fois sur 1000 (ou un truc du genre), pour voir si ça venait vraiment de SDL_GetTicks() ou SDL_Delay.. mais non le problème persiste. C'est à n'y rien comprendre, c'est comme si je n'avais aucun moyen de contrôler la régularité d'exécution de mon programme... J'ai jamais été confronté à ce problème.. sur console c'est facile c'est pas multi-tâche, si tu lui dis d'avancer de 1 pixel à chaque itération, tu auras un mouvement constant..
    Je commence à penser que ça ne vient pas de SDL mais soit de mon ordi soit de mon OS. Je vais tester sur un de mes autres PC et jessaierai même sur un windows (d'ailleurs j'ai pas ce qu'il faut pour compiler pour windows, alors loka si tu pouvais m'envoyer un animation2 en .exe recompilé avec un fps de 50 ça serait cool).


    Edit : bon j'ai testé sur un autre pc, j'obtiens la même chose du moins sous linux. J'ai pas pu tester sous windows, j'ai rien pour compiler :/
    Au fait comment utilise-t-on opengl avec sdl ? Un lien ?
    Edit2 : j'ai essayé sur d'autres pc encore, c'est exactement le même phénomène. Il faut dire que même s'ils n'ont pas la même config, ils ont tous le même os (même distribution).
    Loka , tu m'assures que sous windows le test_animation2 , en mettant 50 fps et sans l'animation, tu ne vois pas de "sauts" à peu près toutes les secondes ? Est-ce que tu pourrais m'envoyer l'exécutable ? (avec ces réglages..) C'est beaucoup te demander, mais ce serait vraiment sympa. Si on n'a pas ça sous windows, alors ça voudra dire que je peux rien y faire, et je pourrai m'arrêter de chercher...

Discussions similaires

  1. Affichage très saccadé !
    Par jlb59 dans le forum Windows XP
    Réponses: 9
    Dernier message: 09/05/2011, 07h32
  2. déplacement d'un label très saccadé
    Par marco62118 dans le forum VB 6 et antérieur
    Réponses: 20
    Dernier message: 13/01/2008, 00h02
  3. glissement d'objet très saccadé même en mode création
    Par marco62118 dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 10/01/2008, 11h23
  4. base de données très légère
    Par julio02200 dans le forum Excel
    Réponses: 4
    Dernier message: 28/10/2007, 00h39
  5. saccades très bizarres
    Par Myth_Titans dans le forum SDL
    Réponses: 3
    Dernier message: 26/08/2006, 17h19

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