Bonjour !
Avec des amis je me suis lancé dans un petit jeu (un rts), seulement j'ai quelques soucis avec l'affichage de la tile map qui à la fâcheuse tendance à clignoter dès lors que je bouge ma souris, et le seul moyen que j'ai trouvé pour résoudre ce problème est de mettre la méthode qui affiche les tiles dans la boucle principale ce qui fait alors chuter mon framerate à 0. Par ailleurs si vous avez des conseils pour amélioree mon code je suis preneur
voici mon code:
MapGen.h (la classe qui gère la map):
#include <SFML/system.hpp>
#include <SFML/window.hpp>
#include <SFML/graphics.hpp>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
class MapGen
{
public:
MapGen(int tailleX, int tailleY);//la taille en tiles
MapGen(int tailleX, int tailleY, bool surcharge);//le bool surcharge ne sert qu'a surchager le constructeur
std::vector<std::vector<int> > getMap() const;//renvoie le vector 2d de la map
bool isCrossable(int x, int y) const;//retourne true si la tile aux coords données est traversable par des unitées
void load(sf::RenderWindow* window, int windowSizeX, int windowSizeY);//charge les tiles
void setView(sf::RenderWindow* window);//definit la vue
void loopView(sf::RenderWindow* window);//a mettre dans la boucle principale, permet de déplacer la vue avec la souris
~MapGen();
protected:
int const m_tailleX;
int const m_tailleY;
int m_viewSpeed;
float m_tileSizeX, m_tileSizeY;
std::vector<std::vector<int> > m_mapp;//un tableau 2d qui contient sous forme de int les tiles de la map
sf::View m_mainView;
};
MapGen.cpp:
#include "MapGen.h"
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <vector>
#include <fstream>
#include <SFML/system.hpp>
#include <SFML/window.hpp>
#include <SFML/graphics.hpp>
MapGen::MapGen(int tailleX, int tailleY) : m_tailleX(tailleX), m_tailleY(tailleY), m_mapp(tailleX, std::vector<int>(tailleY,0)),
m_mainView(sf::Vector2f(0,0), sf::Vector2f(1920,1080))
{
srand(time(0));//seed (à améliorer)
//génération aléatoire chaotique
for(int i(0); i<m_tailleX; i++)//double boucle pour un tableau 2d
{
for(int j(0); j<m_tailleY; j++)
{
m_mapp[i][j] = rand() % 4;
std::cout << m_mapp[i][j];
}
std::cout << std::endl;
}
}
//génération de la map à partir d'un fichier (preque plus buggué)
MapGen::MapGen(int tailleX, int tailleY, bool surcharge) : m_tailleX(tailleX), m_tailleY(tailleY), m_mapp(tailleX, std::vector<int>(tailleY,0))
,m_mainView(sf::Vector2f(500,500), sf::Vector2f(700,800))
{
std::ifstream f_customMap("");
if(f_customMap)//si on reussi à lire le fichier
{
char mapTab[tailleX][tailleY];//tableau qui contiendra la map
while(!f_customMap.eof())//lecture du fichier jusqu'a la fin
{
for(int i(0);i<m_tailleX;i++)
{
for(int j(0);j<m_tailleY;j++)
{
//à lire important !!!!!!
//bug:
//la dernière valeur du tableau (en bas a gauche) ne doit pas etre écrite dans le fichier
//sa valeur sera donc toujours de 0
//sinon gros bugs sur les valeurs
f_customMap.get(mapTab[i][j]);
m_mapp[i][j] = atoi(&mapTab[i][j]);//la fonction atoi transforme le char en int
std::cout << m_mapp[i][j]<< " ";
}
std::cout << std::endl;
}
}
//std::cout << *mapTab;
}
else
{
std::cout << "erreur, le fichier n'a pas pu etre lu" << std::endl;
}
}
std::vector<std::vector<int> > MapGen::getMap() const
{
return m_mapp;
}
bool MapGen::isCrossable(int x, int y) const
{
if(m_mapp[x][y] == 0)
return true;
else
return false;
}
void MapGen::load(sf::RenderWindow* window, int windowSizeX, int windowSizeY)//chargement des tiles
{
std::string r_dirtTile1("C:/Users/blackbird/Dropbox/rts/Graphs/Rendu/Tile Export/TileMaps_Animation 1_00.png"), r_dirtTile2("C:/Users/blackbird/Dropbox/rts/Graphs/Rendu/Tile Export/TileMaps_Animation 1_01.png")
, r_dirtTile3("C:/Users/blackbird/Dropbox/rts/Graphs/Rendu/Tile Export/TileMaps_Animation 1_02.png"), r_dirtTile4("C:/Users/blackbird/Dropbox/rts/Graphs/Rendu/Tile Export/TileMaps_Animation 1_03.png"),
r_dirtTile5("C:/Users/blackbird/Dropbox/rts/Graphs/Rendu/Tile Export/TileMaps_Animation 1_04.png");
// tileSizeX = windowSizeX/m_tailleX;//on définit la taille des tiles en fonction de celle de la fenetre
// tileSizeY = windowSizeY/m_tailleY;//rappel: m_taille ==> taille de la map en tiles
m_tileSizeX = m_tileSizeY = 16*4;
//std::cout << "taille des tiles: " << tileSizeX << std::endl << tileSizeY << std::endl;
sf::RectangleShape tile1[m_tailleX][m_tailleY];//tableau qui contient les tiles
sf::RectangleShape rect;
sf::Texture t_dirtTile1, t_dirtTile2, t_dirtTile3, t_dirtTile4, t_dirtTile5;
t_dirtTile1.loadFromFile(r_dirtTile1);
t_dirtTile2.loadFromFile(r_dirtTile2);
t_dirtTile3.loadFromFile(r_dirtTile3);
t_dirtTile4.loadFromFile(r_dirtTile4);
t_dirtTile5.loadFromFile(r_dirtTile5);
for(int i(0);i<m_tailleX;i++)
{
for(int j(0);j<m_tailleY;j++)
{
tile1[i][j].setSize(sf::Vector2f(m_tileSizeX, m_tileSizeY));
tile1[i][j].setPosition(j * m_tileSizeX,i* m_tileSizeY);
if(m_mapp[i][j] == 0)//les couleurs seront remplacé par les textures
{//tile1[i][j].setFillColor(sf::Color::Yellow);
tile1[i][j].setTexture(&t_dirtTile1);
if (!t_dirtTile1.loadFromFile(r_dirtTile1))
{
std::cout << "erreur,";
}
}
else if(m_mapp[i][j] == 1)
{//tile1[i][j].setFillColor(sf::Color::Green);
tile1[i][j].setTexture(&t_dirtTile2);
if (!t_dirtTile2.loadFromFile(r_dirtTile2))
{
std::cout << "erreur,";
}
}
else if(m_mapp[i][j] == 2)
{//tile1[i][j].setFillColor(sf::Color::Blue);
tile1[i][j].setTexture(&t_dirtTile3);
if (!t_dirtTile3.loadFromFile(r_dirtTile3))
{
std::cout << "erreur,";
}
}
else if(m_mapp[i][j] == 3)
{//tile1[i][j].setFillColor(sf::Color::Red);
tile1[i][j].setTexture(&t_dirtTile4);
if (!t_dirtTile4.loadFromFile(r_dirtTile4))
{
std::cout << "erreur,";
}
}
else
{//tile1[i][j].setFillColor(sf::Color(200,50,30));
tile1[i][j].setTexture(&t_dirtTile5);
if (!t_dirtTile5.loadFromFile(r_dirtTile5))
{
std::cout << "erreur,";
}
}
if(tile1[i][j].getPosition().x <= m_mainView.getCenter().x + m_mainView.getSize().x && tile1[i] [j].getPosition().y >= m_mainView.getCenter().y - m_mainView.getSize().y)
{//on ne dessin que les tiles qui se trouvent dans la vue
window->draw(tile1[i][j]);
}
}
}
}
void MapGen::setView(sf::RenderWindow* window)
{
window->setView(m_mainView);
}
void MapGen::loopView(sf::RenderWindow* window)
{//si la souris est au bord de l'écran, on fait bouger la vue
m_viewSpeed = 30;//vitesse de déplacement de la vue (avec le clavier seulement !!!)
//si les coordonnées de la souris en x sont à 100 pixels près du bord de l'écran/la view on déplace la view
if(sf::Mouse::getPosition().x + 100 >= m_mainView.getSize().x)// && m_mainView.getCenter().x <= m_tailleX*m_tileSizeX)
{
m_mainView.move(100,0);//on déplace la vue de 100 pixels vers la droite
window->setView(m_mainView);//on met à jour la vue pour que les changements soient visibles
}
//même chose avec les coordonées en y
if(sf::Mouse::getPosition().y + 100 >= m_mainView.getSize().y)// && m_mainView.getCenter().x <= m_tailleY*m_tailleY)
{
m_mainView.move(0,100);
window->setView(m_mainView);
}
//toujours pareil mais pou déplacer la view dans l'autre sens
if(sf::Mouse::getPosition().x - 100 <= 0 && m_mainView.getCenter().x >= 0)
{
m_mainView.move(-100,0);
window->setView(m_mainView);
}
if(sf::Mouse::getPosition().y - 100 <= 0 && m_mainView.getCenter().x >= 0)
{
m_mainView.move(0,-100);
window->setView(m_mainView);
}
//------------------------
//déplacement de la vue avec le clavier
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Z))
{
m_mainView.move(0,-m_viewSpeed);
std::cout << "hello world" << std::endl;
window->setView(m_mainView);
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::S))
{
m_mainView.move(0,m_viewSpeed);
std::cout << "hello world" << std::endl;
window->setView(m_mainView);
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::D))
{
m_mainView.move(m_viewSpeed,0);
std::cout << "hello world" << std::endl;
window->setView(m_mainView);
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Q))
{
m_mainView.move(-m_viewSpeed,0);
std::cout << "hello world" << std::endl;
window->setView(m_mainView);
}
}
MapGen::~MapGen()
{
}
et enfin le main.cpp:
#include <SFML/system.hpp>
#include <SFML/window.hpp>
#include <SFML/graphics.hpp>
#include <iostream>
#include <ctime>
#include <cstdlib>
#include "MapGen.h"
/*
génération procédurale de la map && lecture de fichier
*/
int main()
{
//tests
MapGen terrain(85, 85);//1er probleme: si la taille donnée est trop grande, cela provoque une chute de fps
//avec une taille plus faible 20,20 par ex, le framerate reste acceptable
sf::RenderWindow window(sf::VideoMode(1920,1080), "hello world");
window.setFramerateLimit(60);
terrain.load(&window, 1920, 1080);
terrain.setView(&window);
while(window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
// évènement "fermeture demandée" : on ferme la fenêtre
if (event.type == sf::Event::Closed)
{
window.close();
}
window.clear();
terrain.loopView(&window);//méthode qui permet de déplacer la vue
terrain.load(&window, 1920, 1080);//affiche les tiles
window.display();
}
}
return 0;
}
ps: Je m'excuse si mon code est brouillon et illisible