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 :

vitesse de rafraichissement SDL_KEYDOWN


Sujet :

SDL

  1. #1
    Membre éclairé Avatar de guitz
    Homme Profil pro
    Webdesigner
    Inscrit en
    Juillet 2006
    Messages
    717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Webdesigner

    Informations forums :
    Inscription : Juillet 2006
    Messages : 717
    Points : 741
    Points
    741
    Par défaut vitesse de rafraichissement SDL_KEYDOWN
    Bonsoir,

    Je tente de programmer un déplacement d'un objet avec élan. Si je déplace l'objet par ex vers la droite avec la flêche droite de mon clavier, je souhaite que la vitesse de déplacement se décrémente de 1 dans une boucle (position += vitesse += accélération) :

    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
    while (continuer){
            SDL_PollEvent(&event);
            switch(event.type)
            {
                case SDL_QUIT:
                    continuer = 0;
                    break;
                case SDL_KEYDOWN:
                    uniteDeplacement = 5;
                    switch(event.key.keysym.sym)
                    {
                        case SDLK_UP: // Flèche haut
                            positionGuitar.y -= uniteDeplacement;
                            derniereTouche = SDLK_UP;
                            break;
                        case SDLK_DOWN: // Flèche bas
                            positionGuitar.y += uniteDeplacement;
                            derniereTouche = SDLK_DOWN;
                            break;
                        case SDLK_RIGHT: // Flèche droite
                            positionGuitar.x += uniteDeplacement;
                            derniereTouche = SDLK_RIGHT;
                            break;
                        case SDLK_LEFT: // Flèche gauche
                            positionGuitar.x -= uniteDeplacement;
                            derniereTouche = SDLK_LEFT;
                            break;
                    }
                    break;
                case SDL_KEYUP:
                        //fprintf(stderr, "%d\n", SDLK_last);
                     switch(derniereTouche){
                         case SDLK_UP:
                            while(uniteDeplacement > 0){
                                positionGuitar.y -= uniteDeplacement;
                                uniteDeplacement -= 0.1;
                                fprintf(stderr, "%g\n", uniteDeplacement);
                            }
                            break;
                         case SDLK_RIGHT:
                            while(uniteDeplacement > 0){
                                positionGuitar.x += uniteDeplacement;
                                uniteDeplacement--;
                            }
                            break;
                         case SDLK_DOWN:
                            while(uniteDeplacement > 0){
                                positionGuitar.y += uniteDeplacement;
                                uniteDeplacement--;
                            }
                            break;
                         case SDLK_LEFT:
                            while(uniteDeplacement > 0){
                                positionGuitar.x -= uniteDeplacement;
                                uniteDeplacement--;
                            }
                            break;
                     }
                    break;
            }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    case SDLK_UP:
                            while(uniteDeplacement > 0){
                                positionGuitar.y -= uniteDeplacement;
                                uniteDeplacement -= 0.1;
                                //fprintf(stderr, "%d\n", uniteDeplacement);
                            }

    Le soucis c'est que la vitesse de rafraichissement du déplacement de l'objet et celle du ralentissement ne semblent pas les mêmes puisque lorsque je relâche la touche le cumulé des déplacements de chaque tours de boucle, semble se réaliser instantanément: autrement dit l'objet se téléporte au lieu de décélérer.

    Une idée ?

  2. #2
    Membre émérite Avatar de SofEvans
    Homme Profil pro
    Développeur C
    Inscrit en
    Mars 2009
    Messages
    1 076
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 076
    Points : 2 328
    Points
    2 328
    Par défaut
    C'est tout a fait normal selon le code que tu nous as donné :

    Lorsqu'on appuie sur un touche, ton objet doit faire un petit bond de 5 pixel. Il n'y a aucune acceleration :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
               case SDL_KEYDOWN:
                    uniteDeplacement = 5;
     
                    ...                
     
                    break;
    Tu vois ce bond de 5 pixel car l'evenement est traité une fois. Autrement dis, tant que tu reste appuyer sur la fleche UP, ton objet aura fait uniquement 5 pixel de decalage, visible puisqu'ici on sort du case et tu execute certainement un SDL_Flip();.

    Ce qui nous amene au cas du relachement :

    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
     
                case SDL_KEYUP:
                        //fprintf(stderr, "%d\n", SDLK_last);
                     switch(derniereTouche){
                         case SDLK_UP:
                            while(uniteDeplacement > 0){
                                positionGuitar.y -= uniteDeplacement;
                                uniteDeplacement -= 0.1;
                                fprintf(stderr, "%g\n", uniteDeplacement);
                            }
                            break;
     
                            ...
     
                     }
                    break;
    lorsqu'on relache la touche, tu regarde la derniere touche et tu agis en consequence. Si j'avais appuyer sur UP, tu recupere uniteDeplacement et tu le decremente en meme temps que tu le bouge. Normalement, on devrait voir une sorte de decceleration. Sauf que ...
    Tu as fait une boucle while ! Et il n'y a pas de SDL_Flip() ! Donc ton objet va bien decrementer mais il va decrementer a la vitesse du processeur (mauvaise gestion des timers sans doute) et il va le faire sans SDL_Flip().
    Du coup, tu verra uniquement la position du vaisseau une fois sortie de ce while, c'est a dire une fois que toutes la decrementation aura été faite.


    Pour corrigé ca, tu as plusieurs possibilité, mais le probleme pour moi vient du fait que je ne sais pas comment tu veux que ta guitare se comporte. En tout cas, avec le code donné, ta guitare se comporte de la maniere suivante :

    J'appui sur UP -> saut de 5 pixel vers le haut
    Je reste appuyer -> La guitare ne bouge pas (a moins d'avoir SDL_EnableKeyRepeat qui est mauvais)
    Je relache -> Normalement la guitare se remet en mouvement avec un decceleration




    Derniere petite remarque :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SDL_PollEvent(&event);
    Ce n'est pas comme ca que l'on gere les evenement en SDL.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    while (SDL_PollEvent(&event))
    Sans toucher au reste du code.

  3. #3
    Membre éclairé Avatar de guitz
    Homme Profil pro
    Webdesigner
    Inscrit en
    Juillet 2006
    Messages
    717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Webdesigner

    Informations forums :
    Inscription : Juillet 2006
    Messages : 717
    Points : 741
    Points
    741
    Par défaut
    Citation Envoyé par SofEvans Voir le message
    C'est tout a fait normal selon le code que tu nous as donné :

    Lorsqu'on appuie sur un touche, ton objet doit faire un petit bond de 5 pixel. Il n'y a aucune acceleration :
    Je n'ai jamais dit que je souhaitais une accélération !

    Citation Envoyé par SofEvans Voir le message
    lorsqu'on relache la touche, tu regarde la derniere touche et tu agis en consequence. Si j'avais appuyer sur UP, tu recupere uniteDeplacement et tu le decremente en meme temps que tu le bouge. Normalement, on devrait voir une sorte de decceleration. Sauf que ...
    Inutile de m'expliquer l'algorithme puisque je l'ai appliqué dans mon code.

    mais le probleme pour moi vient du fait que je ne sais pas comment tu veux que ta guitare se comporte. En tout cas, avec le code donné, ta guitare se comporte de la maniere suivante :

    Citation Envoyé par SofEvans Voir le message
    J'appui sur UP -> saut de 5 pixel vers le haut
    Je reste appuyer -> La guitare ne bouge pas (a moins d'avoir SDL_EnableKeyRepeat qui est mauvais)
    Je relache -> Normalement la guitare se remet en mouvement avec un decceleration
    tu n'as pas tout mon code j'ai mis plus haut :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SDL_EnableKeyRepeat(10, 10);
    Pour le reste tu as raison concernant SDL_Flip, il est présent en fin de boucle parente mais pas en fin de boucle enfant, d'où la téléportation. Merci bien

  4. #4
    Membre émérite Avatar de SofEvans
    Homme Profil pro
    Développeur C
    Inscrit en
    Mars 2009
    Messages
    1 076
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 076
    Points : 2 328
    Points
    2 328
    Par défaut
    Citation Envoyé par guitz Voir le message
    Inutile de m'expliquer l'algorithme puisque je l'ai appliqué dans mon code.
    Inutile d'etre aussi incisif. Il n'y a aucun commentaire dans ton code, ce qui fait que je ne peut que supposer.
    De plus, si tu as un probleme, c'est bien qu'algorithmiquement quelque chose ne va pas.
    En l'occurence, dans un programme SDL, l'affichage depend des image par seconde, traitement inexistant dans ton code.
    De plus, et c'est la le plus gros probleme, on ne fait qu'un seul est unique SDL_Flip() par boucle de jeu. Or la, tu en a beaucoup trop.




    Citation Envoyé par guitz Voir le message
    tu n'as pas tout mon code j'ai mis plus haut :
    Je suis pas devin, et comme je l'ai dit, SDL_EnableKeyRepeat et mauvais si tu veux faire acceleration/decceleration.


    Mais bon, y'a que toi pour voir si tu veux progresser lentement ou rapidement.

  5. #5
    Membre éclairé Avatar de guitz
    Homme Profil pro
    Webdesigner
    Inscrit en
    Juillet 2006
    Messages
    717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Webdesigner

    Informations forums :
    Inscription : Juillet 2006
    Messages : 717
    Points : 741
    Points
    741
    Par défaut
    Non en fait ce que j'ai dit dans mon énoncé initial c'est que au départ je souhaite un mvt uniforme et ensuite un mvt décéléré, et toi tu m'expliques comment avoir un mvt accéléré, enfin bref c'est pas bien grave.

    En fait mon pb vient plus de la syntaxe et de la construction autour de la librairie sdl que de ma capacité à mettre en place l'algorithme puisque en actionscript j'aurais codé ça en un rien de temps. Mais en c c'est beaucoup plus compliqué surtout pour un débutant qui na que 15 heures à son actif (dont 20% seulement de temps passé à la pratique).

    Bon là mon code est presque bon, mais tu m'as dit qu'il fallait éviter SDL_EnableKeyRepeat, que conseilles-tu alors ?

  6. #6
    Membre émérite Avatar de SofEvans
    Homme Profil pro
    Développeur C
    Inscrit en
    Mars 2009
    Messages
    1 076
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 076
    Points : 2 328
    Points
    2 328
    Par défaut
    Deja, il faut gerer les timers afin d'instaurer un temps de rafraichissement. 60 image/second est un tres bon chiffre.

    As tu une gestion comme cela ?

    Sinon, pour esquiver le SDL_EnableKeyRepeat (en qui je n'ai jamais eu confiance car peu fiable), tu peux te diriger vers SDL_GetKeyStates(). Cela te retourne l'etat des touche sous forme de int "booleen".

  7. #7
    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
    Citation Envoyé par guitz Voir le message
    Je n'ai jamais dit que je souhaitais une accélération !
    Inutile de m'expliquer l'algorithme puisque je l'ai appliqué dans mon code.
    Eh faut pas s'énerver SoftEvans essaie de t'aider sympathiquement.
    Peut-être que l'accélération est à gérer pour un mouvement plus réaliste et un déplacement graduel

  8. #8
    Membre émérite Avatar de SofEvans
    Homme Profil pro
    Développeur C
    Inscrit en
    Mars 2009
    Messages
    1 076
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 076
    Points : 2 328
    Points
    2 328
    Par défaut
    Citation Envoyé par Mat.M Voir le message
    Eh faut pas s'énerver SoftEvans essaie de t'aider sympathiquement.
    Peut-être que l'accélération est à gérer pour un mouvement plus réaliste et un déplacement graduel

    Apparemment, il a deja coder son jeu.
    Ce qu'il veut actuellement faire, c'est le reprendre afin d'y apporter toutes les ameliorations vu après.
    Il a decider que dans son jeu, il ne gererai aucun mouvement d'acceleration mais simplement une deceleration.
    C'est pourquoi SDL_EnableKeyRepeat(10, 10); marche. Je me souviens avoir eu quelque cas particulier en utilisant cette fonction lorsque je voulais coder de la velocité. Je me suis renseigner et il est apparue que cela venait de cette fonction.
    C'est pour ca que je ne l'utilise plus et que je la deconseille.
    Maintenant, je gere tout les deplacement/velocité grace aux timers, et honnetement, j'ai un controle totale de ce qui se passe

    J'exprime mes vitesse en pixel/seconde et quelque soit la plateforme de test, il n'y a aucun probleme, le jeu tourne pile poil.

    Le probleme fondamental de ce morceaux de code, c'est qu'il n'utilise pas des timers, et s'il a comme un pc lent, ca va lui faire bizarre s'il met son jeu sur un autre pc.

  9. #9
    Membre éclairé Avatar de guitz
    Homme Profil pro
    Webdesigner
    Inscrit en
    Juillet 2006
    Messages
    717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Webdesigner

    Informations forums :
    Inscription : Juillet 2006
    Messages : 717
    Points : 741
    Points
    741
    Par défaut
    Citation Envoyé par Mat.M Voir le message
    Eh faut pas s'énerver SoftEvans essaie de t'aider sympathiquement.
    Peut-être que l'accélération est à gérer pour un mouvement plus réaliste et un déplacement graduel
    Oui c'est plus réaliste, et d'ailleurs je l'ai intégré dans mon code tout à l'heure Au début je faisais juste des tests, pour la décélération.
    En fait dsl si j'ai été un peu sec mais je ne comprends pas pourquoi on m'explique le béaba d'un algorythme intégrant des vecteurs alors que ma question était claire. Mais dans la suite du post j'ai eu droit à une réponse valable et je l'en remercie

    Concernant les timer je remet ça a plus tard n'ayant pas encore attaqué la théorie (c'est dans la suite d'un tuto que je suis entraint de suivre). C'est clair que c'est beaucoup plus flexible et je ne m'en priverai pas

  10. #10
    Membre émérite Avatar de SofEvans
    Homme Profil pro
    Développeur C
    Inscrit en
    Mars 2009
    Messages
    1 076
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 076
    Points : 2 328
    Points
    2 328
    Par défaut
    Citation Envoyé par guitz Voir le message
    En fait dsl si j'ai été un peu sec mais je ne comprends pas pourquoi on m'explique le béaba d'un algorythme intégrant des vecteurs alors que ma question était claire. Mais dans la suite du post j'ai eu droit à une réponse valable et je l'en remercie
    En fait, je t'ai donner les infos que tu voulais plus des infos supplementaire.
    De mon point de vue, en tant que debutant (bon, pas du C et de la SDL, mais ...), je me dit que toutes info est bonne a prendre, meme si elle repond indirectement au sujet.
    C'est pour ca que j'ai deborder avant de repondre.

    De plus, j'ai été surpris.
    Tu me dis que tu as fini ton jeu (et je sais qu'un jeu peux etre long a coder), mais je ne vois ni gestion temps ni commentaire. C'est pour ca que je n'ai pas hesité a en dire beaucoup.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Concernant les timer je remet ça a plus tard n'ayant pas encore attaqué la théorie (c'est dans la suite d'un tuto que je suis entraint de suivre). C'est clair que c'est beaucoup plus flexible et je ne m'en priverai pas
    Ah. Si le tuto provient d'un autre site, je te conseille de le completer par ceux de developpez (les excellents tutoriels SDL de loka). Il te seront d'une grande aide pour plus tard et on y voit des notions non aborder ailleurs.

    Enfin bon, si tu veux que je regarde ton code pour y apporter un plus, te gene pas.
    Mon adresse msn est sur mon profil.

    En tout cas, bonne continuation.


    PS : Si tu n'est pas obligé de te servir de la SDL, je te conseille de t'interresser fortement a la SFLM. C'est a peu pres la meme chose sur le fond sauf que SFLM est generalement meilleur.

  11. #11
    Membre éclairé Avatar de guitz
    Homme Profil pro
    Webdesigner
    Inscrit en
    Juillet 2006
    Messages
    717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Webdesigner

    Informations forums :
    Inscription : Juillet 2006
    Messages : 717
    Points : 741
    Points
    741
    Par défaut
    Ok c'est sympa de m'épauler softEvans.

    Voici mon code avec tout un tas de pointeurs svp La théorie commence à bien rentrer avec la pratique :

    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <time.h>
    #include <string.h>
    #include <ctype.h>
    #include <SDL/SDL.h>
    #include <SDL_image.h>
     
    void changerVitesseObjet(int acceleration, SDL_Rect *positionObjet, SDLKey *derTouche, double *unitDeplacement, double unitDeplacementMax, double uniteAccel, SDL_Event event);
     
    int main(int argc, char *argv[])
    {
        SDL_Surface *ecran = NULL, *imageDeFond = NULL, *guitar = NULL;
        SDL_Rect positionFond, positionGuitar;
        SDL_Event event;
        SDLKey derniereTouche;
     
        int continuer = 1, direction = NULL, acceleration = NULL;
        double uniteDeplacement = 0, uniteAccel = 0.15, uniteDeplacementMax = 7;
     
        positionFond.x = 0;
        positionFond.y = 0;
     
        SDL_Init(SDL_INIT_VIDEO);
     
        SDL_WM_SetIcon(IMG_Load("images/sdl_icone.bmp"), NULL);
     
        ecran = SDL_SetVideoMode(1000, 800, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
        SDL_WM_SetCaption("Chargement d'images en SDL", NULL);
     
        imageDeFond = IMG_Load("images/hendrix.bmp");
        guitar = IMG_Load("images/guitar.png");
     
        positionGuitar.x = ecran->w / 2 - guitar->w / 2;
        positionGuitar.y = ecran->h / 2 - guitar->h / 2;
     
        SDL_EnableKeyRepeat(10, 10);
     
        while (continuer){
     
            SDL_PollEvent(&event);
     
            switch(event.type)
            {
                case SDL_QUIT:
                    continuer = 0;
                    break;
                case SDL_KEYDOWN:
                    changerVitesseObjet(1, &positionGuitar, &derniereTouche, &uniteDeplacement, uniteDeplacementMax, uniteAccel, event);
                    break;
                case SDL_KEYUP:
                    changerVitesseObjet(0, &positionGuitar, &derniereTouche, &uniteDeplacement, uniteDeplacementMax, uniteAccel, event);
                    break;
            }
            SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 0, 0, 0));
            SDL_BlitSurface(imageDeFond, NULL, ecran, &positionFond);
            SDL_BlitSurface(guitar, NULL, ecran, &positionGuitar);
            SDL_Flip(ecran);
     
        }
     
        SDL_FreeSurface(imageDeFond);
        SDL_FreeSurface(guitar);
        SDL_Quit();
     
        return EXIT_SUCCESS;
    }
     
    void changerVitesseObjet(int acceleration, SDL_Rect *positionObjet, SDLKey *derTouche, double *unitDeplacement, double unitDeplacementMax, double uniteAccel, SDL_Event event){
     
        switch(event.key.keysym.sym)
            {
                    case SDLK_UP: // Flèche haut
                        (*positionObjet).y -= *unitDeplacement;
                        if(acceleration)
                            *derTouche = SDLK_UP;
                        break;
                    case SDLK_DOWN: // Flèche bas
                        (*positionObjet).y += *unitDeplacement;
                        if(acceleration)
                            *derTouche = SDLK_DOWN;
                        break;
                    case SDLK_RIGHT: // Flèche droite
                        (*positionObjet).x += *unitDeplacement;
                        if(acceleration)
                            *derTouche = SDLK_RIGHT;
                        break;
                    case SDLK_LEFT: // Flèche gauche
                        (*positionObjet).x -= *unitDeplacement;
                        if(acceleration)
                            *derTouche = SDLK_LEFT;
                        break;
            }
     
        if(acceleration){
            if(*unitDeplacement < unitDeplacementMax){
                *unitDeplacement += uniteAccel;
            }
        }else{
            if((*unitDeplacement - uniteAccel) >= 0){
                *unitDeplacement -= uniteAccel;
                if(*unitDeplacement < uniteAccel)
                        *unitDeplacement = 0;
     
            }
        }
    }

  12. #12
    Membre émérite Avatar de SofEvans
    Homme Profil pro
    Développeur C
    Inscrit en
    Mars 2009
    Messages
    1 076
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 076
    Points : 2 328
    Points
    2 328
    Par défaut
    Bon, je met mes remarque sur ton code ici pour en faire profiter tout le monde :


    C'est plutot long et ecrit en largeur aussi, le mieux est de copier/coller.

    PS : Je vais finir pas changer de pseudo si tout le monde m'appelle SoftEvans

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <time.h>
    #include <string.h>
    #include <ctype.h>
    #include <SDL/SDL.h>
     
    /* Premiere remarque : Aucun commentaire ... dur pour moi ... 
       Les seul commentaire present sont
        
       case SDLK_LEFT : // fleche gauche 
       
       Sans dec ? Je l'aurai pas deviné !   ><  */
     
     
    /* Le fond d'ecran est toujours en haut a gauche :
     
    pseudo-code 1:
        ...
        SDL_Rect positionFond;
        ...
        positionFond.x = 0;
        positionFond.y = 0;
        ...
        SDL_BlitSurface(imageDeFond, NULL, ecran, &positionFond);
        ...
     
        Dans un tel cas de figure, on peut se passer du SDL_Rect.
        En effet, si un parametre de SDL_Rect est mis a NULL, il sera considerer comme valant (0,0).
        Donc, l'image sera blitter en haut a gauche.
     
        Le pseudo-code 1 peut etre remplacer par :
    pseudo-code 2:
        ...
        SDL_BlitSurface(imageDeFond, NULL, ecran, NULL);
        ...
     
    */
     
    /*
    pseudo-code 3:
        ...
        SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 0, 0, 0));
        SDL_BlitSurface(imageDeFond, NULL, ecran, NULL);
        ...
     
        Si ton fond d'ecran contenue dans imageDeFond fait exactement les dimensions de ta fenetre, alors
        le pseudo-code 3 peut s'ecrire :
     
    pseudo-code 4:
        ...
        SDL_BlitSurface(imageDeFond, NULL, ecran, NULL);
        ...
     
        En effet, ton imageDeFond remplis deja l'ecran, inutile de remplir l'ecran de blanc. Par contre si ton image ne fait
        pas tout ton ecran, alors il faut garder ton FillRect.
     
    */
     
    /*
    pseudo code 5:
        ...
        SDL_PollEvent(&event);
        switch(event.type)
        ...
     
        J'ai deja expliqué que c'etait la mauvaise maniere de gerer les event avec PollEvent
        Quant tu arrive sur PollEvent, tu recupere 0 ou plusieurs evenement, et a la suite, tu en traite un seul.
        Si tu fait plein d'evenement, la file d'evenement va s'aggrandir et il va y avoir un decalage entre le moment ou l'evenement
        va etre saisie et le moment ou il va etre traité. Sur un petit programme utilisant quatre touche, je peux comprendre que tu n'est
        jamais vu ca, mais si tu fais une image qui suit la souris avec d'autre evenement, tu verra qu'au bout d'un moment, l'image ne sera
        plus sur la souris mais suivra le chemin deja parcouru !
        En resumé :
     
    pseudo code 6:
        ...
        while (SDL_PollEvent(&event))
            switch(event.type)
            {
                ...
            }
        ...
     
        Cela fait tres bien l'affaire. A chaque fois que PollEvent recupere X evenement, on les traite tous.
     
    */
     
    /*  Un gros, gros soucis : tu ne verifie pas le retour des fonctions SDL. Encore pour FillRect, BlitSurface je veux bien, le programme
        n'est pas remis en cause, mais tout ce qui concerne l'allocation memoire DOIT etre verifier !
        Cela concerne aussi bien SDL_CreateRGBSurface que SDL_LoadBMP (et aussi donc IMG_Load de sdl_image.h)
     
        J'ai remplacer tes IMG_Load par SDL_LoadBMP mais le principe reste le meme :
     
    pseudo-code 7:
        ...
        imageDeFond = SDL_LoadBMP("hendrix.bmp");
        guitar = SDL_LoadBMP("guitar.bmp");
        ...
     
        Comme expliqué ci-dessus, faux et DANGEREUX.
        Pour la petite histoire : J'ai codé plusieurs programme SDL plus ou moins gros. Un jour, mon (petit) programme (de 800 lignes)
        plante dès l'ouverture. Rien dans les fichiers standart de sortie et d'erreur, et je savais mal me servir du debuggeur (on est
        tous debutant au debut).
        J'ai mis 3 heures a trouver le probleme : etant donné que les .h, .c et .bmp s'accumulé, j'ai creer un sous-dossier pour y mettre
        tout mes bmp. J'ai ensuite coder plusieurs fonction sans rapport au bmp (et de surcroit simple) avant de tester.
        Resultat : j'etait persuader que le crash venait des nouvelle fonction et non de cette stupide deportation.
        Si j'avais bien gerer mes SDL_LoadBMP, j'aurais directement eu un message d'erreur dans mon fichier stanart de sortie et aurai
        regler le probleme en 30 seconde ... au lieu de 3 heure (a trifouiller un code sans erreur :/  )
     
        Donc :
     
    pseudo-code 8:
        ...
        imageDeFond = SDL_LoadBMP("hendrix.bmp");
        if (imageDeFond == NULL)
        {
            printf("Erreur de chargement pour le sprite imageDeFond : %s\n",SDL_GetError());
            exit(EXIT_FAILURE);
        }
        guitar = SDL_LoadBMP("guitar.bmp");
        if (guitar == NULL)
        {
            printf("Erreur de chargement pour le sprite guitar : %s\n",SDL_GetError());
            exit(EXIT_FAILURE);
        }
        ...
     
        Cela te permet d'arreter le programme a cet erreur et de decrire dans le fichier de sortie l'erreur de maniere
        precise.
    */
     
    /*
       Autre notion (plus poussé) que tu dois savoir :
       Les sprite ainsi qu l'ecran ont un BPP (profondeur de couleur).
       Celui de l'ecran est de 32, tu l'as fixer à sa creation grace SDL_SetVideoMode.
       Quant aux sprite chargé, ils ont en general 24.
     
       Comme il n'ont pas le meme BPP, a chaque fois que tu appele SDL_BlitSurface, SDL_BlitSurface va convertir
       l'image mais ... a "l'arrache".
       J'ai eu ce probleme qe j'ai decrit dans un post :
       http://www.developpez.net/forums/d781615/applications/developpement-2d-3d-jeux/apis-multimedia/sdl/precision-fps-blittage/
     
       Probleme et solution expliqué dedans (mais partiellement) ^^
       La reponse est qu'il faut utilisé SDL_DisplayFormat sur chaque sprite afin de convertir celui ci avant de
       l'utiliser.
     
    pseudo-code 9:
        ...
        imageDeFond = SDL_LoadBMP("hendrix.bmp");
        if (imageDeFond == NULL)
        {
            printf("Erreur de chargement pour le sprite imageDeFond : %s\n",SDL_GetError());
            exit(EXIT_FAILURE);
        }
        guitar = SDL_LoadBMP("guitar.bmp");
        if (guitar == NULL)
        {
            printf("Erreur de chargement pour le sprite guitar : %s\n",SDL_GetError());
            exit(EXIT_FAILURE);
        }
        ...
     
        Ce pseudo-code 9 devient donc :
     
    pseudo-code 10:
        ...
        SDL_Surface *temporaire = NULL;
        temporaire = SDL_LoadBMP("hendrix.bmp");
        if (temporaire == NULL)
        {
            printf("Erreur de chargement pour le sprite imageDeFond : %s\n",SDL_GetError());
            exit(EXIT_FAILURE);
        }
        imageDeFond = SDL_DisplayFormat(temporaire);
     
        temporaire = SDL_LoadBMP("guitar.bmp");
        if (temporaire == NULL)
        {
            printf("Erreur de chargement pour le sprite guitar : %s\n",SDL_GetError());
            exit(EXIT_FAILURE);
        }
        guitar = SDL_DisplayFormat(temporaire);
     
        SDL_FreeSurface (temporaire);
        ...
     
     
        Lors de mes test sur ton code, j'ai noté une très nette amelioration de la fluidité
    */
     
     
    /* Je m'arrete la car sur le fond, il n'y a plus trop de probleme.
        Maintenant, chaque position est defendable, voici la mienne :
        ** Je trouve que la fonction changerVitesseObjet est absolument inadequate. Trop lourde pour ce qu'elle fait et mal gerer.
           Il suffit de commenter SDL_EnableKeyRepeat pour qu'il n'y est plus rien, pas meme de decceleration. En outre, tu lui passe
           enormement d'argument, en pointeur ou en copie. Franchement, je supprimerai cette fonction
        ** Manque les timers pour resoudre le probleme du haut, mais sujet deja aborder.
        ** Si tu connais les structure, pourquoi ne pas en faire une pour guitar ? 
           Cela permettrai d'y voir plus clair et de declarer moins de variable.
        ** Aucune gestion pour restreindre les mouvment de guitar. On peut donc depasser a droite et en bas car en haut et a gauche c'est la SDL qui apprecie pas.
            Tu devrais mettre des define pour les dimensions de l'ecran, et en fonction de ces define restreindre les deplacement.
    */
     
     
    void changerVitesseObjet(int acceleration, SDL_Rect *positionObjet, SDLKey *derTouche, double *unitDeplacement, double unitDeplacementMax, double uniteAccel, SDL_Event event);
     
    int main(int argc, char *argv[])
    {
        SDL_Surface *ecran = NULL, *imageDeFond = NULL, *guitar = NULL;
        SDL_Rect positionGuitar;
        SDL_Event event;
        SDLKey derniereTouche;
     
        int continuer = 1, direction = NULL, acceleration = NULL;
        double uniteDeplacement = 0, uniteAccel = 0.15, uniteDeplacementMax = 7;
     
     
        SDL_Init(SDL_INIT_VIDEO);
     
        //SDL_WM_SetIcon(IMG_Load("images/sdl_icone.bmp"), NULL);
     
        ecran = SDL_SetVideoMode(1000, 800, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
        SDL_WM_SetCaption("Chargement d'images en SDL", NULL);
     
     
        SDL_Surface *temporaire = NULL;
        temporaire = SDL_LoadBMP("hendrix.bmp");
        if (temporaire == NULL)
        {
            printf("Erreur de chargement pour le sprite imageDeFond : %s\n",SDL_GetError());
            exit(EXIT_FAILURE);
        }
        imageDeFond = SDL_DisplayFormat(temporaire);
     
        temporaire = SDL_LoadBMP("guitar.bmp");
        if (temporaire == NULL)
        {
            printf("Erreur de chargement pour le sprite guitar : %s\n",SDL_GetError());
            exit(EXIT_FAILURE);
        }
        guitar = SDL_DisplayFormat(temporaire);
     
        SDL_FreeSurface (temporaire);
     
        positionGuitar.x = ecran->w / 2 - guitar->w / 2;
        positionGuitar.y = ecran->h / 2 - guitar->h / 2;
     
        SDL_EnableKeyRepeat(10, 10);
     
        while (continuer)
        {
            while (SDL_PollEvent(&event))
            switch(event.type)
                {
                    case SDL_QUIT:
                        continuer = 0;
                        break;
                    case SDL_KEYDOWN:
                        changerVitesseObjet(1, &positionGuitar, &derniereTouche, &uniteDeplacement, uniteDeplacementMax, uniteAccel, event);
                        break;
                    case SDL_KEYUP:
                        changerVitesseObjet(0, &positionGuitar, &derniereTouche, &uniteDeplacement, uniteDeplacementMax, uniteAccel, event);
                        break;
                }
     
            SDL_BlitSurface(imageDeFond, NULL, ecran, NULL);
            SDL_BlitSurface(guitar, NULL, ecran, &positionGuitar);
            SDL_Flip(ecran);
     
        }
     
        SDL_FreeSurface(imageDeFond);
        SDL_FreeSurface(guitar);
        SDL_Quit();
     
        return EXIT_SUCCESS;
    }
     
    void changerVitesseObjet(int acceleration, SDL_Rect *positionObjet, SDLKey *derTouche, double *unitDeplacement, double unitDeplacementMax, double uniteAccel, SDL_Event event){
     
        switch(event.key.keysym.sym)
            {
                    case SDLK_UP: // Flèche haut
                        (*positionObjet).y -= *unitDeplacement;
                        if(acceleration)
                            *derTouche = SDLK_UP;
                        break;
                    case SDLK_DOWN: // Flèche bas
                        (*positionObjet).y += *unitDeplacement;
                        if(acceleration)
                            *derTouche = SDLK_DOWN;
                        break;
                    case SDLK_RIGHT: // Flèche droite
                        (*positionObjet).x += *unitDeplacement;
                        if(acceleration)
                            *derTouche = SDLK_RIGHT;
                        break;
                    case SDLK_LEFT: // Flèche gauche
                        (*positionObjet).x -= *unitDeplacement;
                        if(acceleration)
                            *derTouche = SDLK_LEFT;
                        break;
            }
     
        if(acceleration)
        {
            if(*unitDeplacement < unitDeplacementMax)
                *unitDeplacement += uniteAccel;
        }
        else
            if((*unitDeplacement - uniteAccel) >= 0)
            {
                *unitDeplacement -= uniteAccel;
                if(*unitDeplacement < uniteAccel)
                        *unitDeplacement = 0;
     
            }
     
    }

  13. #13
    Membre éclairé Avatar de guitz
    Homme Profil pro
    Webdesigner
    Inscrit en
    Juillet 2006
    Messages
    717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Webdesigner

    Informations forums :
    Inscription : Juillet 2006
    Messages : 717
    Points : 741
    Points
    741
    Par défaut
    Les commentaires "flêche gauche", "flêche droite", ne sont pas de moi mais étaient présents sur le tuto ! J'ai copié-collé cette portion de code sans supprimer les commentaires. Je me doute bien qu'à votre niveau vous savez ce que signifient ces valeurs de sous-variables....

    Je lis la suite de tes corrections...

    pseudo-code 4:
    ...
    SDL_BlitSurface(imageDeFond, NULL, ecran, NULL);
    ...

    En effet, ton imageDeFond remplis deja l'ecran, inutile de remplir l'ecran de blanc. Par contre si ton image ne fait
    pas tout ton ecran, alors il faut garder ton FillRect.

    */
    Ouais ça je sais, mais l'image était petite, et pour l'anime de test jai eu besoin de plus de place, alors j'ai juste agrandi la taille de la fenêtre, ne voulant mettre à jour l'image. Pour un vrai projet de jeu l'image de fond fera bien sûr la taille de ma fenêtre

    Si je met :

    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
     while (continuer){
    
            while(SDL_PollEvent(&event)){
    
                switch(event.type){
                    case SDL_QUIT:
                        continuer = 0;
                        break;
                    case SDL_KEYDOWN:
                        changerVitesseObjet(1, &positionGuitar, &derniereTouche, &uniteDeplacement, uniteDeplacementMax, uniteAccel, event);
                        break;
                    case SDL_KEYUP:
                        changerVitesseObjet(0, &positionGuitar, &derniereTouche, &uniteDeplacement, uniteDeplacementMax, uniteAccel, event);
                        break;
                }
                SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 0, 0, 0));
                SDL_BlitSurface(imageDeFond, NULL, ecran, &positionFond);
                SDL_BlitSurface(guitar, NULL, ecran, &positionGuitar);
                SDL_Flip(ecran);
            }
    
        }
    
        SDL_FreeSurface(imageDeFond);
        SDL_FreeSurface(guitar);
        SDL_Quit();
    
        return EXIT_SUCCESS;
    }
    La décélération n'est plus prise en compte, fais le test et tu verras

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Un gros, gros soucis : tu ne verifie pas le retour des fonctions SDL. Encore pour FillRect, BlitSurface je veux bien, le programme
        n'est pas remis en cause, mais tout ce qui concerne l'allocation memoire DOIT etre verifier !
        Cela concerne aussi bien SDL_CreateRGBSurface que SDL_LoadBMP (et aussi donc IMG_Load de sdl_image.h)
    J'ai rien compris, tu peux m'expliquer par un exemple ?

    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
    pseudo-code 8:
        ...
        imageDeFond = SDL_LoadBMP("hendrix.bmp");
        if (imageDeFond == NULL)
        {
            printf("Erreur de chargement pour le sprite imageDeFond : %s\n",SDL_GetError());
            exit(EXIT_FAILURE);
        }
        guitar = SDL_LoadBMP("guitar.bmp");
        if (guitar == NULL)
        {
            printf("Erreur de chargement pour le sprite guitar : %s\n",SDL_GetError());
            exit(EXIT_FAILURE);
        }
        ...
     
        Cela te permet d'arreter le programme a cet erreur et de decrire dans le fichier de sortie l'erreur de maniere
        precise.
    */
    Si mon fichier .bmp est bien présent et n'est pas corrompu, pourquoi y aurait-il une erreur de chargement ? C'est alourdir son code inutilement

    Je lis la suite de ton message...

    Autre notion (plus poussé) que tu dois savoir :
    Les sprite ainsi qu l'ecran ont un BPP (profondeur de couleur).
    Celui de l'ecran est de 32, tu l'as fixer à sa creation grace SDL_SetVideoMode.
    Quant aux sprite chargé, ils ont en general 24.

    Comme il n'ont pas le meme BPP, a chaque fois que tu appele SDL_BlitSurface, SDL_BlitSurface va convertir
    l'image mais ... a "l'arrache".
    J'ai eu ce probleme qe j'ai decrit dans un post :
    http://www.developpez.net/forums/d78...-fps-blittage/

    Probleme et solution expliqué dedans (mais partiellement) ^^
    La reponse est qu'il faut utilisé SDL_DisplayFormat sur chaque sprite afin de convertir celui ci avant de
    l'utiliser.
    C'est du perfectionnisme à l'extrême tout ça. Concrêtement ça me poserai quels pbs et dans quels cas ?

  14. #14
    Membre éclairé Avatar de guitz
    Homme Profil pro
    Webdesigner
    Inscrit en
    Juillet 2006
    Messages
    717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Webdesigner

    Informations forums :
    Inscription : Juillet 2006
    Messages : 717
    Points : 741
    Points
    741
    Par défaut
    Lors de mes test sur ton code, j'ai noté une très nette amelioration de la fluidité
    Ah ok merci ça m'interesse finalement

    Edit : Oh put*** merci ! c'est le jour et la nuit la fluidité est sans appel, merci de m'expliquer en vulgarisant qu'est ce qui a rendu l'animation plus fluide.

    Par contre le soucis SoftEvans c'est que la transparence du .png n'est plus respectée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    temporaire = SDL_LoadBMP("images/hendrix.bmp");
                if (temporaire == NULL)
                {
                    printf("Erreur de chargement pour le sprite imageDeFond : %s\n",SDL_GetError());
                    exit(EXIT_FAILURE);
                }
                imageDeFond = SDL_DisplayFormat(temporaire);
     
                temporaire = IMG_Load("images/guitar.png");
                if (temporaire == NULL)
                {
                    printf("Erreur de chargement pour le sprite guitar : %s\n",SDL_GetError());
                    exit(EXIT_FAILURE);
                }
                guitar = SDL_DisplayFormat(temporaire);
    Edit : Quoi qu'avec ton code on perd la décélération, testes et tu verras

    ** Je trouve que la fonction changerVitesseObjet est absolument inadequate. Trop lourde pour ce qu'elle fait et mal gerer.
    Il suffit de commenter SDL_EnableKeyRepeat pour qu'il n'y est plus rien, pas meme de decceleration. En outre, tu lui passe
    enormement d'argument, en pointeur ou en copie. Franchement, je supprimerai cette fonction
    Ce serait constructif de proposer qq chose...

    ** Aucune gestion pour restreindre les mouvment de guitar. On peut donc depasser a droite et en bas car en haut et a gauche c'est la SDL qui apprecie pas.
    Tu devrais mettre des define pour les dimensions de l'ecran, et en fonction de ces define restreindre les deplacement.
    J'en suis pas encore là je te rappelle que j'étais en train de tester uniquement une animation de accélération-mvt uniforme-décélération, chaque chose en son temps.

    Si tu connais les structure, pourquoi ne pas en faire une pour guitar ?
    Cela permettrai d'y voir plus clair et de declarer moins de variable.
    Ca c'est un super bon conseil merci, je vais l'appliquer et je posterai la suite ici

  15. #15
    Membre émérite Avatar de SofEvans
    Homme Profil pro
    Développeur C
    Inscrit en
    Mars 2009
    Messages
    1 076
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 076
    Points : 2 328
    Points
    2 328
    Par défaut
    Citation Envoyé par guitz Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Un gros, gros soucis : tu ne verifie pas le retour des fonctions SDL. Encore pour FillRect, BlitSurface je veux bien, le programme
        n'est pas remis en cause, mais tout ce qui concerne l'allocation memoire DOIT etre verifier !
        Cela concerne aussi bien SDL_CreateRGBSurface que SDL_LoadBMP (et aussi donc IMG_Load de sdl_image.h)
    J'ai rien compris, tu peux m'expliquer par un exemple ?

    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
    pseudo-code 8:
        ...
        imageDeFond = SDL_LoadBMP("hendrix.bmp");
        if (imageDeFond == NULL)
        {
            printf("Erreur de chargement pour le sprite imageDeFond : %s\n",SDL_GetError());
            exit(EXIT_FAILURE);
        }
        guitar = SDL_LoadBMP("guitar.bmp");
        if (guitar == NULL)
        {
            printf("Erreur de chargement pour le sprite guitar : %s\n",SDL_GetError());
            exit(EXIT_FAILURE);
        }
        ...
     
        Cela te permet d'arreter le programme a cet erreur et de decrire dans le fichier de sortie l'erreur de maniere
        precise.
    */
    Si mon fichier .bmp est bien présent et n'est pas corrompu, pourquoi y aurait-il une erreur de chargement ? C'est alourdir son code inutilement


    C'est du perfectionnisme à l'extrême tout ça. Concrêtement ça me poserai quels pbs et dans quels cas ?
    Je pensais pourtant avoir été clair. Si un jour tu viens a modifier pour une quelconque raison un sprite, que tu le nomme mal ou autre, les lignes "inutile" t'avertirons alors tout de suite. Pour l'instant, ton programme est tres petit et donc l'erreur est tres facilement localisable.
    Mon projet actuel fait 1600 ligne repartie dans 14 fichier different. En cas de bug, je serai de suite ou se situe le bug pour que je puisse le corrigé. Toi, tu postera un message sur le forum.


    Si je met :

    Code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
     
     while (continuer){
     
            while(SDL_PollEvent(&event)){
     
                switch(event.type){
                    case SDL_QUIT:
                        continuer = 0;
                        break;
                    case SDL_KEYDOWN:
                        changerVitesseObjet(1, &positionGuitar, &derniereTouche, &uniteDeplacement, uniteDeplacementMax, uniteAccel, event);
                        break;
                    case SDL_KEYUP:
                        changerVitesseObjet(0, &positionGuitar, &derniereTouche, &uniteDeplacement, uniteDeplacementMax, uniteAccel, event);
                        break;
                }
                SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 0, 0, 0));
                SDL_BlitSurface(imageDeFond, NULL, ecran, &positionFond);
                SDL_BlitSurface(guitar, NULL, ecran, &positionGuitar);
                SDL_Flip(ecran);
            }
     
        }
     
        SDL_FreeSurface(imageDeFond);
        SDL_FreeSurface(guitar);
        SDL_Quit();
     
        return EXIT_SUCCESS;
    }
    La décélération n'est plus prise en compte, fais le test et tu verras
    Extremement etrange ... de toute facon, comme je l'ai dit, ta decceleration est mauvaise, mais tu verra tout ca quant tu maitrisera les timers.

    J'insiste encore sur ce point, c'est while(SDL_PollEvent(&event)) !! Mon explication a été tres clair.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Edit : Oh put*** merci ! c'est le jour et la nuit la fluidité est sans appel, merci de m'expliquer en vulgarisant qu'est ce qui a rendu l'animation plus fluide.
    Moui, y'a un truc qui t'a interresser sur tout ce que je t'ai dit ?

  16. #16
    Membre éclairé Avatar de guitz
    Homme Profil pro
    Webdesigner
    Inscrit en
    Juillet 2006
    Messages
    717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Webdesigner

    Informations forums :
    Inscription : Juillet 2006
    Messages : 717
    Points : 741
    Points
    741
    Par défaut
    C'est quoi un sprite ??

    J'insiste encore sur ce point, c'est while(SDL_PollEvent(&event)) !!
    Calme toi ou ne m'aide pas Jeuneot

  17. #17
    Membre émérite Avatar de SofEvans
    Homme Profil pro
    Développeur C
    Inscrit en
    Mars 2009
    Messages
    1 076
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 076
    Points : 2 328
    Points
    2 328
    Par défaut
    C'est le monde a l'envers

    Je te signal que je n te connais pas personnelement, je ne connais donc pas ton niveau.
    Je peux juste deduire ceci : Tu fais le tutos SDZ et tu en est au chapitre 3, celui sur SDL. Tu est donc censé savoir ce qui a été ecrit précédemment.
    Donc les define tu connais (normalement).

    Personnelement, quant quelqu'un m'explique quelque chose, je prefere qu'il deborde plutot que le contraire. Je te consacre de mon temps et tu te plaint ?????

    De plus, toutes mes remarques sont basé sur des tutos, des forum et mon experience personnel. Je ne pense pas te donner de faux conseil ou des conseil inutile.

    Ton code est petit je te le rappel, et pourtant je vois plein de faille qui pourrait se reveler des prise de tete comme pas quatre quant tu codera plus !

  18. #18
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2008
    Messages
    308
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Février 2008
    Messages : 308
    Points : 622
    Points
    622
    Par défaut
    Citation Envoyé par guitz Voir le message
    Concernant les timer je remet ça a plus tard
    la vitesse c'est juste une distance sur un temps, pour gérer ça convenablement tu dois donc tenir compte du temps... ça n'a rien de compliqué et rien ne t'empêche de sauter 2-3 chapitre de ton tuto pour ale voir comment ça fonctionne!

    Citation Envoyé par guitz Voir le message
    C'est quoi un sprite ??
    merci google...

    Citation Envoyé par guitz Voir le message
    Calme toi ou ne m'aide pas Jeuneot
    un simple merci pour les bons conseils suffirait... tu remarquera un jour que le SDZ est plein d'erreur (ou de manques, bien que ce soit un très bon tuto pour les débutants), chaque astuce ou conseil est bon à prendre, même si ça ne répond pas directement a ta question, et ça pourrais t'éviter de nombreux problèmes. Si SofEvans insiste sur le while, c'est juste que c'est important...

  19. #19
    Membre éclairé Avatar de guitz
    Homme Profil pro
    Webdesigner
    Inscrit en
    Juillet 2006
    Messages
    717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Webdesigner

    Informations forums :
    Inscription : Juillet 2006
    Messages : 717
    Points : 741
    Points
    741
    Par défaut
    Salut Bebaijhi.

    Bon j'ai fait une refonte de mon code en incluant des #define. C'est déjà beaucoup plus propre puisque ca réduit de beaucoup le nbre de paramètres dans deplacerVaisseau(), bien que le mvt soit encore très saccadé. Mais je ne doute pas qu'en incluant, les timers dont je vais lire le chapitre demain et en appliquant certain conseils de SofEvans, ça devrait être bien plus fluide.

    constantes.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
    #ifndef DEF_CONSTANTES
    #define DEF_CONSTANTES
     
        #define HAUTEUR_ECRAN                800
        #define LARGEUR_ECRAN                800
        #define UNIT_DEPLAC_MAX_VAIS         2
        #define UNIT_DEPLAC_MAX_VAIS         2
        #define UNIT_ACCEL_VAIS              0.03
     
     
        struct vaisseau
        {
            int direction;
            int acceleration;
            double uniteDeplacement;
        };
     
    #endif

    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
    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <time.h>
    #include <string.h>
    #include <ctype.h>
    #include <SDL/SDL.h>
    #include <SDL_image.h>
     
    #include "constantes.h"
     
    //void initImages;
    void deplacerVaisseau(int *continuer, int acceleration, SDL_Rect *positionObjet, double *unitDeplacement, SDL_Event event);
     
    int main(int argc, char *argv[])
    {
        SDL_Surface *ecran = NULL, *imgVaisseau = NULL;
        SDL_Rect positionFond, positionVaisseau;
        SDL_Event event;
     
        int continuer = 1;
     
        struct vaisseau vaisseau1;
            vaisseau1.direction = 0;
            vaisseau1.acceleration = 0;
            vaisseau1.uniteDeplacement = 0;
     
        //positionFond.x = 0; positionFond.y = 0;
     
        SDL_Init(SDL_INIT_VIDEO);
        SDL_WM_SetIcon(IMG_Load("images/sdl_icone.bmp"), NULL);
        ecran = SDL_SetVideoMode(LARGEUR_ECRAN, HAUTEUR_ECRAN, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
        SDL_WM_SetCaption("Casse briques", NULL);
        //imageDeFond = IMG_Load("images/hendrix.bmp");
        imgVaisseau = IMG_Load("images/vaisseau.png");
        //positionCurseur.x = ecran->w / 2 - imgCurseur->w / 2;
        positionVaisseau.x = 0;
        positionVaisseau.y = HAUTEUR_ECRAN - 80 ;
     
        SDL_EnableKeyRepeat(50, 50);
     
        while (continuer){
     
            SDL_PollEvent(&event);
     
            switch(event.type){
                case SDL_QUIT:    // arrêter le jeu
                    continuer = 0;
                    break;
                case SDL_KEYDOWN:
                    deplacerVaisseau(&continuer, 1, &positionVaisseau, &(vaisseau1.uniteDeplacement), event);
                    break;
                case SDL_KEYUP:
                    deplacerVaisseau(&continuer, 0, &positionVaisseau, &(vaisseau1.uniteDeplacement), event);
                    break;
            }
     
            SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 105, 105, 105));
            //SDL_BlitSurface(imageDeFond, NULL, ecran, &positionFond);
            SDL_BlitSurface(imgVaisseau, NULL, ecran, &positionVaisseau);
            SDL_Flip(ecran);
     
            //fprintf(stderr, "ratio = %f\n", ratioXCursTN);
     
        }
     
        //SDL_FreeSurface(imageDeFond);
        SDL_FreeSurface(imgVaisseau);
        SDL_Quit();
     
        return EXIT_SUCCESS;
    }
     
    void deplacerVaisseau(int *continuer, int acceleration, SDL_Rect *positionObjet, double *unitDeplacement, SDL_Event event){
     
        switch(event.key.keysym.sym)
            {
                    case SDLK_RIGHT: // Flèche droite
                        if((*positionObjet).x + *unitDeplacement <= LARGEUR_ECRAN)
                            (*positionObjet).x += *unitDeplacement;
                        break;
                    case SDLK_LEFT: // Flèche gauche
                        (*positionObjet).x -= *unitDeplacement;
                        break;
                    case SDLK_ESCAPE: // arrêter le jeu
                        *continuer = 0;
                        break;
            }
     
        if(acceleration)
        {
            if(*unitDeplacement < UNIT_DEPLAC_MAX_VAIS){
                *unitDeplacement += UNIT_ACCEL_VAIS;
        }
     
        }else{
            if((*unitDeplacement - UNIT_ACCEL_VAIS) > 0){
                *unitDeplacement -= UNIT_ACCEL_VAIS;
                if(*unitDeplacement < UNIT_ACCEL_VAIS)
                        *unitDeplacement = 0;
     
            }
            //fprintf(stderr, "%f\n", *unitDeplacement);
        }
    }
    Je vous tient au courant de la suite du dev de mon tout premier projet en C

  20. #20
    Membre émérite Avatar de SofEvans
    Homme Profil pro
    Développeur C
    Inscrit en
    Mars 2009
    Messages
    1 076
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 076
    Points : 2 328
    Points
    2 328
    Par défaut
    Citation Envoyé par guitz Voir le message
    Salut Bebaijhi.

    Bon j'ai fait une refonte de mon code en incluant des #define. C'est déjà beaucoup plus propre puisque ca réduit de beaucoup le nbre de paramètres dans deplacerVaisseau(), bien que le mvt soit encore très saccadé. Mais je ne doute pas qu'en incluant, les timers dont je vais lire le chapitre demain et en appliquant certain conseils de SofEvans, ça devrait être bien plus fluide.

    Plusieurs remarques :

    Les timers ne sont pas une solution miracle, ils n'ont (presque) qu'une seule utilité : faire en sorte que quelque soit la machine, ton jeu tournera aussi vite.

    Pour l'instant, ton jeu tournera a la vitesse de ta machine : cela peut entrainer effectivement des probleme de fluidité, mais pas si important que ca.

    Le probleme de ta fluidite actuelle est celle que je t'ai deja expliqué : il faut utiliser SDL_DisplayFormat();


    Tu as mis la definition de la structure de vaisseau dans constante.h ?

    Pour l'instant, pourquoi pas. Mais le mieux serait de faire un vaisseau.c et un vaisseau.h.

    Autre remarque : utilise un typedef pour eviter de re-ecrire struct vaisseau a chaque fois :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    typedef struct vaisseau vaisseau;
    A mettre juste avant la structure (pas obliger mais bon ...).

    Pour la structure vaisseau, je trouve qu'elle est incomplete : si tu regarde dans ton main, tu as encore une SDL_Surface ainsi qu'un SDL_Rect qui caracterise ton vaisseau.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    typedef struct vaisseau vaisseau
    struct vaisseau
    {
        SDL_Surface *image;
        SDL_Rect position;
     
        int direction;
        int acceleration;
        double uniteDeplacement;
    };
    serait plus "logique".

    Bon courage pour la suite

Discussions similaires

  1. image à la vitesse du rafraichissement
    Par arbre69 dans le forum Projets
    Réponses: 6
    Dernier message: 04/10/2012, 22h03
  2. [debutant] vitesse de rafraichissement directX
    Par loup_precaire dans le forum DirectX
    Réponses: 2
    Dernier message: 13/08/2010, 21h08
  3. Problème vitesse de rafraichissement sous sdl
    Par sieuzac dans le forum SDL
    Réponses: 16
    Dernier message: 31/05/2007, 14h59
  4. Vitesse de rafraichissement des données
    Par StarMusic dans le forum Bases de données
    Réponses: 2
    Dernier message: 30/09/2005, 10h20
  5. Probleme de rafraichissement d'un BDGrid
    Par marmotte dans le forum Bases de données
    Réponses: 10
    Dernier message: 28/05/2004, 18h07

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