Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: [Résolu]Pb runtime (et gestion des évènement souris)  (Read 6055 times)

0 Members and 1 Guest are viewing this topic.

kamui

  • Sr. Member
  • ****
  • Posts: 291
    • View Profile
[Résolu]Pb runtime (et gestion des évènement souris)
« on: June 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...)
« Last Edit: June 25, 2012, 11:39:39 am by kamui »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re : Pb runtime
« Reply #1 on: June 22, 2012, 11:43:23 am »
Quote
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
  • ****
  • Posts: 291
    • View Profile
Re : Pb runtime
« Reply #2 on: June 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 ?
« Last Edit: June 22, 2012, 12:05:28 pm by kamui »

kamui

  • Sr. Member
  • ****
  • Posts: 291
    • View Profile
Re : Pb runtime
« Reply #3 on: June 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...


« Last Edit: June 22, 2012, 01:25:25 pm by kamui »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re : [Résolu]Pb runtime
« Reply #4 on: June 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
  • ****
  • Posts: 291
    • View Profile
Re : Re : [Résolu]Pb runtime
« Reply #5 on: June 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
  • ****
  • Posts: 291
    • View Profile
Re : [Résolu]Pb runtime
« Reply #6 on: June 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
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re : [Résolu]Pb runtime
« Reply #7 on: June 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
  • ****
  • Posts: 291
    • View Profile
Re : [Résolu]Pb runtime
« Reply #8 on: June 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
  • ****
  • Posts: 291
    • View Profile
Re : [Résolu]Pb runtime (et gestion des évènement souris)
« Reply #9 on: June 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...