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 :

Problème de déplacement avec le Delta Time


Sujet :

SDL

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2022
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2022
    Messages : 21
    Points : 22
    Points
    22
    Par défaut Problème de déplacement avec le Delta Time
    Bonjour/Bonsoir tout le monde, j'ai un petit problème avec les déplacements et le delta time, c'est très étrange et je n'arrive pas à me l'expliquer alors peut être que je m'y prends mal...

    Voici comment je le calcul au début de la boucle principale :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    delta_time = (SDL_GetTicks() - ticks_count) / 1000.0f;
    ticks_count = SDL_GetTicks();
    Le calcul est bon selon moi et je m'en sert même pour un timer qui fonctionne nickel.
    Et voici à peu près à quoi ressemble ma fonction de déplacement :
    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
     
        if (keyState[SDL_SCANCODE_UP])
        {
            if (!keyState[SDL_SCANCODE_LEFT] || !keyState[SDL_SCANCODE_RIGHT])
                 rect.y -= 200 * delta_time;
            else rect.y -= 100 * delta_time;
        }
        else if (keyState[SDL_SCANCODE_DOWN])
        {
            if (!keyState[SDL_SCANCODE_LEFT] || !keyState[SDL_SCANCODE_RIGHT])
                 rect.y += 200 * delta_time;
            else rect.y += 100 * delta_time;
        }
     
        if (keyState[SDL_SCANCODE_LEFT])
        {
            if (!keyState[SDL_SCANCODE_UP] || !keyState[SDL_SCANCODE_DOWN])
                 rect.x -= 200 * delta_time;
            else rect.x -= 100 * delta_time;
        }
        else if (keyState[SDL_SCANCODE_RIGHT])
        {
            if (!keyState[SDL_SCANCODE_UP] || !keyState[SDL_SCANCODE_DOWN])
                 rect.x += 200 * delta_time;
            else rect.x += 100 * delta_time;
        }
     
    }
    Mais voilà, j'ai remarqué que la vers la droite et vers le bas vont moins vite que vers le haut et vers la gauche (donc les += vont moins vite que les -=).
    Alors j'ai fais pas mal de tests, dont par exemple mettre le "200 * dt" dans une varaible et faire le boulot ensuite mais c'etait exactement pareil.

    Puis j'ai aussi remarqué qu'en reduisant la vitesse (par exemple de 200 à 50) ça se déplaçait aux "-=" mais plus dutout aux "+=" et là je ne comprends plus dutout pourquoi.
    J'ai eu pas mal d'hypothèse mais qui se sont révélées fausses ou juste deviennent absurdes, c'est pour cela que je m'en retourne à vous, voilà tout...

    Je vous remercie d'avance si vous avez des avis ou solutions !

    EDIT: Petit exemple en C que je viens de faire pour que vous puissiez essayé et c'est bien flagrant, en tout cas chez moi... (encore plus que mon jeu en C++ alors que je n'ai pas changer les valeurs, bizarre...)

    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
     
    #include <stdlib.h>
    #include <stdio.h>
    #include <stdint.h>
    #include <SDL2/SDL.h>
     
    #define WIN_W 640
    #define WIN_H 480
     
    int main (int argc, char** argv)
    {
        (void) argc; (void) argv;
     
        /* Initialisation de SDL */
     
        if (SDL_Init (SDL_INIT_VIDEO) < 0) { fprintf(stderr, "ERROR: %s", SDL_GetError()); return 1; };
     
        SDL_Window* win = SDL_CreateWindow ("Test mouvement avec delta time", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WIN_W, WIN_H, 0);
        if (!win) { fprintf(stderr, "ERROR: %s", SDL_GetError()); return 1; }
     
        SDL_Renderer* ren = SDL_CreateRenderer (win, -1, SDL_RENDERER_ACCELERATED);
     
        SDL_Event event;
     
        /* Valeurs du programme */
     
        SDL_Rect rect = {(WIN_W-64)/2, (WIN_H-64)/2, 64, 64};
     
        uint32_t ticks_count = SDL_GetTicks();
        float delta_time;
     
        const uint8_t* keyState = SDL_GetKeyboardState(NULL);
        SDL_bool running = SDL_TRUE;
     
        /* Execution du programme */
     
        while (running)
        {
     
            /* Calcul du delta time */
     
            delta_time = (SDL_GetTicks() - ticks_count) / 1000.0f;
            ticks_count = SDL_GetTicks();
     
            /* Evenements SDL */
     
            while (SDL_PollEvent(&event))
                running = event.type != SDL_QUIT;
     
            SDL_PumpEvents();
     
            /* Déplacement du rectangle */
     
            if (keyState[SDL_SCANCODE_UP])
            {
                if (!keyState[SDL_SCANCODE_LEFT] || !keyState[SDL_SCANCODE_RIGHT])
                     rect.y -= 200 * delta_time;
                else rect.y -= 100 * delta_time;
            }
            else if (keyState[SDL_SCANCODE_DOWN])
            {
                if (!keyState[SDL_SCANCODE_LEFT] || !keyState[SDL_SCANCODE_RIGHT])
                     rect.y += 200 * delta_time;
                else rect.y += 100 * delta_time;
            }
     
            if (keyState[SDL_SCANCODE_LEFT])
            {
                if (!keyState[SDL_SCANCODE_UP] || !keyState[SDL_SCANCODE_DOWN])
                     rect.x -= 200 * delta_time;
                else rect.x -= 100 * delta_time;
            }
            else if (keyState[SDL_SCANCODE_RIGHT])
            {
                if (!keyState[SDL_SCANCODE_UP] || !keyState[SDL_SCANCODE_DOWN])
                     rect.x += 200 * delta_time;
                else rect.x += 100 * delta_time;
            }
     
            /* Rendu du programme */
     
            SDL_SetRenderDrawColor(ren, 0, 0, 0, 255);
            SDL_RenderClear(ren);
     
            SDL_SetRenderDrawColor(ren, 255, 255, 255, 255);
            SDL_RenderFillRect(ren, &rect);
     
            SDL_RenderPresent(ren);
     
        }
     
        /* Closing the program */
     
        SDL_DestroyRenderer(ren);
        SDL_DestroyWindow(win);
        SDL_Quit();
     
        return 0;
    }

  2. #2
    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
    Je vois rien d'anormal , mais le manque de delay me choque ,vu que bon tu vas prendre 100% de CPU pour rien ^^'

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2022
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2022
    Messages : 21
    Points : 22
    Points
    22
    Par défaut
    Citation Envoyé par Kannagi Voir le message
    Je vois rien d'anormal , mais le manque de delay me choque ,vu que bon tu vas prendre 100% de CPU pour rien ^^'
    Alors là, est-ce que ça pourrait venir du fait que je suis sur un petit netbook ? Mais si c'est ça je ne vois pas pourquoi ça ne le fait que pour "droite et bas" c'est vachement bizarre...

    Je n'ai pas d'autre pc pour tester où je suis pour l'instant, je pourrais dire que dans quelques jours...

    Et oui j'ai écrit l'exemple rapidement, il était tard je ne me suis pas pris la tête dutout, le problème est le même dans mon projet alors qui s'occupe de ça de toute façon... Merci quand même de la réponse !

  4. #4
    Expert éminent sénior
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 361
    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 361
    Points : 20 381
    Points
    20 381
    Par défaut
    salut le truc qui me chagrine c'est que vous testez SDL_SCANCODE_UP et SDL_SCANCODE_DOWN en même temps le premier événement annule l'autre donc forcément il y a des désynchronisations

    Ensuite pour des questions de lisibilité ça serait mieux de faire une fonction OnKeyPressed() et utiliser un switch (touche_enfoncee) plutôt qu'une palanquée de if imbriqués les uns dans les autres

    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
     
    void OnKeyPressedDown()
    {
    const uint8_t* keyState = SDL_GetKeyboardState(NULL);
     
    	switch(keyState)
    	{
     
    		case SDL_SCANCODE_LEFT:
    		 rect.x -= 200 * delta_time;
    		break;
     
    		case SDL_SCANCODE_RIGHT:
    		 rect.x += 200 * delta_time;
    		break;
     
     
    	}
    }
    MODIF PERSO de 20:15

    ne pas tenir compte de ce code
    car on ne peut pas utiliser de switch

  5. #5
    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 Bigfoot71 Voir le message
    Mais si c'est ça je ne vois pas pourquoi ça ne le fait que pour "droite et bas" c'est vachement bizarre...
    Parce que tu fait une condition pour peut être ?
    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
     
    if (keyState[SDL_SCANCODE_UP])
            {
                if (!keyState[SDL_SCANCODE_LEFT] || !keyState[SDL_SCANCODE_RIGHT])
                     rect.y -= 200 * delta_time;
                else rect.y -= 100 * delta_time;
            }
            else if (keyState[SDL_SCANCODE_DOWN])
            {
                if (!keyState[SDL_SCANCODE_LEFT] || !keyState[SDL_SCANCODE_RIGHT])
                     rect.y += 200 * delta_time;
                else rect.y += 100 * delta_time;
            }
     
            if (keyState[SDL_SCANCODE_LEFT])
            {
                if (!keyState[SDL_SCANCODE_UP] || !keyState[SDL_SCANCODE_DOWN])
                     rect.x -= 200 * delta_time;
                else rect.x -= 100 * delta_time;
            }
            else if (keyState[SDL_SCANCODE_RIGHT])
            {
                if (!keyState[SDL_SCANCODE_UP] || !keyState[SDL_SCANCODE_DOWN])
                     rect.x += 200 * delta_time;
                else rect.x += 100 * delta_time;
            }
    Du coup la vitesse change selon quel direction on appuie.

    De plus les conditions me semble assez fausse (comem dit c'est mieux de faire un switch ).

  6. #6
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2022
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2022
    Messages : 21
    Points : 22
    Points
    22
    Par défaut
    Cela marchait parfaitement sans le delta time donc je ne vois pas où mes conditions ne seraient pas correct, mais peut être.
    Et comme j'avais besoin de 'SDL_GetKeyboardState()' pour mon programme (pour la "simplicté", peut être qu'il existe encore plus simple ?) c'est pour ça que je me suis retrouver "obligé" de faire pleins de conditions...

    Je ne voyais pas vraiment comment utilisé un switch avec 'SDL_GetkeyboardState()' alors j'ai fait ceci, avec d'autres ajouts/modifications, je tatonne et c'est toujours pareil:

    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
     
    #include <stdlib.h>
    #include <stdio.h>
    #include <stdint.h>
    #include <SDL2/SDL.h>
     
    #define WIN_W 640
    #define WIN_H 480
     
    int onKeyPressed(const uint8_t* keyState)
    {
        if (keyState[SDL_SCANCODE_UP])
            return 1;
     
        else if (keyState[SDL_SCANCODE_DOWN])
            return 2;
     
        else if (keyState[SDL_SCANCODE_LEFT])
            return 3;
     
        else if (keyState[SDL_SCANCODE_RIGHT])
            return 4;
     
        return 0;
    }
     
    int main (int argc, char** argv)
    {
        (void) argc; (void) argv;
     
        /* Initialisation de SDL */
     
        if (SDL_Init (SDL_INIT_VIDEO) < 0) { fprintf(stderr, "ERROR: %s", SDL_GetError()); return 1; };
     
        SDL_Window* win = SDL_CreateWindow ("Test mouvement avec delta time", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WIN_W, WIN_H, 0);
        if (!win) { fprintf(stderr, "ERROR: %s", SDL_GetError()); return 1; }
     
        SDL_Renderer* ren = SDL_CreateRenderer (win, -1, SDL_RENDERER_ACCELERATED);
     
        SDL_Event event;
     
        /* Valeurs du programme */
     
        SDL_Rect rect = {(WIN_W-64)/2, (WIN_H-64)/2, 64, 64};
     
        uint32_t actual_frame = SDL_GetTicks();
        uint32_t last_frame = 0;
        int      delta_time = 0;
        float    dt_move   = 0.f;
     
        const uint8_t* keyState = SDL_GetKeyboardState(NULL);
        SDL_bool running = SDL_TRUE;
     
        /* Execution du programme */
     
        while (running)
        {
            /* Calcul du delta time */
     
            last_frame = actual_frame;
            actual_frame = SDL_GetTicks();
            delta_time = actual_frame - last_frame;
            dt_move = delta_time / 1000.f;
     
            printf("DELTA TIME (ms): %d\n", delta_time); // Affichage du delta time
     
            /* Evenements SDL */
     
            while (SDL_PollEvent(&event))
                running = event.type != SDL_QUIT;
     
            SDL_PumpEvents();
     
            /* Déplacement du rectangle */
     
            switch (onKeyPressed(keyState))
            {
                case 1:
                    rect.y -= 200 * dt_move; break;
     
                case 2:
                    rect.y += 200 * dt_move; break;
     
                case 3:
                    rect.x -= 200 * dt_move; break;
     
                case 4:
                    rect.x += 200 * dt_move; break;
     
                default: break;
            }
     
            /* Rendu du programme */
     
            SDL_SetRenderDrawColor(ren, 0, 0, 0, 255);
            SDL_RenderClear(ren);
     
            SDL_SetRenderDrawColor(ren, 255, 255, 255, 255);
            SDL_RenderFillRect(ren, &rect);
     
            SDL_RenderPresent(ren);
     
        }
     
        /* Closing the program */
     
        SDL_DestroyRenderer(ren);
        SDL_DestroyWindow(win);
        SDL_Quit();
     
        return 0;
    }
    Et chose que je comprends encore moins, j'ai refait le code depuis des exemples sur internet et quand je fais comme le code ci-dessous le delta time passe carrément de 0 à ~80 en une itteration et du coup le programme se bloque car ça fait un 'delay' avec une valeur negative...

    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
     
    #include <stdlib.h>
    #include <stdio.h>
    #include <stdint.h>
    #include <SDL2/SDL.h>
     
    #define WIN_W 640
    #define WIN_H 480
     
    int onKeyPressed(const uint8_t* keyState)
    {
        if (keyState[SDL_SCANCODE_UP])
            return 1;
     
        else if (keyState[SDL_SCANCODE_DOWN])
            return 2;
     
        else if (keyState[SDL_SCANCODE_LEFT])
            return 3;
     
        else if (keyState[SDL_SCANCODE_RIGHT])
            return 4;
     
        return 0;
    }
     
    int main (int argc, char** argv)
    {
        (void) argc; (void) argv;
     
        /* Initialisation de SDL */
     
        if (SDL_Init (SDL_INIT_VIDEO) < 0) { fprintf(stderr, "ERROR: %s", SDL_GetError()); return 1; };
     
        SDL_Window* win = SDL_CreateWindow ("Test mouvement avec delta time", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WIN_W, WIN_H, 0);
        if (!win) { fprintf(stderr, "ERROR: %s", SDL_GetError()); return 1; }
     
        SDL_Renderer* ren = SDL_CreateRenderer (win, -1, SDL_RENDERER_ACCELERATED);
     
        SDL_Event event;
     
        /* Valeurs du programme */
     
        SDL_Rect rect = {(WIN_W-64)/2, (WIN_H-64)/2, 64, 64};
     
        uint32_t actual_frame = SDL_GetTicks();
        uint32_t last_frame = 0;
        int      delta_time = 0;
        float    dt_move   = 0.f;
     
        const uint8_t* keyState = SDL_GetKeyboardState(NULL);
        SDL_bool running = SDL_TRUE;
     
        /* Execution du programme */
     
        while (running)
        {
            /* Calcul du delta time */
     
            last_frame = actual_frame;
            actual_frame = SDL_GetTicks();
            delta_time = actual_frame - last_frame;
            dt_move = delta_time / 1000.f;
     
            printf("DELTA TIME (ms): %d\n", delta_time); // Affichage du delta time
     
            /* Evenements SDL */
     
            while (SDL_PollEvent(&event))
                running = event.type != SDL_QUIT;
     
            if (1000/60 > delta_time)
            {
                SDL_PumpEvents();
     
                /* Déplacement du rectangle */
     
                switch (onKeyPressed(keyState))
                {
                    case 1:
                        rect.y -= 200 * dt_move; break;
     
                    case 2:
                        rect.y += 200 * dt_move; break;
     
                    case 3:
                        rect.x -= 200 * dt_move; break;
     
                    case 4:
                        rect.x += 200 * dt_move; break;
     
                    default: break;
                }
     
                /* Rendu du programme */
     
                SDL_SetRenderDrawColor(ren, 0, 0, 0, 255);
                SDL_RenderClear(ren);
     
                SDL_SetRenderDrawColor(ren, 255, 255, 255, 255);
                SDL_RenderFillRect(ren, &rect);
     
                SDL_RenderPresent(ren);
            }
            else
            {
                SDL_Delay((1000/60) - delta_time);
            }
     
     
        }
     
        /* Closing the program */
     
        SDL_DestroyRenderer(ren);
        SDL_DestroyWindow(win);
        SDL_Quit();
     
        return 0;
    }
    Alors que j'ai recuperer du code depuis une reponse du forum du site "libsdl" ... Je crois ne plus rien comprendre au principe ça me perd de tourner en rond...

    Au passage, étant donner que j'affiche du texte dans la console l'execution se fait plus lente et le "bas/droite" qui deconne va legerement plus (surement car le delta time est plus grand)
    Mais encore une fois pourquoi uniquement pour "bas/droite" alors que "haut/gauche" est normal ???

  7. #7
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2022
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2022
    Messages : 21
    Points : 22
    Points
    22
    Par défaut
    Citation Envoyé par Mat.M Voir le message
    salut le truc qui me chagrine c'est que vous testez SDL_SCANCODE_UP et SDL_SCANCODE_DOWN en même temps le premier événement annule l'autre donc forcément il y a des désynchronisations

    Ensuite pour des questions de lisibilité ça serait mieux de faire une fonction OnKeyPressed() et utiliser un switch (touche_enfoncee) plutôt qu'une palanquée de if imbriqués les uns dans les autres

    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
     
    void OnKeyPressedDown()
    {
    const uint8_t* keyState = SDL_GetKeyboardState(NULL);
     
    	switch(keyState)
    	{
     
    		case SDL_SCANCODE_LEFT:
    		 rect.x -= 200 * delta_time;
    		break;
     
    		case SDL_SCANCODE_RIGHT:
    		 rect.x += 200 * delta_time;
    		break;
     
     
    	}
    }
    Je n'avais pas vu la modification, mais lorsque je fais ça j'obtiens:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    main.c:57:17: error: switch quantity not an integer
       57 |         switch (keyState)
    Et c'était voulu que si l'on appui sur "haut" ça ne prenne pas en compte "bas"

    Le code avec votre fonction si jamais ça marche pour vous... Puis je crains que même si ça marche mon problème restera le même...
    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
    #include <stdlib.h>
    #include <stdio.h>
    #include <stdint.h>
    #include <SDL2/SDL.h>
     
    #define WIN_W 640
    #define WIN_H 480
     
    void onKeyPressedDown(SDL_Rect* rect, float delta_time)
    {
        const uint8_t* keyState = SDL_GetKeyboardState(NULL);
     
    	switch(keyState)
    	{
     
    		case SDL_SCANCODE_LEFT:
    		 rect->x -= 200 * delta_time;
    		break;
     
    		case SDL_SCANCODE_RIGHT:
    		 rect->x += 200 * delta_time;
    		break;
     
     
    	}
    }
     
    int main (int argc, char** argv)
    {
        (void) argc; (void) argv;
     
        /* Initialisation de SDL */
     
        if (SDL_Init (SDL_INIT_VIDEO) < 0) { fprintf(stderr, "ERROR: %s", SDL_GetError()); return 1; };
     
        SDL_Window* win = SDL_CreateWindow ("Test mouvement avec delta time", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WIN_W, WIN_H, 0);
        if (!win) { fprintf(stderr, "ERROR: %s", SDL_GetError()); return 1; }
     
        SDL_Renderer* ren = SDL_CreateRenderer (win, -1, SDL_RENDERER_ACCELERATED);
     
        SDL_Event event;
     
        /* Valeurs du programme */
     
        SDL_Rect rect = {(WIN_W-64)/2, (WIN_H-64)/2, 64, 64};
     
        uint32_t actual_frame = SDL_GetTicks();
        uint32_t last_frame = 0;
        float    delta_time = 0;
     
        SDL_bool running = SDL_TRUE;
     
        /* Execution du programme */
     
        while (running)
        {
            /* Calcul du delta time */
     
            last_frame = actual_frame;
            actual_frame = SDL_GetTicks();
            delta_time = (actual_frame - last_frame) / 1000.f;
     
            /* Evenements SDL */
     
            while (SDL_PollEvent(&event))
                running = event.type != SDL_QUIT;
     
            /* Déplacement du rectangle */
     
            onKeyPressedDown(&rect, delta_time);
     
            /* Rendu du programme */
     
            SDL_SetRenderDrawColor(ren, 0, 0, 0, 255);
            SDL_RenderClear(ren);
     
            SDL_SetRenderDrawColor(ren, 255, 255, 255, 255);
            SDL_RenderFillRect(ren, &rect);
     
            SDL_RenderPresent(ren);
     
        }
     
        /* Closing the program */
     
        SDL_DestroyRenderer(ren);
        SDL_DestroyWindow(win);
        SDL_Quit();
     
        return 0;
    }

  8. #8
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    keystate est un tableau, tu ne peux absolument pas faire un switch sur un tableau
    un switch se fait sur une valeur...

    quant au code, tu prétends qu'il est bon, mais en voyant juste la première condition ça fait pas rêver
    if (!keyState[SDL_SCANCODE_LEFT] || !keyState[SDL_SCANCODE_RIGHT]) donc si je n'appuie pas sur gauche ou n'appuie pas sur droite, donc c'est faux uniquement si j'appuie gauche et droite en même temps, ce qui est au mieux bizarre.

    Et avec ces conditions wtf, le comportement est normal.
    Si j'appuye juste sur haut, je monte à 200.
    Si j'appuye sur haut et gauche, je monte à 200 et vais à gauche à 200.
    Et oui le second cas est beaucoup plus rapide que le premier.
    Et si tu ne voyais pas la différence avant c'est juste parce que ton programme est tellement simple et rapide que c'était probablement pas flagrant.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  9. #9
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2022
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2022
    Messages : 21
    Points : 22
    Points
    22
    Par défaut
    Je le savais qu'on ne pouvais pas faire de switch avec mais bon, j'ai quand même essayer ce qu'on m'a proposé...

    Donc j'ai simplifier au maximum les conditions comme elles sont mauvaises mais toujours le même problème pour moi... "bas/droite" ne fonctionnent pas donc je sais que ce n'est pas mes conditions le problème même si elles sont douteuses...

    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
    #include <stdlib.h>
    #include <stdio.h>
    #include <stdint.h>
    #include <SDL2/SDL.h>
     
    #define WIN_W 640
    #define WIN_H 480
     
    int main (int argc, char** argv)
    {
        (void) argc; (void) argv;
     
        /* Initialisation de SDL */
     
        if (SDL_Init (SDL_INIT_VIDEO) < 0) { fprintf(stderr, "ERROR: %s", SDL_GetError()); return 1; };
     
        SDL_Window* win = SDL_CreateWindow ("Test mouvement avec delta time", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WIN_W, WIN_H, 0);
        if (!win) { fprintf(stderr, "ERROR: %s", SDL_GetError()); return 1; }
     
        SDL_Renderer* ren = SDL_CreateRenderer (win, -1, SDL_RENDERER_ACCELERATED);
     
        SDL_Event event;
     
        /* Valeurs du programme */
     
        SDL_Rect rect = {(WIN_W-64)/2, (WIN_H-64)/2, 64, 64};
     
        uint32_t ticks_count = SDL_GetTicks();
        float delta_time;
     
        const uint8_t* keyState = SDL_GetKeyboardState(NULL);
        SDL_bool running = SDL_TRUE;
     
        /* Execution du programme */
     
        while (running)
        {
     
            /* Calcul du delta time */
     
            delta_time = (SDL_GetTicks() - ticks_count) / 1000.0f;
            ticks_count = SDL_GetTicks();
     
            /* Evenements SDL */
     
            while (SDL_PollEvent(&event))
                running = event.type != SDL_QUIT;
     
            SDL_PumpEvents();
     
            /* Déplacement du rectangle */
     
            if (keyState[SDL_SCANCODE_UP])
                rect.y -= 200 * delta_time;
     
            else if (keyState[SDL_SCANCODE_DOWN])
                rect.y += 200 * delta_time;
     
            if (keyState[SDL_SCANCODE_LEFT])
                rect.x -= 200 * delta_time;
     
            else if (keyState[SDL_SCANCODE_RIGHT])
                rect.x += 200 * delta_time;
     
            /* Rendu du programme */
     
            SDL_SetRenderDrawColor(ren, 0, 0, 0, 255);
            SDL_RenderClear(ren);
     
            SDL_SetRenderDrawColor(ren, 255, 255, 255, 255);
            SDL_RenderFillRect(ren, &rect);
     
            SDL_RenderPresent(ren);
     
        }
     
        /* Closing the program */
     
        SDL_DestroyRenderer(ren);
        SDL_DestroyWindow(win);
        SDL_Quit();
     
        return 0;
    }

  10. #10
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2022
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2022
    Messages : 21
    Points : 22
    Points
    22
    Par défaut
    RESOLU ! C'est tout bête et je me le suis dit au départ mais comme ça fonctionnait à moitié je n'y croyais pas !

    C'est juste que les valeurs de SDL_Rect sont de type entières et donc chez moi (avec mon pc pourri) la multiplication avec le delta time tombait proche de 0 et donc (comme type entiers) donnaient 0, mais pourquoi uniquement sur les "+=" ? Perso je ne sais pas. (si... voir fin, si besoin)

    Voici correction si ça arrive à quelqu'un d'autre, il faut utilisé SDL_FRect et non SDL_Rect (qui prend des valeurs float au lieu d'int) et SDL_RenderFillRectF() pour l'afficher. Exemple d'un code qui fait ce que j'attendais, même avec mon pc pourri (et avec gestion des diagonales):

    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
    #include <stdlib.h>
    #include <stdio.h>
    #include <stdint.h>
    #include <SDL2/SDL.h>
     
    #define WIN_W 640
    #define WIN_H 480
     
    int main (int argc, char** argv)
    {
        (void) argc; (void) argv;
     
        /* Initialisation de SDL */
     
        if (SDL_Init (SDL_INIT_VIDEO) < 0) { fprintf(stderr, "ERROR: %s", SDL_GetError()); return 1; };
     
        SDL_Window* win = SDL_CreateWindow ("Test mouvement avec delta time", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WIN_W, WIN_H, 0);
        if (!win) { fprintf(stderr, "ERROR: %s", SDL_GetError()); return 1; }
     
        SDL_Renderer* ren = SDL_CreateRenderer (win, -1, SDL_RENDERER_ACCELERATED);
     
        SDL_Event event;
     
        /* Valeurs du programme */
     
        SDL_FRect rect = {(WIN_W-64)/2.f, (WIN_H-64)/2.f, 64.f, 64.f};
     
        uint32_t ticks_count = SDL_GetTicks();
        float delta_time;
     
        const uint8_t* keyState = SDL_GetKeyboardState(NULL);
        SDL_bool running = SDL_TRUE;
     
        /* Execution du programme */
     
        while (running)
        {
     
            /* Calcul du delta time */
     
            delta_time = (SDL_GetTicks() - ticks_count) / 1000.0f;
            ticks_count = SDL_GetTicks();
     
            /* Evenements SDL */
     
            while (SDL_PollEvent(&event))
                running = event.type != SDL_QUIT;
     
            SDL_PumpEvents();
     
            /* Déplacement du rectangle en prenant compte des diagonales */
     
            float vx = 0.f, vy = 0.f; // Valeurs de direction
     
            if (keyState[SDL_SCANCODE_UP])    vy -= 1.0f;
            if (keyState[SDL_SCANCODE_DOWN])  vy += 1.0f;
            if (keyState[SDL_SCANCODE_LEFT])  vx -= 1.0f;
            if (keyState[SDL_SCANCODE_RIGHT]) vx += 1.0f;
     
            float length = sqrt(vx * vx + vy * vy);
     
            if (length > 0.0f)
            {
                vx /= length;
                vy /= length;
            }
     
            rect.x += (vx*200) * delta_time;
            rect.y += (vy*200) * delta_time;
     
            /* Rendu du programme */
     
            SDL_SetRenderDrawColor(ren, 0, 0, 0, 255);
            SDL_RenderClear(ren);
     
            SDL_SetRenderDrawColor(ren, 255, 255, 255, 255);
            SDL_RenderFillRectF(ren, &rect);
     
            SDL_RenderPresent(ren);
     
        }
     
        /* Closing the program */
     
        SDL_DestroyRenderer(ren);
        SDL_DestroyWindow(win);
        SDL_Quit();
     
        return 0;
    }
    Merci quand même pour l'attention portée ! Dailleurs si quelqu'un a des suggestions sur le pourquoi uniquement les "+=" ça serait le bienvenu ! ^^

    Edit: la raison était ultra évidente, je vais me reposé Je vous laisse faire vos conclusions si jamais ça peu en aider, merci en tout cas
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include <stdio.h>
     
    int main(void)
    {
        int n1 = 1, n2 = 1;
        n1 += .4f; n2 -= .4f;
     
        printf("%d\n", n1);
        printf("%d\n", n2);
     
        return 0;
    }

  11. #11
    Expert éminent sénior
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 361
    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 361
    Points : 20 381
    Points
    20 381
    Par défaut
    Autant pour moi oui il y a une erreur dans mon code et la fonction SDL_GetKeyboardState retourne bien un tableau.
    Mea Culpa et à la modération de modifier les messages inappropriés

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

Discussions similaires

  1. Problème avec la fonction TIME
    Par Alouka dans le forum VBScript
    Réponses: 2
    Dernier message: 02/02/2009, 14h59
  2. VB6 - Problème de compilation avec un Objet - Run-Time Error 91
    Par Hadware dans le forum VB 6 et antérieur
    Réponses: 4
    Dernier message: 18/12/2008, 21h13
  3. [DHTML] Problème de déplacement de calque avec SMF sous Firefox
    Par kiwithereturn dans le forum Balisage (X)HTML et validation W3C
    Réponses: 4
    Dernier message: 24/08/2007, 09h46
  4. Problème tout bête (normallement :) ) avec les date/time
    Par KuBi4K dans le forum SQL Procédural
    Réponses: 1
    Dernier message: 21/06/2007, 20h19
  5. [MySQL 5 + Java] Problème avec un champ TIME
    Par ultracoxy dans le forum SQL Procédural
    Réponses: 1
    Dernier message: 08/07/2006, 09h25

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