diff --git a/Makefile b/Makefile index a37dd7b..6dcfd49 100644 --- a/Makefile +++ b/Makefile @@ -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) diff --git a/game.cpp b/game.cpp new file mode 100644 index 0000000..55e9353 --- /dev/null +++ b/game.cpp @@ -0,0 +1,52 @@ +#include "game.h" +#include "mathutils.h" +#include "debug.h" +#include + +int Game::NODE_RADIUS = 12; + +Game::~Game() +{ + renderer.cleanup(); +} + + +void Game::execute(stack &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); +} diff --git a/gamecore.h b/game.h similarity index 51% rename from gamecore.h rename to game.h index 07216e3..d71d055 100644 --- a/gamecore.h +++ b/game.h @@ -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 -class GameCore : public MainEvent +using std::stack; + + +class Game : public GameState { public: - GameCore(); - int execute(); + Game() {} + ~Game(); + + bool init(); + void execute(stack &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 diff --git a/gamecore.cpp b/gamecore.cpp deleted file mode 100644 index 79c519d..0000000 --- a/gamecore.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include "gamecore.h" -#include "mathutils.h" -#include "debug.h" -#include - -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); -} diff --git a/gamestate.cpp b/gamestate.cpp new file mode 100644 index 0000000..e69de29 diff --git a/gamestate.h b/gamestate.h new file mode 100644 index 0000000..2082ab4 --- /dev/null +++ b/gamestate.h @@ -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 +#include + +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 &game_state) throw(StateExit) = 0; +}; + + +#endif diff --git a/main.cpp b/main.cpp index 46e6417..edecd29 100644 --- a/main.cpp +++ b/main.cpp @@ -1,9 +1,43 @@ /* Do basic initialization, get the loop going */ -#include "gamecore.h" +#include "gamestate.h" +#include "game.h" +#include -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 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; }