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 :

Ma fonction en C pour afficher et animer mon sprite


Sujet :

SDL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Août 2005
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 29
    Par défaut Ma fonction en C pour afficher et animer mon sprite
    Bonjour.

    Je m'amuse avec C et SDL à refaire un "petit" street fighter pour me forger à ces languages.

    Au début je mettais tout mon code dans le main.c histoire de tester un peu.

    Maintenant, je suis en train de créer mes fonctions pour animer les personnages, les deplacer... et que j'inclu dans le main.

    Et la, depuis... que des erreurs.

    Peut etre a cause des pointeurs que j ai galéré pour ne plus avoir d erreur lors de la compilation, autre chose ??

    Voici le prototype de ma fonction pour afficher Ryu:


    void ryuAnim(int *nom, SDL_Surface *ecran, SDL_Rect *player_position);

    Ma fonction animRyu()

    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
     
     
    void ryuAnim(int *nom, SDL_Surface *ecran, SDL_Rect *player_position)
    {
        int tempsPrecedent = 0, tempsActuel = 0;
        int i = 1;
     
     
     
    // 1 = Animation perso fixe
       // if(nom == 0)
       // {
            //SDL_Rect player_position;
           // player_position.y = py;
            //player_position.x = px;
     
                //initialisation des surfaces
                SDL_Surface *player_iddle_1 = NULL;
                SDL_Surface *player_iddle_2 = NULL;
                SDL_Surface *player_iddle_3 = NULL;
                SDL_Surface *player_iddle_4 = NULL;
     
                //Chargement des sprites
                player_iddle_1 = IMG_Load("img/ryu_idle_1.png");
                    if(player_iddle_1 == IMG_Load("img/ryu_idle_1.png") == -1)
                        {
                        fprintf(stderr, "Erreur d'initialisation de la SDL : %s\n", SDL_GetError()); // Ecriture de l'erreur
                        exit(EXIT_FAILURE); // On quitte le programme
                        }
                    else
                        {
                        printf("image 1 bien chargee \n");
                        }
                player_iddle_2 = IMG_Load("img/ryu_idle_2.png");
                player_iddle_3 = IMG_Load("img/ryu_idle_3.png");
                player_iddle_4 = IMG_Load("img/ryu_idle_4.png");
     
     
                //transparence de l image
                SDL_SetColorKey(player_iddle_1, SDL_SRCCOLORKEY, SDL_MapRGB(player_iddle_1->format, 128, 128, 128));
                SDL_SetColorKey(player_iddle_2, SDL_SRCCOLORKEY, SDL_MapRGB(player_iddle_2->format, 128, 128, 128));
                SDL_SetColorKey(player_iddle_3, SDL_SRCCOLORKEY, SDL_MapRGB(player_iddle_3->format, 128, 128, 128));
                SDL_SetColorKey(player_iddle_4, SDL_SRCCOLORKEY, SDL_MapRGB(player_iddle_4->format, 128, 128, 128));
     
                // Animation
     
     
     
                tempsActuel = SDL_GetTicks();
                if(tempsActuel - tempsPrecedent > 150)
                    {
                    tempsPrecedent = tempsActuel;
                    if(i > 4)
                    {
                    i = 1;
                    }
     
                    SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 255, 255, 255));
     
                    if(i == 1)
                    {
                    SDL_BlitSurface(player_iddle_1, NULL, ecran, player_position);
                    SDL_Flip(ecran);
                        if(SDL_BlitSurface(player_iddle_1, NULL, ecran, player_position) < 0)
                            {
                            fprintf(stderr, "Erreur fonction affichage : %s\n", SDL_GetError()); // Ecriture de l'erreur
                            exit(EXIT_FAILURE); // On quitte le programme
                            }
                    }
     
     
                    if(i == 2)
                    {
                    SDL_BlitSurface(player_iddle_2, NULL, ecran, player_position);
                    SDL_Flip(ecran);
                    }
     
                    if(i == 3)
                    {
                    SDL_BlitSurface(player_iddle_3, NULL, ecran, player_position);
                    SDL_Flip(ecran);
                    }
     
                    if(i == 4)
                    {
                     SDL_BlitSurface(player_iddle_4, NULL, ecran, player_position);
                     SDL_Flip(ecran);
                    }
                    i++;
                    }
     
     
            SDL_FreeSurface(player_iddle_1);
            SDL_FreeSurface(player_iddle_2);
            SDL_FreeSurface(player_iddle_3);
            SDL_FreeSurface(player_iddle_4);
        //}
     
     
    }

    Pour appeler ma fonction dans le main

    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 <SDL/SDL.h>
    #include <SDL/SDL_image.h>
    #include "anim_ryu.h"
    #include "ecran.h"
     
    int main(int argc, char *argv[])
    {
        //Variable d 'evenment
        SDL_Event event;
     
        //1 le programme continue 0 on quitte
        int continuer = 1;
     
     
        SDL_Surface *ecran = NULL; // Creation de l'ecran
     
        SDL_Init(SDL_INIT_VIDEO);
     
         ecran = SDL_SetVideoMode(800, 600, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
         void *pEcran = &ecran;
     
       //initialisation de la position du joueur
        SDL_Rect player_position;
        player_position.x = 220;
        player_position.y = 220;
     
        // J avai essayer de passer x et y a la fonction sans reussite
        SDL_Rect *pointeurPosition = &player_position;
     
        // On initialise la repetition des touches au clavier
        SDL_EnableKeyRepeat(10,10);
     
     
     
        while(continuer)
        {
     
        SDL_PollEvent(&event);
     
            switch(event.type)
            {
     
            case SDL_QUIT:
            continuer = 0;
            break;
     
            case SDL_KEYDOWN:
                switch(event.key.keysym.sym)
                {
                    case SDLK_ESCAPE:
                    continuer = 0;
                    break;
     
                    case SDLK_RIGHT:
     
                    break;
     
                    case SDLK_LEFT:
     
                    break;
                }
            }
                    int x=200; // ca c est des variables que j ai essayé de passer
                    int y = 200;// idem
                    int nomanim = 0; // le type d animation a afficher
                    int *pNomanim = &nomanim;
     
     
                  ryuAnim(pNomanim, pEcran, pointeurPosition);
     
     
               }
     
     
        }
     
        return EXIT_SUCCESS;
     
        SDL_Quit();
    }

    J ai pas affiché tout mes includes...

    Voila ce que code::block m'affiche

    Project : SDL Application
    Compiler : GNU GCC Compiler (called directly)
    Directory : C:\Documents and Settings\proprietaire\Mes documents\C C++\C\SDL\TEST anims evenements\
    --------------------------------------------------------------------------------
    Checking for existence: sdlapp.exe
    Executing: "C:\Documents and Settings\proprietaire\Mes documents\C C++\C\SDL\TEST anims evenements\sdlapp.exe" (in .)
    Process terminated with status 1 (0 minutes, 0 seconds)
    0 errors, 0 warnings

    Juste avant de poster le message il me disait que y'avai un probleme avec les pointeurs.

    Ce que j'ai fai dans les blit de ma fonction, j'ai mis player_position au lieu de &player_position

    Le programme se lance et se quitte imméditement apres la compilation.

    Si j'enleve l'appel de la fonction ryuAnim la fenetre noire s'affiche correctement et j'appui sur ECHAP pour quitter le programme

    En console j'utilisai sans probleme les fonctions avec pointeur mais là....

  2. #2
    Membre éprouvé
    Lycéen
    Inscrit en
    Juillet 2007
    Messages
    148
    Détails du profil
    Informations personnelles :
    Âge : 34

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Juillet 2007
    Messages : 148
    Par défaut
    Il y a plein de petites erreur (c'ets pas ça qui doit faire bugger, mais c'ets toujours bon à corriger) :

    - ecran est déjà un pointeur, pas besoin de faire un pointeur dessus.

    - Au lieu de passer int *pNomanim = &nomanim;, mets directement &nomanim, ça marche aussi, et ça évite de creer un pointeur qui sert à rien

    - Tu ne devrai pas charqer et décharger les images à chaque animation, charge les tout au début, puis vide les tout à la fin. Tu peux faire par exemple un tableau de SDL_Surface à 4 cases, un pour chaque frame, qui te permettrai de faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
                    SDL_BlitSurface(player_iddle[i], NULL, ecran, player_position);
                    SDL_Flip(ecran);
                        if(SDL_BlitSurface(player_iddle[i], NULL, ecran, player_position) < 0)
                            {
                            fprintf(stderr, "Erreur fonction affichage : %s\n", SDL_GetError()); // Ecriture de l'erreur
                            exit(EXIT_FAILURE); // On quitte le programme
                            }
     
     
                    i++;
    (et encore, je doute du fait de mettre une 2e fois le SDL_BlitSurface(player_iddle[i], NULL, ecran, player_position) pour tester sa validité).

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Août 2005
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 29
    Par défaut
    Les erreurs :

    anim_ryu.c:75: warning: passing arg 4 of `SDL_UpperBlit' from incompatible pointer type
    anim_ryu.c:76: warning: passing arg 1 of `SDL_Flip' from incompatible pointer type



    J'avai oublié la boucle pour afficher l image

    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
     
     
    while(tempsActuel + 1000 > SDL_GetTicks())
                {
                if(tempsActuel - tempsPrecedent > 150)
                    {
                    tempsPrecedent = tempsActuel;
                    if(i > 4)
                    {
                    i = 1;
                    }
     
                    SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 255, 255, 255));
     
                    if(i == 1)
                    {
                    SDL_BlitSurface(player_iddle_1, NULL, ecran, &player_position);
                    SDL_Flip(&ecran);
                        if(SDL_BlitSurface(player_iddle_1, NULL, ecran, player_position) < 0)
                            {
                            fprintf(stderr, "Erreur fonction affichage frame1 : %s\n", SDL_GetError()); // Ecriture de l'erreur
                            exit(EXIT_FAILURE); // On quitte le programme
                            }
    Appel de la fonction (comme tu m a dis de le faire)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
     
    ryuAnim(&nomanim, &ecran, &pointeurPosition);
    Donc les pointeurs sont incompatibles si j'ai bien compris?
    Pourquoi ?


    fearyourself, je prends tres bien les critiques c'est comme ca que l'on progresse et je t'en remercie


    J'essai justement de comprendre mes erreurs et pas de recopier une correction, j'espere y arriver petit à petit

  4. #4
    Membre éprouvé
    Lycéen
    Inscrit en
    Juillet 2007
    Messages
    148
    Détails du profil
    Informations personnelles :
    Âge : 34

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Juillet 2007
    Messages : 148
    Par défaut
    Il faut mettre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ryuAnim(&nomanim, ecran, &player_position);
    Car ecran est un pointeur, et pas besoin non plus de creer un pointeur juste pour faire passer player_position, autant directement filer l'adresse à la fonction.

  5. #5
    Expert confirmé

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Par défaut
    Citation Envoyé par schtek2
    J'avai oublié la boucle pour afficher l image
    Oui mais ce n'est pas bon de bloquer le programme dans la fonction de rendu, faut faire le rendu le plus rapidement possible et laisser le programme gérer le reste des événements.

    Regarde les tutoriels sur ce site pour voir un peu comment nous faisons.

    http://jeux.developpez.com/tutoriels/#a_sdl

    fearyourself, je prends tres bien les critiques c'est comme ca que l'on progresse et je t'en remercie
    C'est bien, c'est la bonne attitude à avoir mais on m'a déjà dit que je répondais de facon un peu crue alors je prends les précautions

    Jc

  6. #6
    Expert confirmé

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Par défaut
    Bien le bonjour,

    Quelques remarques :
    Citation Envoyé par schtek2
    Je m'amuse avec C et SDL à refaire un "petit" street fighter pour me forger à ces languages.
    C'est trop compliqué pour se forger à ces langages. Il faudrait mieux faire quelque chose de plus simple. Mais de temps en temps, la complexité fait avancer les choses... A toi de voir !

    Les remarques qui suivent sont directes et peut-être parfois crue. Je ne souhaite pas te descendre mais je vais simplement dire ce que je pense du code. Espérant que tu le prendras comme cela, regardons le code !

    - Beaucoup d'erreurs ou de choses dangereuses dans ton main :

    - Où sont les tests pour ces appels ? Il faut tester le retour des fonctions SDL !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
        SDL_Init(SDL_INIT_VIDEO);
     
         ecran = SDL_SetVideoMode(800, 600, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);

    Pareil pour ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
        SDL_PollEvent(&event);
     
            switch(event.type)
    voir http://jeux.developpez.com/faq/sdl/?...NTS_repetition

    - Ajoute un cas default aussi dans tes switch même avec seulement un petit break à la fin...

    - Ici tu fais ceci comme appel :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
                  ryuAnim(pNomanim, pEcran, pointeurPosition);
    or ton prototype est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    void ryuAnim(int *nom, SDL_Surface *ecran, SDL_Rect *player_position);
    Tu as donc un problème de typage pour le 2ème paramètre. Tu passes un SDL_Surface**...


    - Cela devrait être dans l'autre ordre non ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
        return EXIT_SUCCESS;
     
        SDL_Quit();

    Passons à ta fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
                //Chargement des sprites
                player_iddle_1 = IMG_Load("img/ryu_idle_1.png");
                    if(player_iddle_1 == IMG_Load("img/ryu_idle_1.png") == -1)
                        {
                        fprintf(stderr, "Erreur d'initialisation de la SDL : %s\n", SDL_GetError()); // Ecriture de l'erreur
                        exit(EXIT_FAILURE); // On quitte le programme
                        }
                    else
                        {
                        printf("image 1 bien chargee \n");
                        }
    - Depuis quand est-ce qu'on teste le retour d'une fonction à sa 2ème exécution ? Et que fais-tu de la fuite de mémoire occasionnée par le premier appel ?

    - Il manque des tests après pour ces appels :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
                player_iddle_2 = IMG_Load("img/ryu_idle_2.png");
                player_iddle_3 = IMG_Load("img/ryu_idle_3.png");
                player_iddle_4 = IMG_Load("img/ryu_idle_4.png");
    Aucune preuve que les images sont bien chargées, le problème pourrait venir d'ici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
                //transparence de l image
                SDL_SetColorKey(player_iddle_1, SDL_SRCCOLORKEY, SDL_MapRGB(player_iddle_1->format, 128, 128, 128));
                SDL_SetColorKey(player_iddle_2, SDL_SRCCOLORKEY, SDL_MapRGB(player_iddle_2->format, 128, 128, 128));
                SDL_SetColorKey(player_iddle_3, SDL_SRCCOLORKEY, SDL_MapRGB(player_iddle_3->format, 128, 128, 128));
                SDL_SetColorKey(player_iddle_4, SDL_SRCCOLORKEY, SDL_MapRGB(player_iddle_4->format, 128, 128, 128));
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
                // Animation
                tempsActuel = SDL_GetTicks();
                if(tempsActuel - tempsPrecedent > 150)
                    {
                    tempsPrecedent = tempsActuel;
                    if(i > 4)
                    {
                    i = 1;
                    }
     
                    SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 255, 255, 255));
    i, TempsActuel et tempsPrecedent sont des variables locales et donc perdent leur valeur à chaque fin de fonction. Il te faut une structure contenant ces éléments pour les stocker convenablement.

    Ici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
                    if(i == 1)
                    {
                    SDL_BlitSurface(player_iddle_1, NULL, ecran, player_position);
                    SDL_Flip(ecran);
                        if(SDL_BlitSurface(player_iddle_1, NULL, ecran, player_position) < 0)
                            {
                            fprintf(stderr, "Erreur fonction affichage : %s\n", SDL_GetError()); // Ecriture de l'erreur
                            exit(EXIT_FAILURE); // On quitte le programme
                            }
                    }
    - Même question sur le test du deuxième SDL_BlitSurface....
    - On ne fait pas un SDL_Flip à chaque SDL_BlitSurface mais à la fin du rendu de toute la scène...

    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
     
                    if(i == 2)
                    {
                    SDL_BlitSurface(player_iddle_2, NULL, ecran, player_position);
                    SDL_Flip(ecran);
                    }
     
                    if(i == 3)
                    {
                    SDL_BlitSurface(player_iddle_3, NULL, ecran, player_position);
                    SDL_Flip(ecran);
                    }
     
                    if(i == 4)
                    {
                     SDL_BlitSurface(player_iddle_4, NULL, ecran, player_position);
                     SDL_Flip(ecran);
                    }
                    i++;
                    }
    - i ne pourra jamais valoir autre chose que 0 ou 1 donc ce code ne sera jamais exécuter. Préferez un switch ou le tableau que propose bogoss

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
            SDL_FreeSurface(player_iddle_1);
            SDL_FreeSurface(player_iddle_2);
            SDL_FreeSurface(player_iddle_3);
            SDL_FreeSurface(player_iddle_4);
    - Il ne faut pas charger et libérer la mémoire à chaque rendu, le faire une fois et le stocker quelque part (dans la structure qui représente Ryu peut-être ?)

    Il faut faire attention à ce qu'on fait et programmer doucement.
    Jc

Discussions similaires

  1. Réponses: 1
    Dernier message: 14/08/2009, 12h19
  2. Probleme avec IE pour afficher une animation flash
    Par the magic developer dans le forum Flash
    Réponses: 0
    Dernier message: 24/07/2009, 16h29
  3. Réponses: 1
    Dernier message: 18/07/2006, 23h38
  4. Réponses: 9
    Dernier message: 17/02/2006, 11h04
  5. Réponses: 1
    Dernier message: 22/11/2004, 10h46

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