Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: [Résolu]Pb runtime (et gestion des évènement souris)  (Lu 4951 fois)

0 Membres et 1 Invité sur ce sujet

kamui

  • Sr. Member
  • ****
  • Messages: 291
    • Voir le profil
[Résolu]Pb runtime (et gestion des évènement souris)
« le: Juin 22, 2012, 11:37:27 am »
Bonjour,

j'ai le message "this application has requested to terminate it in an unusual way. Please contact etc..." dès que je clique en dehors de ma fenetre SFML.

je vous montre la boucle de gestion des events mais je ne sais pas si ça peut venir de là, c'est plus par intuition :

while (fenetre->isOpen() && compteurCoups != 0 && !partieTerminee)
     {
         sf::Event event;
         while (fenetre->pollEvent(event))
         {
             if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Q)
                 fenetre->close();
             if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
             {
                 if (ModifierGrille(Contenu::CROIX, sf::Mouse::getPosition(*fenetre).x/100, sf::Mouse::getPosition(*fenetre).y/100))
                 {
                     compteurCoups--;
                     partieTerminee = PartieTerminee();
                     if (compteurCoups > 0 && !partieTerminee)
                     {
                        compteurCoups--;
                        partieTerminee = IA();
                     }
                 }

             }
         }

         fenetre->clear();

         DessinerContenuGrille();

         fenetre->display();
     }

 


merci d'avance pour votre aide ;)


EDIT : gdb me dit :

(gdb) r
Starting program: C:\Program Files (x86)\CodeBlocks\Projets\morpion\b
[New Thread 6440.0x1b58]
[New Thread 6440.0x1aa8]
warning: Invalid parameter passed to C runtime function.

warning: Invalid parameter passed to C runtime function.

[Inferior 1 (process 6440) exited with code 03]
(gdb) bt
No stack.
(gdb)
 

(je pige pas pourquoi il y'a deux thread...)
« Modifié: Juin 25, 2012, 11:39:39 am par kamui »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Pb runtime
« Réponse #1 le: Juin 22, 2012, 11:43:23 am »
Citer
je ne sais pas si ça peut venir de là
Un peu de debugging te dira justement très précisément d'où vient l'erreur. Ca c'est un travail que tu dois faire en amont, de sorte qu'on puisse examiner uniquement le morceau de code qui pose problème. L'idéal c'est de réussir à écrire un exemple complet minimal qui reproduit le problème.
Laurent Gomila - SFML developer

kamui

  • Sr. Member
  • ****
  • Messages: 291
    • Voir le profil
Re : Pb runtime
« Réponse #2 le: Juin 22, 2012, 11:44:35 am »
ouep désolé c'est ce que j'étais en train de faire justement.

ça peut venir du fait que j'ai plusieurs MingW, compilos etc ? ... plusieurs librairies runtime qui rentrent en conflit ?
« Modifié: Juin 22, 2012, 12:05:28 pm par kamui »

kamui

  • Sr. Member
  • ****
  • Messages: 291
    • Voir le profil
Re : Pb runtime
« Réponse #3 le: Juin 22, 2012, 01:21:51 pm »
voici le code complet minimal qui reproduit l'erreur
#include <vector>
#include <SFML/Graphics.hpp>
using namespace std;

class Morpion
{
    typedef enum {VIDE, CROIX, ROND} Contenu;
    vector<vector<Morpion::Contenu>> grille;

    sf::Texture* tGrille;
    sf::Sprite* sGrille;

    sf::Texture* tCroix;
    sf::Sprite* sCroix;

    sf::Texture* tRond;
    sf::Sprite* sRond;

    sf::RenderWindow* fenetre;

    int compteur;
    bool partieTerminee;
    bool aGagne;
  public :
    Morpion();
    ~Morpion();
    void Jouer();
    bool ModifierGrille(Morpion::Contenu contenu, int i, int j);
    bool PartieTerminee();
    void Init();

    bool IA();
    std::pair<int,int> EvaluerColonnes(Morpion::Contenu c);
    std::pair<int,int> EvaluerLignes(Morpion::Contenu c);
    std::pair<int,int> EvaluerDiagonales(Morpion::Contenu c);

    int GetCompteur() {return compteur;}
    bool AGagne() {return aGagne;}
    sf::RenderWindow* GetFenetre() {return fenetre;}

};



Morpion::Morpion() :
grille(3, vector<Morpion::Contenu>(3)),
tGrille(new sf::Texture()),
sGrille(new sf::Sprite()),
tCroix(new sf::Texture()),
sCroix(new sf::Sprite()),
tRond(new sf::Texture()),
sRond(new sf::Sprite()),
fenetre(new sf::RenderWindow(sf::VideoMode(300,300,32), "Test", sf::Style::None)),
compteur(9),
partieTerminee(false),
aGagne(false)
{
    grille = {{VIDE, VIDE, VIDE},{VIDE, VIDE, VIDE},{VIDE, VIDE, VIDE}};

    tGrille->loadFromFile("grille.png");
    sGrille->setTexture(*tGrille);

    tCroix->loadFromFile("croix.png");
    sCroix->setTexture(*tCroix);

    tRond->loadFromFile("rond.png");
    sRond->setTexture(*tRond);

    fenetre->setFramerateLimit(60);
    srand(time(NULL)); // initialisation de rand

}

Morpion::~Morpion()
{
    delete tGrille;
    delete tCroix;
    delete tRond;

    delete sGrille;
    delete sCroix;
    delete sRond;

    delete fenetre;
}

void Morpion::Jouer()
{
    while (fenetre->isOpen() && compteur!= 0 && !partieTerminee)
     {
         sf::Event event;
         while (fenetre->pollEvent(event))
         {
             if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Q)
                 fenetre->close();
            //C'est la ligne qui vient qui fait planter quand on clique en dehors de la fenetre
             if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
                 ModifierGrille(Contenu::CROIX, sf::Mouse::getPosition(*fenetre).x/100, sf::Mouse::getPosition(*fenetre).y/100);

         }

         fenetre->clear();
         fenetre->display();
     }
}

