SFML community forums
Help => Graphics => Topic started by: Ptlomej on February 21, 2012, 05:42:59 pm
-
i have a performance problem i want make a Star background for my Spaceshooter game im using this
ITS VERY LAGGY O.O(1-2 FPS)
Background.h
#pragma once
#include "Funktions.h"
class Background {
public:
Background();
~Background();
void Draw(sf::RenderWindow *Window);
void Update();
public:
list<sf::Sprite*> BackgroundSpriteSet;
list<sf::Image*> BackgroundImageSet;
list<sf::Shape*> Stars;
};
Background.cpp
#include "Background.h"
Background::Background(){
int Test = 1000;
for(int i = 0; i != Test; i++){
float X = sf::Randomizer::Random(-10000.f,10000.f);
float Y = sf::Randomizer::Random(-10000.f,10000.f);
float Size = sf::Randomizer::Random(1.f,5.f);
float BorderSize = Size*0.75;
float Alpha = sf::Randomizer::Random(64.25f,200.f);
float BorderAlpha = Alpha*0.25f;
sf::Shape *S2 = new sf::Shape;
*S2 = sf::Shape::Circle(sf::Vector2f(X,Y),Size,sf::Color(255,255,255,Alpha),BorderSize,sf::Color(255,255,255,BorderAlpha));
Stars.push_back(S2);
}
}
Background::~Background(){
}
void Background::Draw(sf::RenderWindow *Window){
for(list<sf::Sprite*>::iterator IT = BackgroundSpriteSet.begin(); IT != BackgroundSpriteSet.end(); IT++){
Window->Draw((*(*IT)));
}
for(list<sf::Shape*>::iterator IT = Stars.begin(); IT != Stars.end(); IT++){
Window->Draw((*(*IT)));
}
}
void Background::Update(){
}
-
Don't get me wrong, but this code shouldn't run at all. You should get a segfault.
Don't use pointers. That's my advice. Avoid them as long as you can, and if you really need to use pointers, then use some smart pointer.
So, try to change your containers to <sf::Sprite>, <sf::Image> and <sf::Shape>, and remove your pointers in the constructor, and see what happens. By the way, why do you have a std::list<sf::Image> ? You don't even use it.
-
I comes later the images i want not only use Stars later come Gas clouds and more. but then as Sprite. no Pointer FPS = 5 also laggy :S
-
Alright, then. I don't know why it's lagging, so I just post my similar implementation I did long ago.
Stars.hpp
#ifndef STARS_HPP
#define STARS_HPP
#include <SFML/Graphics.hpp>
#include <vector>
class Star
{
public:
Star (float x, float y);
~Star ();
void Draw (sf::RenderTarget& target) const;
private:
float mPosX;
float mPosY;
sf::Shape mCircle;
};
class StarManager
{
public:
StarManager (unsigned int width, unsigned int height);
~StarManager ();
void GenerateStars ();
void DrawStars (sf::RenderTarget& target);
private:
unsigned int mWidth;
unsigned int mHeight;
unsigned int mMaxStars;
std::vector<Star> Stars;
};
#endif
Stars.cpp
#include "Stars.hpp"
Star::Star (float x, float y):
mPosX(x),
mPosY(y)
{
mCircle = sf::Shape::Circle(mPosX, mPosY, 1, sf::Color::Yellow);
}
Star::~Star ()
{
}
void Star::Draw (sf::RenderTarget& target) const
{
target.Draw(mCircle);
}
StarManager::StarManager (unsigned int width, unsigned int height):
mWidth(width),
mHeight(height),
mMaxStars(200)
{
}
StarManager::~StarManager ()
{
Stars.clear();
}
void StarManager::GenerateStars ()
{
unsigned int lx;
unsigned int ly;
for (unsigned int i = 0; i != mMaxStars; ++i)
{
lx = sf::Randomizer::Random(0, mWidth);
ly = sf::Randomizer::Random(0, mHeight);
Star aStar(lx, ly);
Stars.push_back(aStar);
}
}
void StarManager::DrawStars (sf::RenderTarget& target)
{
std::vector<Star>::iterator iter;
for (iter = Stars.begin(); iter != Stars.end(); ++iter)
{
iter->Draw(target);
}
}
And here is how you use it:
StarManager smgr(400, 400); // (400, 400) is the width and height of the area, where the stars will be
smgr.GenerateStars();
// in your render code
smgr.DrawStars(mywindow); // mywindow is your sf::RenderWindow
It's old code, but should work without problems. Hope it helps.
-
I done it now but its to laggy ? its too much Stairs oô ? or how can i perform it FASTER i saw yours and you use vector okay i take vector its now Faster but not faster enough :S now i use images CODE:
Background.h
#pragma once
#include "Funktions.h"
class Background {
public:
Background();
~Background();
void Draw(sf::RenderWindow *Window);
void Update();
public:
sf::Image *TempLoader[6];
vector<sf::Sprite> BackgroundSpriteSet;
};
Background.cpp
#include "Background.h"
Background::Background(){
int Test = 500;
TempLoader[0] = new sf::Image;
TempLoader[1] = new sf::Image;
TempLoader[2] = new sf::Image;
TempLoader[3] = new sf::Image;
TempLoader[4] = new sf::Image;
TempLoader[5] = new sf::Image;
TempLoader[0]->LoadFromFile("./resource/stair1.png");
TempLoader[1]->LoadFromFile("./resource/stair2.png");
TempLoader[2]->LoadFromFile("./resource/stair3.png");
TempLoader[3]->LoadFromFile("./resource/stair4.png");
TempLoader[4]->LoadFromFile("./resource/stair5.png");
TempLoader[5]->LoadFromFile("./resource/stair6.png");
TempLoader[0]->SetSmooth(true);
TempLoader[1]->SetSmooth(true);
TempLoader[2]->SetSmooth(true);
TempLoader[3]->SetSmooth(true);
TempLoader[4]->SetSmooth(true);
TempLoader[5]->SetSmooth(true);
for(int i = 0; i != Test; i++){
float X = sf::Randomizer::Random(-5000.f,5000.f);
float Y = sf::Randomizer::Random(-5000.f,5000.f);
int SEL = sf::Randomizer::Random(0,5);
sf::Sprite S1((*TempLoader[SEL]),sf::Vector2f(X,Y));
S1.SetCenter(TempLoader[SEL]->GetWidth()/2.f,TempLoader[SEL]->GetHeight()/2.f);
S1.SetScale(S1.GetScale()*0.25f);
BackgroundSpriteSet.push_back(S1);
}
}
Background::~Background(){
}
void Background::Draw(sf::RenderWindow *Window){
for(vector<sf::Sprite>::iterator IT = BackgroundSpriteSet.begin(); IT != BackgroundSpriteSet.end(); IT++){
Window->Draw((*IT));
}
}
void Background::Update(){
}
-
How do you use this in your actual game ? Do you construct the Background object once, and then just call Draw() or you construct it every frame (which is obviously wrong)?
What's in the "Functions.h" ?
Yes, maybe you have too much stars, try it with 100 or 200. Using sf::Shape's might be faster, so use them for this. In this case you can use list and vector aswell, so that's not an issue.
-
One time Construct with pointer, the game are running in class.
and every while in the Draw section a Draw.