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èmes lors de manipulations de fonctions


Sujet :

SDL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 67
    Par défaut Problèmes lors de manipulations de fonctions
    Bonsoir tout le monde! (enfin surtout Softevans puisque c'est lui qui aide tout le monde on dirai ! XD)

    Bon alors, pour faire simple:
    j'ai une valeur pour une int a qui vaut 0 au départ.
    Je l'envoie dans une fonction g et selon la manipulation de l'utilisateur, elle renvoie à l'int 0 ou 1.
    Selon la valeur de cet int, une autre fonction h, va manipuler par rapport à l'int a, une nouvelle valeur selon ce que fait l'utilisateur : soit -1 ou 0.

    On est bien d'accord, théoriquement, ça devrai marcher? (sinon le problème vient de là! XD)

    Passons maintenant à ce que j'ai codé :
    voici une partie de la fonction "main" qui va appeler la fonction g et 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
    if(event.button.button == SDL_BUTTON_RIGHT)
                        objet = ouvrirInventaire(ecran, objet); //Si la valeur renvoyé par la fonction est différent de 0, c'est donc qu'on a un objet:
     
                    if(objet == 1) //si la valeur de l'objet est de 1, alors c'est l'objet FEU qui est utilisé
                    {
                        oSouris = IMG_Load("feu.png"); //On charge l'icone feu qui va suivre la souris
                        objet = utiliserObjet(objet,lieux); //On teste ce que fait le joueur avec l'objet, et on renvoie la valeure de l'objet pour connaître son état
                    }
     
                    if(objet == -1)
                    {
                        okFeu = IMG_Load("okFEU.png");
                        positionOkFeu.x = 420;
                        positionOkFeu.y = 140;
                    }

    la fonction g renvoie la valeur au paramètre objet (pas besoin de l'afficher, j'ai vérifié, et le problème ne vient pas de cette fonction)

    et maintenant le code de la fonction h (complète)

    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
    int utiliserObjet(int objet, int lieux)
    {
        SDL_Surface *okFeu = NULL;
        SDL_Rect positionOkFeu;
     
        int continuer = 1;
        SDL_Event event;
     
        while(continuer)
        {
            SDL_WaitEvent (&event);
     
            switch(event.type)
            {
                if (lieux == 0 && objet == 1) //Si le lieux est celui du départ
                {
                        case SDL_MOUSEBUTTONDOWN:
                            if((event.button.button == SDL_BUTTON_LEFT) &&(event.button.x <= 360)&&(event.button.x >= 320)&&(event.button.y <= 290)&&(event.button.y >= 260)) //Si on clique gauche sur la pancarte
                                objet = -1; //on n'utilise plus l'objet, et on le retire
     
                            if((event.button.button == SDL_BUTTON_LEFT) &&(event.button.x >= 360)&&(event.button.x <= 320)&&(event.button.y >= 290)&&(event.button.y <= 260 || (event.button.button == SDL_BUTTON_RIGHT)) //si on clique gauche en dehors de la carte
                                objet = 0;
                    }
                }
        }
     
        return objet;
    }

    J'aimerai en fait, que objet soit égale soit à 0 ou -1 après cette fonction pour qu'ensuite la fonction "main" puisse faire apparaître une image (pour montrer que ça a marché).

    Mais lorsqu'elle appelle cette fonction, la fenêtre reste bloqué à ouvrirInventaire, il m'est impossible de sortir de l'inventaire avec le clique droit ou alors le jeu plante complètement (souris ne bouge plus), mais sinon on peut balader la souris dans l'inventaire.

    Merci pour votre aide et bonne soirée

    Je tiens à préciser que le programme marche parfaitement sans l'appel de la fonction h!

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

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 084
    Par défaut
    Bonsoir,

    En effet, elle risque de chercher longtemps les bonnes valeurs ta fonction

    Je n'ai pas examiner en profondeur ton code mais on peut deja voir une erreur de structure dans ta structure switch.
    Quand tu fait fais un switch, tu dois avoir obligatoirement une succession de case, souvent un default ( généralement il faut le mettre ).
    Dans ton test switch, tu met une autre condition, et ça c'est pas bon.

    Ah, je n'avais pas vu la deuxième erreur, tu ne mets jamais ta variable continuer a 0, d'où la boucle infini.

    Une troisième apparait pendant que je fais la correction, j'ai nommée l'oublie de parenthèse q^_^p

    Une légère ambiguïté aussi :

    if .... (event.button.x <= 360) ...
    objet = -1;

    if... (event.button.x >= 360) ...
    objet = 0;

    Et si event.button.x == 360, quelle action voudrait tu faire ?

    Bref, voici la première correction : J'ai uniquement corrigé avec mes remarque précédente :

    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
     
    int utiliserObjet(int objet, int lieux)
    {
        SDL_Surface *okFeu = NULL;
        SDL_Rect positionOkFeu;
     
        int continuer = 1;
        SDL_Event event;
     
        while(continuer)
        {
            SDL_WaitEvent (&event);
            switch(event.type)
            {
                case SDL_MOUSEBUTTONDOWN:
                    if (lieux == 0 && objet == 1) //Si le lieux est celui du départ
                    {
                            if((event.button.button == SDL_BUTTON_LEFT) &&(event.button.x <= 360)&&(event.button.x >= 320)&&(event.button.y <= 290)&&(event.button.y >= 260)) //Si on clique gauche sur la pancarte
                                objet = -1; //on n'utilise plus l'objet, et on le retire
     
                            if((event.button.button == SDL_BUTTON_LEFT) &&(event.button.x >= 360)&&(event.button.x <= 320)&&(event.button.y >= 290)&&(event.button.y <= 260) || (event.button.button == SDL_BUTTON_RIGHT)) //si on clique gauche en dehors de la carte
                                objet = 0;
     
                            // Je pense que ici est la bonne position, car d'apres ce que je vois, si on rentre dans cette condition
                            // on affecte objet et on sort
                            continuer = 0;
                    }
                    // Termine un case par un break, meme si ici, de par le fait que l'on est qu'une seule condition, il n'est pas indispensable
                    break;
            }
        }
     
        return objet;
    }

    Voici maintenant un autre code qui fait exactement la même chose, mais je pense qu'il est plus clair :

    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
     
    int utiliserObjet(int objet, int lieux)
    {
        SDL_Surface *okFeu = NULL;
        SDL_Rect positionOkFeu;
     
        int continuer = 1;
        SDL_Event event;
     
        while(continuer)
        {
            SDL_WaitEvent (&event);
            switch(event.type)
            {
                case SDL_MOUSEBUTTONDOWN:
                    if (lieux == 0 && objet == 1) //Si le lieux est celui du départ
                    {
                        switch (event.button.button)
                        {
                            case SDL_BUTTON_LEFT:
                                // Pour le clique gauche, soit on est dans la pancarte, soit on est dehors  ->
                                if ((event.button.x <= 360) && (event.button.x >= 320)&&(event.button.y <= 290)&&(event.button.y >= 260)) //Si on clique gauche sur la pancarte
                                    objet = -1;
                                else
                                    objet = 0;
     
                                break;
                            case SDL_BUTTON_RIGHT:
                                // Pour le clique droit, on ne se pose pas de question ^^
                                objet = 0;
                                break;             
                        }
                        continuer = 0;
                    }
                    // Termine un case par un break, meme si ici, de par le fait que l'on est qu'une seule condition, il n'est pas indispensable
                    break;
            }
        }
     
        return objet;
    }
    Voila, tout est dans les commentaire.
    Je n'ai pas tester ces code mais il devrait fonctionner.
    J'espère que je n'ai pas dériver et répondu a cote de la plaque.

    Bon courage pour la suite

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 67
    Par défaut
    J'ai toujours le même problèmes, malgré ta correction de mes énormités! (incroyable qu'à force ces choses là deviennent si insignifiantes) XD

    Par contre, je n'ai pas compris pourquoi
    "Dans ton test switch, tu met une autre condition, et ça c'est pas bon. "
    ce n'est pas bon?

    J'ai corrigé avec tes explications, voici la fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    int utiliserObjet(int objet, int lieux)
    {
        SDL_Surface *okFeu = NULL;
        SDL_Rect positionOkFeu;
     
        int continuer = 1;
        SDL_Event event;
     
        while(continuer)
        {
            SDL_WaitEvent (&event);
     
            switch(event.type)
            {
                if (lieux == 0 && objet == 1) //Si le lieux est celui du départ
                {
                        case SDL_MOUSEBUTTONDOWN:
                            if((event.button.button == SDL_BUTTON_LEFT) &&(event.button.x <= 360)&&(event.button.x >= 320)&&(event.button.y <= 290)&&(event.button.y >= 260)) //Si on clique gauche sur la pancarte
                                    objet = -1; //on n'utilise plus l'objet, et on le retire
     
                            if(((event.button.button == SDL_BUTTON_LEFT) &&(event.button.x > 360)&&(event.button.x < 320)&&(event.button.y > 290)&&(event.button.y < 260)) || (event.button.button == SDL_BUTTON_RIGHT)) //si on clique gauche en dehors de la carte
                                    objet = 0;
     
                        break;
                    }
                continuer = 0;
     
                default:
                break;
                }
        }
     
        return objet;
    }
    Je n'ai pas pris l'un de tes codes, car en fait le test que fait le programme c'est de savoir si le joueur a cliqué avec le bouton de la souris sur une pancarte, et donc si il clique à côté ou si il fait un clique droit, ça annule l'objet qu'il tenait en main (d'où le "objet = 0;") par contre, si il clique sur la pancarte, il va utiliser l'objet donc objet = -1;

    Mais, j'ai peur qu'en mettant le "continuer = 0" après ces deux if, qu'ils le lisent "si il fait autre chose que ces deux if, alors on annule la boucle" mais le joueur peut déplacer sa souris sans cliquer, donc il annulera la boucle directement après sa lecture, non?

    Mais même en remettant continuer = 0; sous les if, ça ne marche pas... et le debugueur n'a trouvé aucun problème :/

    Merci encore une fois pour ton aide

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

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 084
    Par défaut
    Salut,

    Désolé pour le switch case s je t'ai parut impératif. En fait, on m'a appris ( en DUT ) qu'après un switch, il y avait obligatoirement des case et rien d'autre.

    Il y a un petit ( gros ) problème avec ton code. Tu lui dit de sortir de ta boucle (continuer = 0) lorsque tu détecte .... un événement.
    Par conséquent, il sortira dès que tu bougera la souris (événement MOUSEMOTION envoyé).
    Il faut donc lui dire de sortir de la boucle uniquement lorsque tu detecte un événement de type MOUSEBUTTONDOWN car hormis le bouton du milieu, dès que tu clic, tu affecte objet et tu sort.
    Si tu veux être vraiment rigoureux et contrôler ce que tu fais, test le code suivant :

    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
     
    int utiliserObjet(int objet, int lieux)
    {
        SDL_Surface *okFeu = NULL;
        SDL_Rect positionOkFeu;
     
        int continuer = 1;
        SDL_Event event;
     
        while(continuer)
        {
            // Ici, on recupere un evenement
            SDL_WaitEvent (&event);
            switch(event.type)
            {
                // On ne le traitera que si il s'agit d'un appui sur le bouton
                case SDL_MOUSEBUTTONDOWN:
                    // Condition pour que le clic soit valide
                    if (lieux == 0 && objet == 1)
                    {
                        switch (event.button.button)
                        {
                            // On gere le clique gauche
                            case SDL_BUTTON_LEFT:
                                if ((event.button.x <= 360) && (event.button.x >= 320)&&(event.button.y <= 290)&&(event.button.y >= 260)) 
                                    objet = -1;
                                else
                                    objet = 0;
     
                                continuer = 0;
                                break;
     
                            // On gere le clic droit
                            case SDL_BUTTON_RIGHT:
     
                                objet = 0;
                                continuer = 0;
     
                                break;   
     
                                // continuer = 0 est a l'interieur de chase case afin de ne pas sortir si on clic sur le bouton du milieu          
                        }
     
                    }
                    // Termine un case par un break, meme si ici, de par le fait que l'on est qu'une seule condition, il n'est pas indispensable
                    break;
            }
        }
     
        return objet;
    }

    Test vraiment ce code s'il te plait et lis les commentaire.
    Il devrait faire exactement ce que tu m'as décrit. Après, s'il ne fait pas ce que tu veux, décrit moi mieux ton problème et donne moi plus de donné.


    Sinon, si il y a encore un problème, je voudrais savoir :

    *si t'a fonction renvoie bien -1 ou 0 ( affiche le résultat avec cout dans ta sortie texte)
    *si ta fonction renvoie toujours le même résultat quelque soit l'action que tu fais ?
    *si ta fonction sort bien uniquement lorsqu'il y a un clic et pas avant ?
    *si elle fait planter le programme ?

    Déjà, si on a ces élément de réponse, on devrait pouvoir mieux cibler l'origine du problème.

    A toute !


    qO-Op

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 67
    Par défaut
    J'ai copié collé le code que tu m'as proposé, et ça fait quand même planté le programme. Les tests que tu m'as demandé de faire ne peuvent pas être réalisé du coup.

    Mais je crois savoir où vient le programme, en fait, je ne crois pas que ça vient de ma fonction "utiliserObjet".

    J'aimerai que tu me dises ce que tu penses de la fonction qui l'appelle :

    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_MOUSEBUTTONDOWN:
                      if(event.button.button == SDL_BUTTON_RIGHT)
                        objet = ouvrirInventaire(ecran, objet); //Si la valeur renvoyé par la fonction est différent de 0, c'est donc qu'on a un objet:
     
                    if(objet == 1) //si la valeur de l'objet est de 1, alors c'est l'objet FEU qui est utilisé
                    {
                        oSouris = IMG_Load("feu.png"); //On charge l'icone feu qui va suivre la souris
                        objet = utiliserObjet(objet,lieux); //On teste ce que fait le joueur avec l'objet, et on renvoie la valeure de l'objet pour connaître son état
                    }
     
                    if(objet == -1)
                    {
                        okFeu = IMG_Load("okFEU.png");
                        positionOkFeu.x = 420;
                        positionOkFeu.y = 140;
                    }
    On est bien d'accord, si on lit ligne par ligne, le code va appeler une première fonction "ouvrirInventaire" avec le clique droit, et cette fonction va lui renvoyer une valeur pour objet. MAIS! au moment où la fonction va être utilisé, un test va se faire pour savoir si l'objet vaut désormais 1 ou pas, normalement, une fois que l'objet a pris le return de ouvrirInventaire, il change, et ce return n'est appliqué qu'une fois que le joueur a cliqué sur le bouton droit de la souris. Mais est-ce que le code rentre pas en conflit car il fais le test de l'objet tout en étant dans la fonction "ouvrirInventaire" [car c'est une fois dans ouvrirInventaire que l'objet prend 1).

    Je sais pas si t'as compris, et selon moi ça ne devrai pas être ça l'erreur, mais là je sèche totalement...

    (après relecture je jette mon hypothèse, mais on ne sait jamais...)

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

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 084
    Par défaut
    Honnêtement, ton erreur demeure pour l'instant un mystère.

    Juste un truc, remplace

    if (lieux == 0 && objet == 1)

    par

    if ((lieux == 0) && (objet == 1))

    J'aimerai savoir deux trois chose :

    Si tu commente l'appel a la fonction, y a t'il des erreur ? (d'après le premier post, non)
    Si non, fait des cout pour avoir un trace de tes variable notamment après ouvrirInventaite.

    Es tu sûr et certain de la valeur de lieu ? ( je ne le vois pas initialiser et il joue un rôle important après )

    Es tu sur et certain de l'existence de tes fichier png ? Une faute de frappe et hop, tout plante ...

    Si rien de tout cela marche, envoie moi un code plus conséquent (voir tout ton code et tes images via sofevans@hotmail.fr ).

    J'espère qu'on va la trouver cette erreur ...

    EDIT :

    J'ai peut être une autre piste

    Dans UtiliseObjet, tu déclare un SDL_Surface *okFeu = NULL ainsi qu'une SDL_Rect positionokFeu. Tu ne les utilise pas dans ta fonction UtiliseObjet. Par contre, tu utilise les même en dehors ...
    Vérifie leur déclaration et leur utilite dans UtiliseObjet

Discussions similaires

  1. [Débutant] Problème lors d'appel de fonction dans page de démarrage.
    Par Vidou12 dans le forum VB.NET
    Réponses: 46
    Dernier message: 20/01/2015, 14h40
  2. Réponses: 1
    Dernier message: 06/07/2007, 09h55
  3. [MySQL] problème lors de l'appel d'une fonction
    Par jexl dans le forum PHP & Base de données
    Réponses: 5
    Dernier message: 27/06/2007, 09h53
  4. Problème lors de l'utilisation de la fonction exp()
    Par pillou dans le forum Paradox
    Réponses: 5
    Dernier message: 14/05/2007, 15h05
  5. Réponses: 6
    Dernier message: 20/01/2006, 19h28

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