Bien le bonsoir,
Pour m'entraîner au C++/SFML, j'ai eu comme idée de porter le mario sokoban du cours sur le C du site du zéro en C++.
Pour commencer j'avais pensé entamer mon projet par l'éditeur de niveau. J'ai pensé le faire sous forme de deux fenêtres: la grande pour construire le niveau et la petite avec les différents tiles que l'on peut sélectionner en cliquant dessus. Pour l'instant l'éditeur est juste censé permettre de créer un nouveau niveau sans pouvoir encore le sauvegarder.
Problème: En SFML, on ne peut avoir qu'une seule fenêtre active par thread
Solution: Qu'à cela ne tienne, je vais faire un deuxième thread
Re-problème: Étant donné que c'est la première fois que je fais un programme qui utilise plusieurs threads, je suis très mauvais (et le compilo ne se gêne pas pour me le faire comprendre avec ses mots doux
): le programme compile mais crash au moment de démarrer l'éditeur.
J'aimerais donc savoir si vous pouviez m'aider à trouver d'où vient l'erreur. Sans plus tarder le moment que vous attendez tous:
LE CODE!!! main.cpp:#include <iostream>
#include <SFML\Graphics.hpp>
#include "Constantes.hpp"
#include "Editeur.hpp"
using namespace std;
using namespace sf;
int main()
{
Event event;
//Création de la fenêtre
RenderWindow window(VideoMode(LARGEUR_FENETRE,HAUTEUR_FENETRE),"Mario Sokoban (by Mehfak)",Style::Close);
window.setFramerateLimit(60);
//Icone
Image icone;
if(!icone.loadFromFile("sprites/caisse.jpg"))
{
cout<<"Erreur lors du chargement de l'icone"<<endl;
system("pause>nul");
return EXIT_FAILURE;
}
window.setIcon(icone.getSize().x,icone.getSize().y,icone.getPixelsPtr());
//Menu
Texture menuTexture;
if(!menuTexture.loadFromFile("sprites/menu.jpg"))
{
cout<<"Erreur lors du chargement du menu"<<endl;
system("pause>nul");
return EXIT_FAILURE;
}
Sprite menu(menuTexture);
//Boucle Principale
while(window.isOpen())
{
while(window.pollEvent(event))
if(event.type == Event::Closed || event.key.code == Keyboard::Escape)
window.close();
if(Keyboard::isKeyPressed(Keyboard::Numpad2) || Keyboard::isKeyPressed(Keyboard::Num2))
{
Editeur* editeur = new Editeur(&window);
editeur->Launch();
delete(editeur);
}
window.clear();
window.draw(menu);
window.display();
}
return EXIT_SUCCESS;
}
Constantes.hpp:#ifndef CONSTANTES_HPP
#define CONSTANTES_HPP
#define TAILLE_TILE 34
#define NB_TILES_X 12
#define NB_TILES_Y 12
#define NB_TILES 5
#define LARGEUR_FENETRE TAILLE_TILE*NB_TILES_X
#define HAUTEUR_FENETRE TAILLE_TILE*NB_TILES_Y
enum Direction{HAUT,BAS,GAUCHE,DROITE};
enum Tile{VIDE, MUR, CAISSE, OBJECTIF, MARIO, CAISSE_OK};
#endif //CONSTANTES_HPP
Editeur.hpp, la classe qui me pose problème:#ifndef EDITEUR_HPP
#define EDITEUR_HPP
#include <iostream>
#include <fstream>
#include <string>
#include <SFML\Graphics.hpp>
#include "Constantes.hpp"
class Editeur
{
public:
Editeur(sf::RenderWindow* pointeur);
void Launch();
private:
//Fonctions de l'éditeur
void CreateLvl();
void ModifyLvl();
//Fonction d'affichage
void Afficher();
//Fonctions de lancement
void CreateSprite();
void LaunchTileWindow();
sf::Thread threadTileWindow;
sf::RenderWindow *window, tileWindow;
char tileActuel;
sf::Sprite sprites[NB_TILES];
sf::Texture textures[NB_TILES];
char niveau[NB_TILES_X][NB_TILES_Y];
};
#endif //EDITEUR_HPP
Editeur.cpp, les erreurs sont sûrement là dedans:#include "Editeur.hpp"
using namespace std;
using namespace sf;
Editeur::Editeur(RenderWindow* pointeur) : window(pointeur), threadTileWindow(&Editeur::LaunchTileWindow, this)
{
//Initialisation du tableau de sprites
CreateSprite();
}
void Editeur::CreateSprite()
{
if(!textures[VIDE].loadFromFile("sprites/vide.jpg"))
{
cout<<"Erreur lors du chargement du sprite vide"<<endl;
system("pause>nul");
exit(-1);
}
if(!textures[MUR].loadFromFile("sprites/mur.jpg"))
{
cout<<"Erreur lors du chargement du sprite mur"<<endl;
system("pause>nul");
exit(-1);
}
if(!textures[CAISSE].loadFromFile("sprites/caisse.jpg"))
{
cout<<"Erreur lors du chargement du sprite caisse"<<endl;
system("pause>nul");
exit(-1);
}
if(!textures[OBJECTIF].loadFromFile("sprites/objectif.png"))
{
cout<<"Erreur lors du chargement du sprite objectif"<<endl;
system("pause>nul");
exit(-1);
}
if(!textures[MARIO].loadFromFile("sprites/mario_bas.gif"))
{
cout<<"Erreur lors du chargement du sprite mario"<<endl;
system("pause>nul");
exit(-1);
}
for(int i = 0; i<NB_TILES; i++)
sprites[i].setTexture(textures[i]);
}
void Editeur::LaunchTileWindow()
{
//Création fenêtre
tileWindow.create(VideoMode(NB_TILES*TAILLE_TILE,TAILLE_TILE,32),"Sélectionner un bloc",Style::Close);
tileWindow.setFramerateLimit(1);
Image icone;
if(!icone.loadFromFile("sprites/caisse.jpg"))
{
cout<<"Erreur lors du chargement de l'icone"<<endl;
system("pause>nul");
exit(-1);
}
tileWindow.setIcon(icone.getSize().x,icone.getSize().y,icone.getPixelsPtr());
for(int i=0; i < 5; i++)
{
sprites[i].setPosition(i*TAILLE_TILE,0);
tileWindow.draw(sprites[i]);
}
Event event;
while(tileWindow.isOpen())
{
while(tileWindow.waitEvent(event))
switch(event.type)
{
case Event::Closed:
tileWindow.close();
break;
case Event::MouseButtonPressed:
if(event.mouseButton.button == Mouse::Left)
tileActuel = event.mouseButton.x/TAILLE_TILE;
break;
}
}
}
void Editeur::Launch()
{
int choix(0);
while(choix != 1 && choix != 2 && choix != 3)
{
cout<<"Que souhaitez-vous faire?"<<endl;
cout<<"1) Creer un niveau"<<endl;
cout<<"2) Modifier un niveau"<<endl;
cout<<"3) Quitter l'editeur de niveau"<<endl;
cin>>choix;
system("cls");
}
cout<<"Fermez la fenetre de tiles pour quitter l'editeur."<<endl;
switch(choix)
{
case 1:
CreateLvl();
break;
case 2:
break;
case 3:
break;
}
}
void Editeur::CreateLvl()
{
Event event;
//Affichage
window->clear();
window->setMouseCursorVisible(false);
threadTileWindow.launch();
while(tileWindow.isOpen())
{
while(window->pollEvent(event))
if(event.type == Event::Closed || event.key.code == Keyboard::Escape)
tileWindow.close();
if(Mouse::isButtonPressed(Mouse::Left))
niveau[Mouse::getPosition(*window).x/TAILLE_TILE][Mouse::getPosition(*window).y/TAILLE_TILE]= tileActuel;
Afficher();
}
}
void Editeur::Afficher()
{
Sprite curseur(sprites[tileActuel]);
curseur.setPosition(Mouse::getPosition(*window).x,Mouse::getPosition(*window).y);
window->clear();
for(unsigned int x = 0; x < NB_TILES_X; x++)
{
for(unsigned int y = 0; y < NB_TILES_Y; y++)
{
sprites[niveau[x][y]].setPosition(x*TAILLE_TILE,y*TAILLE_TILE);
window->draw(sprites[niveau[x][y]]);
}
}
window->draw(curseur);
window->display();
}
Merci de me faire part de mes erreurs, j'ai envie de progresser et surtout de faire fonctionner ce %#@!$* d'éditeur
EDIT: Oups! Petite précision qui a certainement son importance, quand je debug le programme j'ai un message d'erreur qui me dit R6025 - pure virtual function call et qaund je cherche de quelle fonction virtuelle il parle, il semblerait que ce soit une fonction qui soit dans une des .dll de SFML =/