bool Morpion::ModifierGrille(Morpion::Contenu contenu, int i, int j)
{
    if (grille[i].at(j) == Contenu::VIDE)
    {
        grille[i].at(j) = contenu;
        return true;
    }
    else return false;
}


int main()
{
    Morpion m;
    m.Jouer();
    return 0;
}

 

je pensais que renseigner la fenetre dans getPosition permettait de ne pas tenir compte des clics en dehors du programme...mais aparremment ça fonctionne pas comme ça ^^

Donc quand je clique en dehors getPosition(*fenetre) plante pas vraiment mais renvoit des coordonnées négatives je supposes, ce qui créé un segfault à l'affectation de la grille...


« Modifié: Juin 22, 2012, 01:25:25 pm par kamui »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [Résolu]Pb runtime
« Réponse #4 le: Juin 22, 2012, 01:56:12 pm »
En effet, Mouse::getPosition(window) renvoie des coordonnées relatives à la fenêtre, mais pas limitées à celle-ci.

De toute façon ta façon de faire n'est pas du tout la bonne. Tu vérifies l'appui sur le bouton dans la boucle d'évènements, donc uniquement lorsqu'il se passe quelque chose (y compris des choses qui n'ont rien à voir avec la souris).

Pourquoi n'utilises-tu pas l'évènement MouseButtonPressed ? D'une part il ne sera pas généré lors de clics en dehors de la fenêtre, et d'autre part le code sera plus correct.
Laurent Gomila - SFML developer

kamui

  • Sr. Member
  • ****
  • Messages: 291
    • Voir le profil
Re : Re : [Résolu]Pb runtime
« Réponse #5 le: Juin 22, 2012, 02:17:48 pm »

Pourquoi n'utilises-tu pas l'évènement MouseButtonPressed ? D'une part il ne sera pas généré lors de clics en dehors de la fenêtre, et d'autre part le code sera plus correct.

Parce que je commences juste avec sfml2.0 Laurent et que j'ai pris la première chose que jai trouvé, et que je ne connais pas le fonctionnement interne

kamui

  • Sr. Member
  • ****
  • Messages: 291
    • Voir le profil
Re : [Résolu]Pb runtime
« Réponse #6 le: Juin 22, 2012, 05:35:12 pm »

en fait je n'arrive pas à déduire de la doc ni du forum une bonne façon d'utiliser sf::Mouse, classe avec laquelle je ne suis pas du tout familier (même sous 1.6 jamais utilisé)

et j'ai fait un truc qui me bouffe 3 à 6% du proc quand j'effectue une action (bouger la souris), 50% sinon :

while (m->GetFenetre()->pollEvent(event))
             {
                 if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Q)
                     m->GetFenetre()->close();
                 if (event.type == sf::Event::MouseButtonPressed && event.mouseButton.button == sf::Mouse::Button::Left)
                 {
                     if ((sf::Mouse::getPosition(*m->GetFenetre()).x <= 150) && (sf::Mouse::getPosition(*m->GetFenetre()).y > 150))
                     {
                        //on veut rejouer
                        rejouer = true;
                        choixFait = true;
                     }
                     else if ((sf::Mouse::getPosition(*m->GetFenetre()).x > 150) && (sf::Mouse::getPosition(*m->GetFenetre()).y > 150))
                     {
                         //on ne veut pas rejouer
                         rejouer = false;
                         choixFait = true;
                     }
                 }
                 m->GetFenetre()->clear();
                 m->DessinerContenuGrille();
                 m->GetFenetre()->draw(*sRejouer);
                 m->GetFenetre()->display();
             }
 

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [Résolu]Pb runtime
« Réponse #7 le: Juin 22, 2012, 06:43:28 pm »
Justement, pour faire ce que tu veux tu ne dois pas utiliser sf::Mouse. Uniquement les évènements, dont le fonctionnement est strictement le même que dans SFML 1.6.
Laurent Gomila - SFML developer

