Refactored code heavily to be able to use a state stack - main function now does the basic init, looping, and shutdown, and each state is a pointer to an object that has its own event handling, rendering, etc

This commit is contained in:
Anna Rose 2011-06-27 22:07:52 -04:00
parent a77a8575c5
commit 5522cbc64c
7 changed files with 136 additions and 94 deletions

View File

@ -4,7 +4,7 @@ PROJECT=graphgame
CXX=g++
CXXFLAGS=-DDEBUG -g `sdl-config --cflags`
LDFLAGS=`sdl-config --libs`
OBJECTS=drawutils.o gamecore.o graph.o main.o mainevent.o mathutils.o gamedata.o sdlrenderer.o
OBJECTS=drawutils.o game.o graph.o main.o mainevent.o mathutils.o gamedata.o sdlrenderer.o
all: $(PROJECT)

52
game.cpp Normal file
View File

@ -0,0 +1,52 @@
#include "game.h"
#include "mathutils.h"
#include "debug.h"
#include <SDL.h>
int Game::NODE_RADIUS = 12;
Game::~Game()
{
renderer.cleanup();
}
void Game::execute(stack<GameState*> &state_stack) throw(StateExit)
{
SDL_Event event;
while(SDL_PollEvent(&event))
handle_event(&event);
renderer.render(data);
}
bool Game::init()
{
return renderer.init();
}
void Game::on_exit()
{
throw StateExit();
}
void Game::on_lbutton_down(int x, int y)
{
data.do_vertex(x, y, NODE_RADIUS);
}
void Game::on_rbutton_down(int mX, int mY)
{
data.clear_current_vertex();
}
void Game::on_key_down(SDLKey sym, SDLMod mod, Uint16 unicode)
{
if (sym == SDLK_q && mod & KMOD_CTRL) throw StateExit();
if (sym == SDLK_a) data.set_mode(MODE_ATTACK);
if (sym == SDLK_m) data.set_mode(MODE_MOVE);
}

View File

@ -1,23 +1,28 @@
/* This is the heart of the application.
This contains the basic game looping code, sets up event handlers, etc.
/* This is the heart of the application - the main game state where we are
actually playing.
All the hard work will eventually get farmed out to other objects, for now,
we're doing almost everything in here.
This contains the basic game logic.
*/
#ifndef _GAME_H_
#define _GAME_H_
#ifndef _GAME_CORE_H_
#define _GAME_CORE_H_
#include "mainevent.h"
#include "gamedata.h"
#include "sdlrenderer.h"
#include "gamestate.h"
#include <stack>
class GameCore : public MainEvent
using std::stack;
class Game : public GameState
{
public:
GameCore();
int execute();
Game() {}
~Game();
bool init();
void execute(stack<GameState*> &state_stack) throw(StateExit);
protected:
// event handlers
@ -26,14 +31,8 @@ class GameCore : public MainEvent
void on_rbutton_down(int mX, int mY);
void on_key_down(SDLKey sym, SDLMod mod, Uint16 unicode);
private:
bool init();
void render();
void cleanup();
bool is_running;
SDLRenderer renderer;
@ -44,5 +43,4 @@ class GameCore : public MainEvent
static int MAX_MOVE_DISTANCE;
};
#endif

View File

@ -1,71 +0,0 @@
#include "gamecore.h"
#include "mathutils.h"
#include "debug.h"
#include <SDL.h>
int GameCore::NODE_RADIUS = 12;
GameCore::GameCore()
{
is_running = true;
}
int GameCore::execute()
{
if (!init()) return 1;
SDL_Event event;
while (is_running)
{
while(SDL_PollEvent(&event))
handle_event(&event);
// iterate();
renderer.render(data);
}
cleanup();
return 0;
}
bool GameCore::init()
{
if (SDL_Init(SDL_INIT_EVERYTHING) < 0) return false;
SDL_WM_SetCaption("TreeWars","TreeWars");
return renderer.init();
}
void GameCore::cleanup()
{
renderer.cleanup();
SDL_Quit();
}
void GameCore::on_exit()
{
is_running = false;
}
void GameCore::on_lbutton_down(int x, int y)
{
data.do_vertex(x, y, NODE_RADIUS);
}
void GameCore::on_rbutton_down(int mX, int mY)
{
data.clear_current_vertex();
}
void GameCore::on_key_down(SDLKey sym, SDLMod mod, Uint16 unicode)
{
if (sym == SDLK_q && mod & KMOD_CTRL) is_running = false;
if (sym == SDLK_a) data.set_mode(MODE_ATTACK);
if (sym == SDLK_m) data.set_mode(MODE_MOVE);
}

0
gamestate.cpp Normal file
View File

29
gamestate.h Normal file
View File

@ -0,0 +1,29 @@
/* Abstract instance of a game state.
This contains the basic functions for game looping code,
and has a fully-functional event handler we can overload later
*/
#ifndef _GAME_STATE_H_
#define _GAME_STATE_H_
#include "mainevent.h"
#include <exception>
#include <stack>
using std::exception;
using std::stack;
class StateExit : public exception {};
class GameState : public MainEvent
{
public:
GameState() {}
~GameState() {}
virtual bool init() = 0;
virtual void execute(stack<GameState*> &game_state) throw(StateExit) = 0;
};
#endif

View File

@ -1,9 +1,43 @@
/* Do basic initialization, get the loop going */
#include "gamecore.h"
#include "gamestate.h"
#include "game.h"
#include <SDL.h>
int main()
int main(int argc, char** argv)
{
GameCore game_core;
return game_core.execute();
// Barebones setup for our game
if (SDL_Init(SDL_INIT_EVERYTHING) < 0) return false;
SDL_WM_SetCaption("TreeWars","TreeWars");
stack<GameState*> state_stack;
// initialize the stack by initting and pushing the initial state(s)
GameState* tmpstate = new Game();
if (!tmpstate->init()) exit(1);
state_stack.push(tmpstate);
while (!state_stack.empty())
{
GameState* state = state_stack.top();
try {
state->execute(state_stack);
} catch (StateExit& e) {
// remove the old state
state_stack.pop();
delete state;
// init the new state, discarding it if we fail
while (!(state_stack.empty() || state_stack.top()->init()))
{
state_stack.pop();
delete state;
}
}
}
SDL_Quit();
return 0;
}