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