kamui

  • Sr. Member
  • ****
  • Messages: 291
    • Voir le profil
Re : [Résolu]Pb runtime
« Réponse #8 le: Juin 25, 2012, 09:53:10 am »
Merci Laurent, j'ai suivi tes instructions, et c'est vrai que c'est plus cool de récupérer des infos dans des objets que l'on a déjà à disposition ^^

Sinon, pour l'histoire des performances, c'est vraiment étrange, j'ai du oublié un détail, car je n'arrive pas à détecter l'erreur que j'ai commis pour obtenir ceci :

ici, 0-1% du proc (quoi que je fasse) :
void Morpion::Jouer()
{
    while (fenetre->isOpen() && compteurCoups!= 0 && !partieTerminee)
     {
         sf::Event event;
         while (fenetre->pollEvent(event))
         {
             if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Q)
                 fenetre->close();
             if (event.type == sf::Event::MouseButtonPressed)
             {
                 if (ModifierGrille(Contenu::CROIX, event.mouseButton.x/100, event.mouseButton.y/100))
                 {
                     compteurCoups--;
                     partieTerminee = PartieTerminee();
                     if (compteurCoups > 0 && !partieTerminee)
                     {
                        compteurCoups--;
                        partieTerminee = IA();
                     }
                 }
             }
         }

         fenetre->clear();

         DessinerContenuGrille();

         fenetre->display();
     }
}
 

ici par contre, 50% du proc si je ne bouge pas la souris...dès que je bouge la souris je retombe à 0-1% du proc... je ne comprends pas pourquoi et ne vois pas d'erreurs de ma part (mais il y en a forcément une) :

while (m->GetFenetre()->isOpen() && !choixFait)
         {
             sf::Event event;
             while (m->GetFenetre()->pollEvent(event))
             {
                 if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Q)
                     m->GetFenetre()->close();
                 if (event.type == sf::Event::MouseButtonPressed && event.mouseButton.button == sf::Mouse::Button::Left)
                 {
                     if ((event.mouseButton.x <= 150) && (event.mouseButton.y > 150))
                     {
                        //on veut rejouer
                        rejouer = true;
                        choixFait = true;
                     }
                     else if ((event.mouseButton.x > 150) && (event.mouseButton.y > 150))
                     {
                         //on ne veut pas rejouer
                         rejouer = false;
                         choixFait = true;
                     }
                 }
                 m->GetFenetre()->clear();
                 m->DessinerContenuGrille();
                 m->GetFenetre()->draw(*sRejouer);
                 m->GetFenetre()->display();
             }
         }
 

y a-t-il une évidence que j'ai raté ?

kamui

  • Sr. Member
  • ****
  • Messages: 291
    • Voir le profil
Re : [Résolu]Pb runtime (et gestion des évènement souris)
« Réponse #9 le: Juin 25, 2012, 07:39:40 pm »
Bah ouai gros con t'appelle display dans la boucle des events ! bientot 2 ans que j'utilise SFML et je passe deux jours sur un bug comme ça...