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 :

Afficher une image toutes les X secondes ? [SDL 1.2]


Sujet :

SDL

  1. #1
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2013
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2013
    Messages : 90
    Points : 69
    Points
    69
    Par défaut Afficher une image toutes les X secondes ?
    Salut à tous,

    Voilà je suis en train de gérer l'affichage et le déplacement d'image via les flèches du clavier. Pour celà aucun soucis particulier et j'arrive à faire parfaitement ce que je veux, si j'appuie sur la flèche droite j'ai bien l'image de mon personnage qui regarde vers la droite et se déplace bien.

    Le soucis viens du fait que ledit personnage est sous LSD ou toute autre substance illicite lors de son déplacement tellement il va vite et malgré le fait que je ne déplace l'image que d'un seul pixel à la fois ! xD

    J'ai donc penser à incorporer un timer pour afficher l'image toutes les X secondes ou millisecondes via la librairie time.h, mais je vois pas trop comment je pourrais procéder comme je débute dans tout ça.

    Je viens donc vers vous pour que vous puissiez m'éclairer un petit peu sur le sujet

    Voici actuellement mon code si ça peut vous aider :
    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
    typedef struct Input Input;
     
    void UpdateEvent(Input *in);
     
    struct Input {
        char key[SDLK_LAST];
    };
     
    int main ( int argc, char** argv )
    {
        SDL_Surface *ecran = NULL, *mario = NULL;
        SDL_Rect positionMario;
     
        int continuer = 1;
        Input in;
     
        SDL_Init(SDL_INIT_VIDEO);
     
        ecran = SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE);
        SDL_WM_SetCaption("Essais Mario", NULL);
     
        SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran -> format, 255, 255, 255));
     
        // Chargement de Mario de base
        mario = IMG_Load("images/mario_bas.gif");
     
        // Position de mario
        positionMario.x = (ecran -> w / 2) - (mario -> w / 2);
        positionMario.y = (ecran -> h / 2) - (mario -> h / 2);
     
        // Affichage de mario
        SDL_BlitSurface(mario, NULL, ecran, &positionMario);
        SDL_Flip(ecran);
     
        memset(&in, 0, sizeof(in)); // Toute la structure est à 0
     
        // Boucle principale
        do {
            UpdateEvent(&in);
     
            // On gère les directions
            if (in.key[SDLK_UP]){
                mario = IMG_Load("images/mario_haut.gif");
                positionMario.y -= 1;
            }
     
            if (in.key[SDLK_DOWN]){
                mario = IMG_Load("images/mario_bas.gif");
                positionMario.y += 1;
            }
     
            if (in.key[SDLK_RIGHT]){
                mario = IMG_Load("images/mario_droite.gif");
                positionMario.x += 1;
            }
     
            if (in.key[SDLK_LEFT]){
                mario = IMG_Load("images/mario_gauche.gif");
                positionMario.x -= 1;
            }
     
            // On efface l'écran
            SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran -> format, 255, 255, 255));
     
            // On affiche la nouvelle position
            SDL_BlitSurface(mario, NULL, ecran, &positionMario);
            SDL_Flip(ecran);
     
        } while (!in.key[SDLK_ESCAPE]);
     
        SDL_FreeSurface(mario);
        SDL_Quit();
     
        return EXIT_SUCCESS;
    }
     
    // Fonctions
    void UpdateEvent(Input *in){
        SDL_Event event;
     
        // On traite tout les événements
        while (SDL_PollEvent(&event)){
            switch (event.type){
                case SDL_KEYDOWN :
                    in -> key[event.key.keysym.sym] = 1;
                    break;
                case SDL_KEYUP :
                    in -> key[event.key.keysym.sym] = 0;
                    break;
                default :
                    break;
            }
        }
    }
    Merci d'avance

  2. #2
    Membre régulier
    Profil pro
    Ingénieur
    Inscrit en
    Avril 2013
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur

    Informations forums :
    Inscription : Avril 2013
    Messages : 77
    Points : 107
    Points
    107
    Par défaut
    Si ton personnage se déplace si vite, c'est que l'appui sur une touche implique plusieurs déplacements.

    Je ne connais pas trop la SDL. En parcourant quelques tutoriaux, j'ai remarqué souvent cette syntaxe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    while (continuer) /* TANT QUE la variable ne vaut pas 0 */
        {
            SDL_WaitEvent(&event); /* On attend un événement qu'on récupère dans event */
            switch(event.type) /* On teste le type d'événement */
            {
                case SDL_QUIT: /* Si c'est un événement QUITTER */
                    continuer = 0; /* On met le booléen à 0, donc la boucle va s'arrêter */
                    break;
            }
        }
    Cette syntaxe utilise la fonction SDL_WaitEvent() qui attend un nouvel évènement.
    Donc je te propose de remplacer UpdateEvent(Input *in) (qui fait quoi??) par SDL_WaitEvent()

  3. #3
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2013
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2013
    Messages : 90
    Points : 69
    Points
    69
    Par défaut
    J'avais fais de cette manière avant celle que j'ai mise ici, l'embêtant avec celle là c'est qu'il faut mitrailler à répétition la touche souhaitée pour voir le personnage avancé "en continu" et le fait de garder la touche enfoncée n'a aucun effet :s

  4. #4
    Membre régulier
    Profil pro
    Ingénieur
    Inscrit en
    Avril 2013
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur

    Informations forums :
    Inscription : Avril 2013
    Messages : 77
    Points : 107
    Points
    107
    Par défaut
    C'est normal, il déplace d'un pixel à chaque appui.

    Cette fonction pourrait t'intéresser : SDL_EnableKeyRepeat()

  5. #5
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2013
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2013
    Messages : 90
    Points : 69
    Points
    69
    Par défaut
    Déjà fais et refait ces solutions mais elle ne me plaisent pas ^^

    Mais même en changeant le taille du déplacement tout ce que je fais c'est lui mettre une plus grande distance de marche à chaque fois, ce n'est pas ce que je veux. Je veux un déplacement fluide quand on garde une touche appuyée comme j'ai pour l'instant, je cherche juste à réduire cette vitesse beaucoup trop rapide, d'où mon idée d'un timer

  6. #6
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Bonjour,
    Fais une recherche sur le thème du keyboard state.

    Le rythme des keypress n'est pas à écouter, il faut seulement s'intéresser à savoir si la dernière action sur la touche est un keypress ou un keydown.
    Garde des booléens pour savoir si chaque flèche est enfoncée ou non.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  7. #7
    Membre averti
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Juin 2012
    Messages
    257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2012
    Messages : 257
    Points : 321
    Points
    321
    Par défaut
    Bonjour Odawin,

    Tu veux que ton personnage se déplace tant que la touche est maintenue enfoncée ou à chaque fois que tu fais un appui (transition) ?

    Dans le premier cas il faut tester "in -> key[event.key.keysym.sym]" pour bouger positionMario.

    Dans le deuxième cas, ta structure n'est pas optimale : il faut agir en fonction de l’événement (et non d'un état) et donc à l'intérieur du case SDL_KEYDOWN : (ou KEYUP).

    Apparemment "tu tournes à fond" dans la boucle principale, tu consommes tout le CPU et c'est pour cela que l'incrément des positions se fait très vite (avec le déplacement du personnage)

    J'ai donc penser à incorporer un timer pour afficher l'image toutes les X secondes ou millisecondes via la librairie time.h, mais je vois pas trop comment je pourrais procéder comme je débute dans tout ça.
    => Regarde la gestion du frame-rate.

    Un autre conseil : charge toutes les images en ligne 25 et dans les if tu choisis juste celle que tu veux blitter.

  8. #8
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2013
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2013
    Messages : 90
    Points : 69
    Points
    69
    Par défaut
    Bonjour,

    Effectivement je souhaite que Mario se déplace tant que la touche est maintenue, je trouve ça plus logique et moins contraignant

    J'avais essayer avec un WaitEvent au lieu d'un PollEvent mais là Mario ne bougeait pas du tout ! xD

    En farfouillant un peu j'ai trouver ce tuto concernant les timer avec SDL, en reprenant quelques trucs de ça et en adaptant je pense que ça devrait fonctionner niveau framerate ?

    Merci pour le conseil de chargement, je vais modifier ça en même temps

  9. #9
    Expert éminent sénior
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cyber-paléontologue

    Informations forums :
    Inscription : Mai 2010
    Messages : 3 214
    Points : 10 140
    Points
    10 140
    Par défaut
    Normal ,que avec wait le perso bouge plus , vu que ça attend un éventement pour continuer dans la boucle.
    Les timers en SDL résoudra plus ou moins ton problème , c'est juste les fonction clock() et sleep() mais en plus portable.

    En général il y a 2 grosse solution pour faire un framerate avec ou sans sleep() (mais avec sleep c'est plus conseillé).

    En gros si tu fais un SDL_Delay(33); t'aura plus ou moins 30 fps , pour avoir 30 fps il faut calculer le temps que tu met pour faire des autres calculs avec SDL_getticks.

  10. #10
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2013
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2013
    Messages : 90
    Points : 69
    Points
    69
    Par défaut
    Ok merci beaucoup pour les infos, je vais tester tout ça et ensuite je viendrai donner des nouvelles

  11. #11
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2013
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2013
    Messages : 90
    Points : 69
    Points
    69
    Par défaut
    Bonjour, bonjour,

    J'ai finalement eu le temps de me repencher un petit peu sur mon code pour essayer de gérer le framerate.

    J'ai trouver une solution pour afficher l'image moins vite et maintenant Mario se déplace enfin à une vitesse normale !

    Mais je ne suis pas sûr que ma méthode soit totalement efficace et parfaitement optimisée telle que je l'ai faite, donc je me permet de remettre mon code ici

    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
    SDL_Surface *ecran = NULL, *mario = NULL, *marioBas = NULL, *marioHaut = NULL, *marioGauche = NULL, *marioDroite = NULL;
        SDL_Rect positionMario;
     
        int continuer = 1, render = 0, FPS = 30;
        Input in;
     
        SDL_Init(SDL_INIT_VIDEO);
     
        ecran = SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE);
        SDL_WM_SetCaption("Essais Mario", NULL);
     
        SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran -> format, 255, 255, 255));
     
        // Chargement de Mario
        mario = IMG_Load("images/mario_bas.gif");
        marioBas = IMG_Load("images/mario_bas.gif");
        marioHaut = IMG_Load("images/mario_haut.gif");
        marioGauche = IMG_Load("images/mario_gauche.gif");
        marioDroite = IMG_Load("images/mario_droite.gif");
     
        // Position de mario
        positionMario.x = (ecran -> w / 2) - (mario -> w / 2);
        positionMario.y = (ecran -> h / 2) - (mario -> h / 2);
     
        memset(&in, 0, sizeof(in)); // Toute la structure est à 0
     
        // Boucle principale
        do {
            UpdateEvent(&in);
     
            // On gère les directions
            if (in.key[SDLK_UP]){
                mario = marioHaut;
                positionMario.y -= 5;
            }
     
            if (in.key[SDLK_DOWN]){
                mario = marioBas;
                positionMario.y += 5;
            }
     
            if (in.key[SDLK_RIGHT]){
                mario = marioDroite;
                positionMario.x += 5;
            }
     
            if (in.key[SDLK_LEFT]){
                mario = marioGauche;
                positionMario.x -= 5;
            }
     
            // On efface l'écran
            SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran -> format, 255, 255, 255));
     
            render = SDL_GetTicks();
     
            if (render > 1000 / FPS){
                SDL_Delay(1000 / FPS);
            }
     
            // On affiche la nouvelle position
            SDL_BlitSurface(mario, NULL, ecran, &positionMario);
     
            SDL_Flip(ecran);
     
     
        } while (!in.key[SDLK_ESCAPE]);
     
        SDL_FreeSurface(mario);
        SDL_Quit();
     
        return EXIT_SUCCESS;

  12. #12
    Expert éminent sénior
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cyber-paléontologue

    Informations forums :
    Inscription : Mai 2010
    Messages : 3 214
    Points : 10 140
    Points
    10 140
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    render = SDL_GetTicks();
     
            if (render > 1000 / FPS){
                SDL_Delay(1000 / FPS);
            }
    Ce code sert pas a grand chose , (on plus de pas avoir un fps exacte).
    Tu met render > 1000 / FPS , mais render sera toujours plus grand que 1000 / FPS, au bout d'une seconde SDL_GetTicks(); fait 1000 x)

  13. #13
    Membre averti
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Juin 2012
    Messages
    257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2012
    Messages : 257
    Points : 321
    Points
    321
    Par défaut
    Oui,

    Il faut 2 mesures SDL_GetTicks() et faire une différence pour mesurer une durée.

    J'ai une suggestion :
    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
    int FPS = 30;
        int t_boucle = 1000/FPS;    // la durée de la boucle en ms
        int t_deb, t_fin;
     
    // Boucle principale
        do {
            t_deb = SDL_GetTicks();  // instant de début de boucle
            UpdateEvent(&in);
     
            // On gère les directions
            if (in.key[SDLK_UP]){
                mario = marioHaut;
                positionMario.y -= 5;
            }
     
            if (in.key[SDLK_DOWN]){
                mario = marioBas;
                positionMario.y += 5;
            }
     
            if (in.key[SDLK_RIGHT]){
                mario = marioDroite;
                positionMario.x += 5;
            }
     
            if (in.key[SDLK_LEFT]){
                mario = marioGauche;
                positionMario.x -= 5;
            }
     
            // On efface l'écran
            SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran -> format, 255, 255, 255));
     
     
            // On affiche la nouvelle position
            SDL_BlitSurface(mario, NULL, ecran, &positionMario);
     
            SDL_Flip(ecran);
            t_fin = SDL_GetTicks();  // instant de fin de boucle
            // On rajoute un délai pour obtenir t_boucle
            if (t_fin - t_deb < t_boucle) SDL_Delay(t_boucle - (t_fin - t_deb));
     
        } while (!in.key[SDLK_ESCAPE]);
    et une question :

    Pourquoi ne pas mettre les différents if dans la fonction UpdateEvent(&in); ?

    Car tant que tu gères des états (in.key[ ] ) pas de soucis, mais tu aurais un ennui pour gérer des évènements : voir la doc SDL ou le tuto du site pour tester le retour des fonctions WaitEvent et PollEvent.

  14. #14
    Expert éminent sénior
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cyber-paléontologue

    Informations forums :
    Inscription : Mai 2010
    Messages : 3 214
    Points : 10 140
    Points
    10 140
    Par défaut
    Citation Envoyé par nanosoft Voir le message

    et une question :

    Pourquoi ne pas mettre les différents if dans la fonction UpdateEvent(&in); ?

    Car tant que tu gères des états (in.key[ ] ) pas de soucis, mais tu aurais un ennui pour gérer des évènements : voir la doc SDL ou le tuto du site pour tester le retour des fonctions WaitEvent et PollEvent.
    Non les évènements sont bien gérer , il les met dans une structure (in) et dans un tableau (key).

    Je fais exactement la même chose et cela marche très bien.

  15. #15
    Membre averti
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Juin 2012
    Messages
    257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2012
    Messages : 257
    Points : 321
    Points
    321
    Par défaut
    Bonsoir,

    C'était une question :
    Pourquoi ...


    Je fais exactement la même chose et cela marche très bien.
    Je suis d'accord, j'ai dit pas de soucis.

    Je voulais mettre en garde Odawin qu'il ne fallait pas tester un évènement (par exemple un SDL_KEYDOWN) en dehors du retour des fonctions Wait ou Poll.

  16. #16
    Expert éminent sénior
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cyber-paléontologue

    Informations forums :
    Inscription : Mai 2010
    Messages : 3 214
    Points : 10 140
    Points
    10 140
    Par défaut
    Citation Envoyé par nanosoft Voir le message
    Bonsoir,

    C'était une question :



    Je suis d'accord, j'ai dit pas de soucis.

    Je voulais mettre en garde Odawin qu'il ne fallait pas tester un évènement (par exemple un SDL_KEYDOWN) en dehors du retour des fonctions Wait ou Poll.
    oh ok désolé x)

    Pour in.key[SDLK_DOWN] , je pense pas que ça soit des évènements SDL, mais plus comme je l'ai dit un tableau de booléen , donc il peut faire le test ailleurs que en dehors de Wait ou Poll (dans une fonction gameplay plus tard par exemple).

    Sinon pour répondre pourquoi parce que c'est différents if sont pas associé a Wait et Poll, Updateevent doit remplir la structure in , puis en retour les utiliser , c'est une bonne pratique ça permet d'avoir une boucle du jeu comme cela plus tard :

    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
     
    do {
            UpdateEvent(&in);
     
            gameplay(in,&joueur);
     
            SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran -> format, 255, 255, 255));
     
     
            SDL_BlitSurface(joueur.image, NULL, ecran, &joueur.position);
     
            SDL_Flip(ecran);
     
            fps();
     
     
        } while (!in.key[SDLK_ESCAPE]);
    Voila mais bon en général on déplace rarement les positions directement , on met des vecteur vitesse (qu'on fera des test et modification dessus pour les collisions).


    Pour les FPS c'est exact mais je aurait présentait comme cela.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
            t_fin = SDL_GetTicks();  // instant de fin de boucle
            if (t_fin - t_deb < t_boucle) SDL_Delay(t_boucle - (t_fin - t_deb));
            t_deb = SDL_GetTicks();  // instant de début de boucle
    Pour la mettre dans une fonction

  17. #17
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2013
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2013
    Messages : 90
    Points : 69
    Points
    69
    Par défaut
    Merci pour l'aide précieuse ! Ce forum est vraiment super

    J'avoue qu'en revoyant mon code hier je me demande un peu ce que j'ai foutu... xD Je devais avoir la tête dans le pâté ou je sais pas trop quoi

    J'ai finalement opter pour cette méthode :
    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
    renderDebut = SDL_GetTicks();
     
            UpdateEvent(&in);
     
            // On gère les directions
            if (in.key[SDLK_UP]){
                mario = marioHaut;
                positionMario.y -= 5;
            }
     
            if (in.key[SDLK_DOWN]){
                mario = marioBas;
                positionMario.y += 5;
            }
     
            if (in.key[SDLK_RIGHT]){
                mario = marioDroite;
                positionMario.x += 5;
            }
     
            if (in.key[SDLK_LEFT]){
                mario = marioGauche;
                positionMario.x -= 5;
            }
     
            // On efface l'écran
            SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran -> format, 255, 255, 255));
     
            // On affiche la nouvelle position
            SDL_BlitSurface(mario, NULL, ecran, &positionMario);
     
            SDL_Flip(ecran);
     
            renderFin = SDL_GetTicks();
     
            if (renderFin - renderDebut < renderBoucle){
                SDL_Delay(renderBoucle - (renderFin - renderDebut));
            }
     
     
        } while (!in.key[SDLK_ESCAPE]);
     
        SDL_FreeSurface(mario);
        SDL_Quit();
     
        return EXIT_SUCCESS;
    J'admet aussi volontiers que mon code est assez cracra pour l'instant comme je ne fais que des tests, mais plus tard je sortirai la gestion des touches de la pour le mettre dans une fonction à part, histoire d'avoir le minimum possible dans la boucle principale, là c'est "fait à l'arrache" comme le but principal était plus de gérer un déplacement correct

    Mais effectivement en ce qui concerne les événements je remplis un tableau de booléens suivant les touches enfoncées du clavier. Ainsi on n'est pas obligé de matraquer une touche pour avoir un mouvement "fluide" à l'écran et je peux aussi gérer plusieurs touches enfoncées en même temps

    Ma fonction updateEvent ressemble à ça :
    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
    void UpdateEvent(Input *in){
        SDL_Event event;
     
        // On traite tout les événements
        while (SDL_PollEvent(&event)){
            switch (event.type){
                case SDL_KEYDOWN :
                    in -> key[event.key.keysym.sym] = 1;
                    break;
                case SDL_KEYUP :
                    in -> key[event.key.keysym.sym] = 0;
                    break;
                default :
                    break;
            }
        }
    }

  18. #18
    Membre averti
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Juin 2012
    Messages
    257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2012
    Messages : 257
    Points : 321
    Points
    321
    Par défaut
    Pour les FPS c'est exact mais je aurait présentait comme cela.
    Code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     t_fin = SDL_GetTicks();  // instant de fin de boucle
    if (t_fin - t_deb < t_boucle) SDL_Delay(t_boucle - (t_fin - t_deb));
    t_deb = SDL_GetTicks();  // instant de début de boucle
    Oui, c'est une bonne idée pour regrouper tout dans une fonction fps() placée à la fin.
    Prendre soin alors d'initialiser t_deb (négligé dans ma suggestion).
    (Pour la première boucle ! )

  19. #19
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Si c'est du C++, la classique capsule raii peut être sympa
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class fpsguard{
    private:
        int start;
        int min;
    public:
        explicit fpsguard(int min) : start(SDL_GetTicks()), min(min) {}
        ~fpsguard() {
            int delay = SDL_GetTicks() - start;
            if (delay < min) SDL_Delay(min - delay);
        }
    };
    du coup, il suffit d'avoir comme boucle principale
    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
    do {
            fpsguard guard(renderBoucle);
     
            UpdateEvent(&in);
     
            // n'importe quoi ...
     
            // On efface l'écran
            SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran -> format, 255, 255, 255));
     
            // On affiche la nouvelle position
            SDL_BlitSurface(mario, NULL, ecran, &positionMario);
     
            SDL_Flip(ecran);
         } while (!in.key[SDLK_ESCAPE]);
    La magie, c'est la destruction du fpsguard à la fin du while.
    Par contre, il faut faire du C++
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  20. #20
    Expert éminent sénior
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cyber-paléontologue

    Informations forums :
    Inscription : Mai 2010
    Messages : 3 214
    Points : 10 140
    Points
    10 140
    Par défaut
    Pas besoin initialiser , il faut juste faire quelque contrôle avant.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    t_fin = SDL_GetTicks();  // instant de fin de boucle
    s = t_fin - t_deb;
    if(s < 0) s = 0;
    if (s < t_boucle) SDL_Delay(t_boucle - s);
    t_deb = SDL_GetTicks();  // instant de début de boucle

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Comment afficher une nouvelle image toutes les 2 secondes ?
    Par islogged dans le forum Général JavaScript
    Réponses: 12
    Dernier message: 02/01/2013, 16h06
  2. Afficher une image toutes les 5 secondes
    Par Bois990 dans le forum Général JavaScript
    Réponses: 14
    Dernier message: 30/03/2012, 08h57
  3. Changer une image toutes les x secondes
    Par ApocKalipsS dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 11/02/2010, 17h02
  4. Afficher une image toutes les 20 secondes
    Par sab_etudianteBTS dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 16/02/2008, 18h27
  5. modifier une image toutes les X secondes
    Par didine44 dans le forum GTK+ avec C & C++
    Réponses: 4
    Dernier message: 01/02/2007, 17h09

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