Forum de la communauté SFML

Aide => Système => Discussion démarrée par: Glân de Brylan le Septembre 18, 2014, 01:06:18 pm

Titre: [Résolu] Étrange erreur
Posté par: Glân de Brylan le Septembre 18, 2014, 01:06:18 pm
Bonjour,

En codant un petit jeu pour me familiariser avec la SFML, je me suis heurté à une étrange erreur concernant les threads, à la ligne 39 de 'Thread.inl' :
error: must use '.*' or '->*' to call pointer-to-member function in '((sf::priv::ThreadFunctor<void (Fenetre::*)()>*)this)->sf::priv::ThreadFunctor<void (Fenetre::*)()>::m_functor (...)', e.g. '(... ->* ((sf::priv::ThreadFunctor<void (Fenetre::*)()>*)this)->sf::priv::ThreadFunctor<void (Fenetre::*)()>::m_functor) (...)'|
(tellement long que je ne suis même pas sûr de l'avoir en entier...)

Voici le code :
main.cpp
#include "Fenetre"

#include <ctime>


int main()
{
    srand(time(0));

    Fenetre fenetre;


    return 0;
}

Piece.h
#ifndef PIECE_H
#define PIECE_H

#include <SFML/Graphics.hpp>
#include <cstdlib>


class Piece : public sf::Sprite
{
    public:
        Piece(int type=0);
        int getValue();
    private:
        int value;
        sf::Texture texture;
};

#endif // PIECE_H

Piece.cpp
#include "Piece.h"

Piece::Piece(int type) : value(0), Sprite()
{

    /*
    0 = pas de pièce
    1 = pièce de bronze (+1)
    2 = pièce d'argent (+3)
    3 = pièce d'or (+5)
    4 = pièce pif (résultat d'une pièce maudite ou bénie à 50/50)
    5 = pièce maudite (-3)
    6 = pièce bénie (+10)
    */
    switch(type)
    {
    case 1:
        texture.loadFromFile("pieceDbronze.png");
        value=1;
        break;
    case 2:
        texture.loadFromFile("peceDargent.png");
        value=3;
        break;
    case 3:
        texture.loadFromFile("pieceDor.png");
        value=5;
        break;
    case 4:
        texture.loadFromFile("piecepif.png");
        type=rand()%3; type+=4;
    case 5:
        texture.loadFromFile("piecemaudite.png");
        value=-3;
        break;
    case 6:
        texture.loadFromFile("piecebenie.png");
        value=10;
        break;
    default:
        return;
        break;
    }
    setTexture(texture);
}

int Piece::getValue()
{
    return value;
}

Fenetre.h
#ifndef FENETRE_H
#define FENETRE_H


#include "GTexture.h"
#include "Piece.h"


class Fenetre
{
    public:
        Fenetre();
        virtual ~Fenetre();
    protected:
        void update();
        void deplacements();
        int typePiece();
        void jump();
        void pieces();
    private:
        GTexture lapin, fond, pieceDbronze, pieceDargent, pieceDor, piecepif, piecemaudite, piecebenie;
        sf::Sprite spLapin, spFond;

        sf::Thread dpl, pcs, jmp;

        bool jeuEnCours;
        bool jumping, droite, gauche;
        sf::RenderWindow window;
        std::vector<sf::Drawable*> entities;
};

#endif // FENETRE_H

Fenetre.cpp
#include "Fenetre.h"



Fenetre::Fenetre() :lapin("resources/pain.png"), fond("resources/fond.png"), pieceDbronze("resources/pieceDbronze.png"), pieceDargent("resources/pieceDargent.png"), \
                    pieceDor("resources/pieceDor.png"), piecepif("resources/piecepif.png"), piecemaudite("resources/piecemaudite.png"), piecebenie("resources/piecebenie.png"),\
                    spLapin(lapin), spFond(fond), \
                    dpl(&Fenetre::deplacements), pcs(&Fenetre::pieces), jmp(&Fenetre::jump), \
                    jeuEnCours(false), jumping(false), droite(false), gauche(false), \
                    window(sf::VideoMode(800, 600), "Rabbits like coins", sf::Style::Titlebar | sf::Style::Close)

{
    entities.push_back(&spFond);
    entities.push_back(&spLapin);
    spLapin.setPosition(400,545);
    spLapin.setOrigin(25, 25);
    update();

    dpl.launch();

    sf::Event event;

    while (window.isOpen())
    {
        if(gauche && droite)
            {}
        else if(gauche)
            spLapin.setScale(-1, 1);
        else if(droite)
            spLapin.setScale(1, 1);

        update();
        // on inspecte tous les évènements de la fenêtre qui ont été émis depuis la précédente itération
        while (window.pollEvent(event))
        {
            // évènement "fermeture demandée" : on ferme la fenêtre
            if (event.type == sf::Event::Closed)
            {
                jeuEnCours=false;
                window.close();
            }
            else if (event.type == sf::Event::KeyPressed)
            {
                switch(event.key.code)
                {
                case sf::Keyboard::Left:
                    gauche=true;
                    break;
                case sf::Keyboard::Right:
                    droite=true;
                    break;
                case sf::Keyboard::Up:
                    if(jumping)
                        jumping=false;
                    jmp.launch();
                default:
                    update();
                    break;
                }
            }
            else if (event.type == sf::Event::KeyReleased)
            {
                if(event.key.code == sf::Keyboard::Left)
                    gauche=false;
                if(event.key.code == sf::Keyboard::Right)
                    droite=false;
                break;
            }
        }
    }
}

Fenetre::~Fenetre()
{
    //dtor
}

void Fenetre::deplacements()
{
    while(jeuEnCours)
    {
        //std::this_thread::sleep_for(std::chrono::milliseconds(5));
        if(droite && gauche)
        return;

        if(droite && spLapin.getPosition().x < 825)
        {
            spLapin.move(1,0);
            if(spLapin.getPosition().x >= 824)
                spLapin.setPosition(-25, spLapin.getPosition().y);
        }

        if(gauche && spLapin.getPosition().x > -25)
        {
            spLapin.move(-1,0);
            if(spLapin.getPosition().x <= -24)
                spLapin.setPosition(825, spLapin.getPosition().y);
        }
    }
}

void Fenetre::update()
{
    window.clear();
    for(int i=0;i<(int)entities.size();i++)
        if(entities[i] != nullptr)
            window.draw(*entities[i]);
    window.display();
}

int Fenetre::typePiece()
{
    /*
    0 = pas de pièce (5%)
    1 = pièce de bronze (40%)
    2 = pièce d'argent (20%)
    3 = pièce d'or (10%)
    4 = pièce pif (27%)
    5 = pièce maudite (18%)
    6 = pièce bénie (10%)
    */
    int nb(rand() % 100);
    if(nb<70)
    {
        if(nb<40)
            return 1;
        else if(nb<20)
            return 2;
        else
            return 3;
    }
    else if(nb<95)
    {
        if(nb<67)
            return 4;
        else if(nb<85)
            return 5;
        else
            return 6;
    }
    else
        return 0;
}


//threads
void Fenetre::jump()
{
    jumping=true;
    int i(0);
    for(i=1;i<100;i++)
    {
        if(spLapin.getPosition().y>0)
        {
            if(!jumping)
                return;
            spLapin.move(0,-1);
            sf::sleep(sf::milliseconds(i/10));;
        }
    }

    i=1;
    while(spLapin.getPosition().y<545)
    {
        if(i<100)
            i++;
        if(!jumping)
            return;
        spLapin.move(0,1);
        sf::sleep(sf::milliseconds(100/i));
    }

    jumping=false;
}

void Fenetre::pieces()
{
    int intervalle(50),type(0);
    while(jeuEnCours)
    {
        sf::sleep(sf::milliseconds(intervalle*10));
        type=typePiece();

        if(type!=0)
        {
            Piece *piece(new Piece(type));
            piece->setPosition((rand() % 800), (rand() % 600));
            entities.push_back(piece);
        }
        if (intervalle > 1)
            intervalle--;
    }
}


Toutes les infos potentiellement utiles :
OS : Windows 8.1
IDE : Code::Blocks 13.12
Compilateur : GCC 4.7.1
Titre: Re : Étrange erreur
Posté par: Laurent le Septembre 18, 2014, 01:46:35 pm
Relis bien le tutoriel et la documentation. Tu ne peux pas passer ce genre de fonction comme ça à sf::Thread.
Titre: Re : Étrange erreur
Posté par: Glân de Brylan le Septembre 18, 2014, 02:12:02 pm
C'est juste, merci. J'ai mis this en second paramètre des threads et ça fonctionne.