Alright it has been a while since I have programmed but I have found some free time. State managing has really held me back because I can't seem to grasp how to do it! I started trying to put together a very simple state manager by looking at different resources but I'm having problems.
Here's the basic jest of it:
#ifndef ENGINE_HPP_
#define ENGINE_HPP_
#include <iostream>
#include <vector>
#include <SFML/Graphics.hpp>
class CGameState;
class Engine
{
public:
void Init(const string& title, int width=1024, int height=768,
int bpp=32, bool fullscreen=false);
void Cleanup();
void ChangeState(CGameState* state);
void PushState(CGameState* state);
void PopState();
void HandleEvents();
void Update();
void Draw();
bool Running() { return m_running; }
void Quit() { m_running = false; }
sf::RenderWindow screen;
private:
std::vector<CGameState*> states;
bool m_running;
bool m_fullscreen;
};
#endif
#include "Engine.hpp"
#include "gamestate.hpp"
void Engine::Init(const string& title, int width, int height,
int bpp, bool fullscreen)
{
mode = sf::VideoMode(width, height, bpp);
Window.Create(mode, title);
m_fullscreen = fullscreen;
m_running = true;
printf("CGameEngine Init\n");
}
void Engine::Cleanup()
{
// cleanup the all states
while ( !states.empty() )
{
states.back()->Cleanup();
states.pop_back();
}
printf("GameEngine Cleanup\n");
}
void Engine::ChangeState(CGameState* state)
{
// cleanup the current state
if ( !states.empty() ) {
states.back()->Cleanup();
states.pop_back();
}
// store and init the new state
states.push_back(state);
states.back()->Init();
}
void Engine::PushState(CGameState* state)
{
// pause current state
if ( !states.empty() ) {
states.back()->Pause();
}
// store and init the new state
states.push_back(state);
states.back()->Init();
}
void Engine::PopState()
{
// cleanup the current state
if ( !states.empty() ) {
states.back()->Cleanup();
states.pop_back();
}
// resume previous state
if ( !states.empty() ) {
states.back()->Resume();
}
}
void Engine::HandleEvents()
{
// let the state handle events
states.back()->HandleEvents(this);
}
void Engine::Update()
{
// let the state update the game
states.back()->Update(this);
}
void Engine::Draw()
{
// let the state draw the screen
states.back()->Draw(this);
}
#ifndef GAMESTATE_H
#define GAMESTATE_H
#include "Engine.hpp"
class CGameState
{
public:
virtual void Init() = 0;
virtual void Cleanup() = 0;
virtual void Pause() = 0;
virtual void Resume() = 0;
virtual void HandleEvents(Engine* game) = 0;
virtual void Update(Engine* game) = 0;
virtual void Draw(Engine* game) = 0;
void ChangeState(Engine* game, CGameState* state) {
game->ChangeState(state);
}
protected:
CGameState() { }
};
#endif
#ifndef INTROSTATE_HPP_
#define INTROSTATE_HPP_
#include <SFML/Graphics.hpp>
#include "gamestate.hpp"
class CIntroState : public CGameState
{
public:
void Init();
void Cleanup();
void Pause();
void Resume();
void HandleEvents(Engine* game);
void Update(Engine* game);
void Draw(Engine* game);
static CIntroState* Instance() {
return &m_IntroState;
}
protected:
CIntroState() { }
private:
static CIntroState m_IntroState;
sf::Sprite OpenMenu;
};
#endif
#include <iostream>
#include <SFML/Graphics.hpp>
#include "Engine.hpp"
#include "IntroState.hpp"
CIntroState CIntroState::m_IntroState;
void CIntroState::Init()
{
std::cout << "start" << std::endl;
sf::Image Open;
if( !Open.LoadFromFile("OpenGameMenu.png") )
std::cout << "ERROR" << std::endl;
OpenMenu.SetImage(Open);
}
void CIntroState::HandleEvents(Engine* game)
{
sf::Event event;
while( game->screen.GetEvent(event) )
{
if( event.Type == sf::Event::Closed )
{
game->Quit();
}
}
}
void CIntroState::Draw(Engine* game)
{
game->screen.Draw(OpenMenu);
}
void CIntroState::Update(Engine* game)
{
game->screen.Clear();
game->screen.Display();
}
#include <iostream>
#include "Engine.hpp"
#include "IntroState.hpp"
int main()
{
Engine game;
// initialize the engine
game.Init( "Engine" );
// load the intro
game.ChangeState( CIntroState::Instance() );
// main loop
while ( game.Running() )
{
game.HandleEvents();
game.Update();
game.Draw();
}
// cleanup the engine
game.Cleanup();
std::cout << "END OF MAIN" << std::endl;
std::cin.get();
return 0;
}
But my problem is I'm not sure how to manage the Window, when I try to draw a sprite to the window, I get nothing. In here, I create a window in the engine class, but how do I reach the window while I'm in the states to change the window? What would be a simple implementation of the IntroState to create an window output, while being able to switch to another state that uses the same window?