Hey there, everyone on SFML forum. First of all, I would like to thank everyone who answers questions in this forum. I've gotten some great help from you guys (by lurking).
Let's get to the point. I'm basically trying to create a good code "structure" for managing multiple states (like intro, menu, options, playing, etc). I've been following
this guide, which has been helpful. The author of the article has written his program with SDL though, and I get problems trying to "remake" it for SFML.
My problem is simple, and hopefully easily solvable:
My
sf::Drawables won't render, even though the game loop is rolling as it should (I believe). Maybe you could take a look at the code and see what's wrong. If something's unclear I'll try to explain (I'm kind of a noob though).
Note: I have included all SFML libraries where needed, and also put
#ifndef,
#define and
#endif where appropriate, and will therefore omit them from the code. I have also removed all code that is irrelevant to the question, which is why the program seems incomplete
/** main.cpp **/
#include "GameEngine.hpp"
#include "IntroState.hpp"
int main() {
// Create GameEngine instance, which also creates a window, like this:
// sf::RenderWindow mWindow(sf::VideoMode(800, 600), "Window Title");
// Also sets Running() to "true".
GameEngine game;
// Change GameState to IntroState and call its Init()-method
game.ChangeState( IntroState::Instance() );
// Game loop
while ( game.Running() )
{
game.HandleEvents();
game.Draw();
}
return 0;
}
/** GameEngine.hpp **/
class GameState;
class GameEngine
{
public:
void ChangeState(GameState* state);
void HandleEvents();
void Draw();
bool Running() { return m_running; }
sf::RenderWindow mWindow;
private:
std::vector<GameState*> states;
bool m_running;
};
/** GameEngine.cpp **/
#include "GameEngine.hpp"
#include "GameState.hpp"
// An sf::RenderWindow is created in Init()-function here. Omitted for simplicity.
// sf::RenderWindow mWindow(sf::VideoMode(800, 600), "Window Title");
void GameEngine::ChangeState(GameState* state)
{
// Clean up the old states
if ( !states.empty() )
{
states.back()->Cleanup();
states.pop_back();
}
// Store and initialize the new state
states.push_back(state);
states.back()->Init();
}
void GameEngine::HandleEvents()
{
// Let the state handle events
states.back()->HandleEvents(this);
}
void GameEngine::Draw()
{
// Let the state draw the screen
states.back()->Draw(this);
}
/** GameState.hpp **/
#include "GameEngine.hpp"
class GameState
{
public:
virtual void Init() = 0;
virtual void HandleEvents(GameEngine* game) = 0;
virtual void Draw(GameEngine* game) = 0;
protected:
GameState() { };
};
/** IntroState.hpp **/
#include "GameState.hpp"
class IntroState : public GameState
{
public:
void Init();
void HandleEvents(GameEngine* game);
void Draw(GameEngine* game);
static IntroState* Instance() { return &m_IntroState; }
protected:
IntroState() { };
private:
sf::CircleShape circle;
};
This is basically where I implement the part of the Game Loop that happens while IntroState (the intro screen) is active:
/** IntroState.cpp **/
#include "IntroState.hpp"
void IntroState::Init()
{
// Create a shape to draw
sf::CircleShape circle;
circle.setRadius(50);
circle.setPosition(100, 100);
circle.setFillColor(sf::Color::Red);
}
void IntroState::HandleEvents(GameEngine* game)
{
sf::Event event;
while ( game->mWindow.pollEvent(event) )
switch (event.type)
{
// ... handle user input and such. No graphics in here.
}
}
void IntroState::Draw(GameEngine* game)
{
game->mWindow.clear(sf::Color::Black);
game->mWindow.draw(circle);
game->mWindow.display();
// Which is the same as
// (*game).mWindow.foo();
}
So basically I (try to) access
mWindow through
*game, which is
public and declared inside GameEngine.hpp.
I get the
sf::RenderWindow to display properly, I get it to clear with whichever color I choose (in this case
sf::Color::Black), but I can't see the circle. I've tried with different shapes and texts, but I can't get any
sf::Drawable to show at all.
I know it's a lot of code, sorry about that. Thank you in advance.