Bonjour à tous et merci par avance de vos potentiels réponses.
Je suis en train de créer un petit shm'up à la space invader ("scrolling infini qui deviens de plus en plus dur")
Cependant, j'ai un problème ... En gros, je génère des ennemis, et à chaque fois que un d'entre eux sort de la View je le supprime de la liste des ennemis existants, quand le nombre d'ennemis est égal à 0 j'en génère d'autres en augmentant le nombre... Le problème est qu'à partir de la troisième génération ( voir deuxième ) avec à peine 25 ennemis ca lag ... Les fps tombent en dessous de 30 et encore bien en dessous par la suite 10 puis 5 .
J'ai donc crée un textureManager qui se charge dès le début de la partie de manière à ne pas charger les textures à chaque affichage, le principe d'affichage est le suivant :
//Boucle qui vérifie si un ennemi sort de la view
//Boucle qui move chaque ennemis de la liste puis les affiche
La boucle principale :
App::App()
{
window.create(sf::VideoMode(600, 600), "Space", sf::Style::Close );
window.setVerticalSyncEnabled(1);
}
void App::start()
{
window.clear(sf::Color::White);
}
void App::runGame()
{
GraphicsManager graphicsManager(window);
sf::Clock clock;
float lastTime = 0;
while(window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
{
window.close();
exit(1);
}
}
graphicsManager.slideAll(window);
window.display();
sf::Time elapsed1 = clock.getElapsedTime();
float fps= 1/ elapsed1.asSeconds();
cout <<"Fps : "<<fps << std::endl;
clock.restart();
}
}
Le gameManager ( qui servira à gérer les différents coefs et scores) et qui sert actuellement à gérer les listes d'ennemis
GameManager::GameManager()
{
m_score=0;
m_ennemiesNumber= 3;
m_ennemiesNumberCoef= 1;
string dir ="dat/ennemies/";
DIR *folder=opendir(dir.c_str());
dirent *currentFiles=NULL;
// INITIALISING THE ENNEMIESLIST
while((currentFiles = readdir(folder))!=NULL)
{
string tmp(currentFiles->d_name);
if(tmp.find(".txt") != string::npos)
{
SpaceShips create(dir+tmp);
ennemiesList.push_back(create);
}
}
}
void GameManager::ennemiesGeneration(int leftX, int leftY)
{
random_device rd;
mt19937 gen(rd());
uniform_int_distribution<int> Xposition(leftX, leftX+500);
existentEnnemiesList.resize(m_ennemiesNumber*m_ennemiesNumberCoef);
for(int i=0; i<existentEnnemiesList.size(); ++i)
{
shuffle(ennemiesList.begin(), ennemiesList.end(), random_device());
existentEnnemiesList[i] = ennemiesList[0];
existentEnnemiesList[i].setPosition(Xposition(gen), leftY-100);
}
m_ennemiesNumberCoef+=3;
}
Le GraphicsManager qui gère les mouvements et sorti de liste et l'affichage
#include "GraphicsManager.hpp"
using namespace std;
GraphicsManager::GraphicsManager(sf::RenderWindow &window)
{
m_slideCoef=1;
standard = window.getView();
standard.setCenter(300, 9000);
texture.loadFromFile("dat/back.png");
back.setTexture(texture);
window.draw(back);
TextureManager textureManager();
}
void GraphicsManager::slideAll(sf::RenderWindow & window)
{
// Background Slide
standard.move(0.f, -2.f);
// COORD
sf::Vector2f coor=standard.getCenter();
int leftCornerX=coor.x-(standard.getSize().x/2);
int leftCornerY=coor.y+(standard.getSize().y/2);
int leftCornerYTop=coor.y-(standard.getSize().y/2);
int maxX=leftCornerX+standard.getSize().x;
// RETURN 0 FOR SLIDING
sf::Vector2f lim(0, 300);
if(coor.y==lim.y)
{
standard.setCenter(300, 9000);
}
if(existentEnnemiesList.size()==0)
ennemiesGeneration(leftCornerX, leftCornerYTop);
// Move & ennemies & delete if out of view
int maxBox;
int cpt=0;
vector<SpaceShips>::iterator it;
for(it=existentEnnemiesList.begin(); it!=existentEnnemiesList.end(); ++it)
{
sf::FloatRect border=(*it).getBox();
maxBox=border.left + border.width;
if(border.left<=leftCornerX || maxBox>=maxX)
{
(*it).reverse();
}
if(border.top>=leftCornerY)
{
existentEnnemiesList.erase(existentEnnemiesList.begin()+cpt);
it=existentEnnemiesList.begin()+cpt;
cpt--;
break;
}
cpt++;
}
window.setView(standard);
window.draw(back);
for( auto &T:existentEnnemiesList)
{
T.moveX();
T.moveY();
T.display(window, textureManager);
}
}
le textureManager
#include "TextureManager.hpp"
using namespace std;
TextureManager::TextureManager()
{
string dir ="dat/ennemiesTextures/";
DIR *folder=opendir(dir.c_str());
dirent *currentFiles=NULL;
sf::Texture toMap;
// INITIALISING THE ENNEMIESLIST
while((currentFiles = readdir(folder))!=NULL)
{
string tmp(currentFiles->d_name);
if(tmp.find(".png") != string::npos)
{
if(toMap.loadFromFile(dir+tmp))
{
textureList[tmp]= toMap;
}
}
}
}
sf::Sprite TextureManager::getTexturedSprite(string textureName)
{
sf::Sprite sprite;
std::map<string,sf::Texture>::iterator it;
it=textureList.find(textureName);
sprite.setTexture((*it).second);
return sprite;
}
Et l'objet SpaceShips
#include "SpaceShips.hpp"
using namespace std;
SpaceShips::SpaceShips()
{
}
SpaceShips::SpaceShips(string path)
{
ifstream load(path, ios::in);
string buff;
if(load)
{
load >> buff >> buff >> name;
load >> buff >> buff >> buff;
maxLifePoint=atoi(buff.c_str());
load >> buff >> buff >> buff;
dirX=atoi(buff.c_str());
load >> buff >> buff >> buff;
dirY=atoi(buff.c_str());
load >> buff >> buff >> buff;
velocity=atoi(buff.c_str());
load >> buff >> buff >> buff;
size=atoi(buff.c_str());
load >> buff >> buff >> buff;
killPoint=atoi(buff.c_str());
load >> buff >> buff >> textureName;
}
}
void SpaceShips::moveX()
{
spaceShipSprite.move(dirX*velocity, 0);
}
void SpaceShips::moveY()
{
spaceShipSprite.move(0, dirY*velocity);
}
void SpaceShips::reverse()
{
dirX*=-1;
}
void SpaceShips::display(sf::RenderWindow &window, TextureManager textureManager)
{
sf::Sprite tmp=textureManager.getTexturedSprite(textureName);
tmp.setPosition(spaceShipSprite.getPosition());
tmp.setScale(0.6,0.6);
window.draw(tmp);
}
sf::FloatRect SpaceShips::getBox()
{
return spaceShipSprite.getGlobalBounds();
}
void SpaceShips::setPosition(int leftX, int leftY)
{
spaceShipSprite.setPosition(leftX, leftY);
}
J'écouterais attentivement toutes vos remarques, et même si je sais que mon code est très très loin d'être parfait je me prêterai à toutes les modifications que vous jugerez nécessaires !
Cordialement,
Moi (
)