Huge refactor with the basic goal of reducing complexity in the Game class. Broke a couple of small things in the process - still working on fixing them back up

This commit is contained in:
Anna Rose 2011-07-06 14:24:37 -04:00
parent 12bbcb7f23
commit 42e2e43ead
5 changed files with 169 additions and 60 deletions

View File

@ -8,7 +8,7 @@ OBJECTS=\
main.o \ main.o \
drawutils.o mathutils.o timer.o itos.o \ drawutils.o mathutils.o timer.o itos.o \
graph.o gamedata.o player.o vertex.o gamevertex.o \ graph.o gamedata.o player.o vertex.o gamevertex.o \
menubutton.o \ entity.o menubutton.o \
mainevent.o gamestate.o game.o titlescreen.o mainevent.o gamestate.o game.o titlescreen.o
all: $(PROJECT) all: $(PROJECT)

110
game.cpp
View File

@ -4,7 +4,7 @@
#include "debug.h" #include "debug.h"
#include "itos.h" #include "itos.h"
#include <SDL.h> #include <SDL.h>
using std::pair;
Game::Game(stack<GameState*>* state_stack, SDL_Surface* display) Game::Game(stack<GameState*>* state_stack, SDL_Surface* display)
: GameState(state_stack, display) : GameState(state_stack, display)
@ -76,10 +76,34 @@ bool Game::init()
BUTTON_END_TURN)); BUTTON_END_TURN));
for (list<MenuButton*>::iterator cursor = buttons.begin();
cursor != buttons.end(); cursor++)
{
if (!(*cursor)->init())
{
debug("Failed to initialize a button");
throw StateExit();
}
}
mode_changed();
return GameState::init(); return GameState::init();
} }
void Game::iterate()
{
// handle the button iterations
for (list<MenuButton*>::iterator cursor = buttons.begin();
cursor != buttons.end(); cursor++)
{
(*cursor)->iterate();
}
}
void Game::render() void Game::render()
{ {
int range = data.get_range(); int range = data.get_range();
@ -142,7 +166,22 @@ void Game::render()
} }
// draw the rest of the bottom menu // draw the rest of the bottom menu
draw_menu_bars();
for (list<MenuButton*>::iterator cursor = buttons.begin();
cursor != buttons.end(); cursor++)
{
(*cursor)->render(display);
}
draw_player_info();
SDL_Flip(display);
}
void Game::draw_menu_bars()
{
// horizontal line across the whole thing // horizontal line across the whole thing
DrawUtils::draw_line(display, 0, display->h - 100, DrawUtils::draw_line(display, 0, display->h - 100,
display->w, display->h - 100, 2, 0x000000); display->w, display->h - 100, 2, 0x000000);
@ -155,51 +194,6 @@ void Game::render()
DrawUtils::draw_line(display, display->w - 100, display->h - 100, DrawUtils::draw_line(display, display->w - 100, display->h - 100,
display->w - 100, display->h, 2, display->w - 100, display->h, 2,
0x000000); 0x000000);
for (list<MenuButton*>::iterator cursor = buttons.begin();
cursor != buttons.end(); cursor++)
{
MenuButton* button = *cursor;
if (!(button->get_action() & BUTTON_END_TURN) &&
(data.get_current_vertex() == NULL ||
data.get_current_vertex()->player != data.get_turn()))
continue;
if ((button->get_action() & (BUTTON_BUILD_ATTACKER |
BUTTON_BUILD_DEFENDER |
BUTTON_BUILD_PRODUCER)) &&
data.get_mode() != MODE_BUILD)
continue;
draw_button(button);
}
draw_player_info();
SDL_Flip(display);
}
void Game::draw_button(MenuButton* button)
{
int colour = 0x000000;
ButtonAction action = button->get_action();
Mode mode = data.get_mode();
VertexType build_type = data.get_build_type();
// fixme - there's really got to be a better way...
if ((action == BUTTON_BUILD && mode == MODE_BUILD) ||
(action == BUTTON_ATTACK && mode == MODE_ATTACK) ||
(action == BUTTON_MOVE && mode == MODE_MOVE) ||
(action == BUTTON_BUILD_ATTACKER && build_type == VERTEX_ATTACKER) ||
(action == BUTTON_BUILD_DEFENDER && build_type == VERTEX_DEFENDER) ||
(action == BUTTON_BUILD_PRODUCER && build_type == VERTEX_PRODUCER)
)
colour = 0x0000ff;
else if (button->is_at(cursor_x, cursor_y)) colour = 0xff0000;
button->draw(display, colour);
} }
@ -331,17 +325,24 @@ void Game::on_lbutton_down(int x, int y)
cursor != buttons.end(); cursor++) cursor != buttons.end(); cursor++)
{ {
MenuButton* button = *cursor; MenuButton* button = *cursor;
if (button->is_at(x, y)) handle_button_press(button->get_action()); if (button->is_at(x, y))
{
handle_button_press(button->get_action());
mode_changed();
return;
}
} }
if (y > display->h - 110) return; if (y > display->h - 110) return;
if (!data.endgame()) data.handle_click(x, y); if (!data.endgame()) data.handle_click(x, y);
mode_changed();
} }
void Game::on_rbutton_down(int mX, int mY) void Game::on_rbutton_down(int mX, int mY)
{ {
data.clear_current_vertex(); data.clear_current_vertex();
mode_changed();
} }
@ -357,6 +358,8 @@ void Game::on_key_down(SDLKey sym, SDLMod mod, Uint16 unicode)
else if (sym == SDLK_s || sym == SDLK_ESCAPE) data.set_mode(MODE_SELECT); else if (sym == SDLK_s || sym == SDLK_ESCAPE) data.set_mode(MODE_SELECT);
else if (sym == SDLK_e) data.toggle_turn(); else if (sym == SDLK_e) data.toggle_turn();
mode_changed();
#ifdef DEBUG #ifdef DEBUG
if (sym == SDLK_d && mod & (KMOD_ALT | KMOD_CTRL)) print_debug_info(); if (sym == SDLK_d && mod & (KMOD_ALT | KMOD_CTRL)) print_debug_info();
#endif #endif
@ -377,3 +380,16 @@ void Game::print_debug_info()
fprintf(stderr, "Turn: %s\n", data.get_turn()->get_name().c_str()); fprintf(stderr, "Turn: %s\n", data.get_turn()->get_name().c_str());
} }
#endif #endif
void Game::mode_changed()
{
// Set the state for each button
for (list<MenuButton*>::iterator cursor = buttons.begin();
cursor != buttons.end(); cursor++)
{
(*cursor)->set_state(data.get_mode(), data.get_build_type(),
data.get_current_vertex());
}
}

5
game.h
View File

@ -28,7 +28,7 @@ class Game : public GameState
protected: protected:
void render(); void render();
void iterate() {} void iterate();
// event handlers // event handlers
void on_lbutton_down(int x, int y); void on_lbutton_down(int x, int y);
@ -39,11 +39,12 @@ class Game : public GameState
private: private:
void draw_stats(GameVertex* v); void draw_stats(GameVertex* v);
void draw_button(MenuButton* button);
void draw_node(GameVertex* v); void draw_node(GameVertex* v);
void draw_player_info(); void draw_player_info();
void draw_menu_bars();
void handle_button_press(ButtonAction action); void handle_button_press(ButtonAction action);
void mode_changed();
// data // data
GameData data; GameData data;

View File

@ -3,7 +3,8 @@
MenuButton::MenuButton(string text, TTF_Font* font, int x, int y, MenuButton::MenuButton(string text, TTF_Font* font, int x, int y,
ButtonAction action) ButtonAction action, int colour, int hover_colour,
int selected_colour, int background_colour)
{ {
this->text = text; this->text = text;
this->x = x; this->x = x;
@ -11,29 +12,99 @@ MenuButton::MenuButton(string text, TTF_Font* font, int x, int y,
this->font = font; this->font = font;
this->action = action; this->action = action;
this->colour = colour;
this->hover_colour = hover_colour;
this->selected_colour = selected_colour;
this->background_colour = background_colour;
}
bool MenuButton::init()
{
hover = false; hover = false;
selected = false;
visible = true;
return true;
} }
void MenuButton::set_hover(bool is_hovering) void MenuButton::set_selected(bool is_selected)
{ {
hover = is_hovering; selected = is_selected;
} }
void MenuButton::draw(SDL_Surface* display, int colour, int background_colour) void MenuButton::set_visible(bool is_visible)
{ {
visible = is_visible;
}
void MenuButton::iterate()
{
int x, y;
SDL_GetMouseState(&x, &y);
if (is_at(x, y)) hover = true;
else hover = false;
}
void MenuButton::render(SDL_Surface* display)
{
if (!visible) return;
int colour_to_use = colour;
if (selected) colour_to_use = selected_colour;
else if (hover) colour_to_use = hover_colour;
SDL_Rect pen = {x, y, 80, 20}; SDL_Rect pen = {x, y, 80, 20};
SDL_FillRect(display, &pen, background_colour); SDL_FillRect(display, &pen, background_colour);
int temp_colour = 0x000000; int temp_colour = 0x000000;
DrawUtils::draw_text(display, text, x + 40, y + 10, font, colour, 1, 1); DrawUtils::draw_text(display, text, x + 40, y + 10, font, colour_to_use,
1, 1);
} }
bool MenuButton::is_at(int test_x, int test_y) bool MenuButton::is_at(int test_x, int test_y)
{ {
if (!visible) return false;
return test_x >= x && test_y >= y && test_x <= x + 100 && test_y <= y + 40; return test_x >= x && test_y >= y && test_x <= x + 100 && test_y <= y + 40;
} }
void MenuButton::set_state(Mode mode, VertexType type, GameVertex* current)
{
selected = false;
visible = false;
if (action & BUTTON_END_TURN)
{
visible = true;
return;
}
if ((mode & MODE_ATTACK && action & BUTTON_ATTACK) ||
(mode & MODE_MOVE && action & BUTTON_MOVE) ||
(mode & MODE_BUILD && action & BUTTON_BUILD) ||
(type & VERTEX_ATTACKER && action & BUTTON_BUILD_ATTACKER) ||
(type & VERTEX_DEFENDER && action & BUTTON_BUILD_DEFENDER) ||
(type & VERTEX_PRODUCER && action & BUTTON_BUILD_PRODUCER)
)
selected = true;
// If we have selected one of our vertices, and we're one of the three
// main buttons, be visible
if (current != NULL && action & (BUTTON_ATTACK | BUTTON_MOVE |
BUTTON_BUILD))
visible = true;
// If we're one of the other three, and we're in MODE_BUILD, we're visible
if (mode & MODE_BUILD && action & (BUTTON_BUILD_ATTACKER |
BUTTON_BUILD_DEFENDER |
BUTTON_BUILD_PRODUCER))
visible = true;
}

View File

@ -8,6 +8,9 @@
#include <SDL.h> #include <SDL.h>
#include <SDL_ttf.h> #include <SDL_ttf.h>
#include <string> #include <string>
#include "entity.h"
#include "gamedata.h"
#include "gamevertex.h"
using std::string; using std::string;
@ -17,27 +20,45 @@ enum ButtonAction {BUTTON_BUILD=0x1, BUTTON_ATTACK=0x2, BUTTON_MOVE=0x4,
BUTTON_BUILD_ATTACKER=0x8, BUTTON_BUILD_DEFENDER=0x10, BUTTON_BUILD_ATTACKER=0x8, BUTTON_BUILD_DEFENDER=0x10,
BUTTON_BUILD_PRODUCER=0x20, BUTTON_END_TURN=0x40}; BUTTON_BUILD_PRODUCER=0x20, BUTTON_END_TURN=0x40};
class MenuButton class MenuButton : public Entity
{ {
public: public:
MenuButton(string text = "", TTF_Font* font = NULL, int x = 0, int y = 0, MenuButton(string text = "", TTF_Font* font = NULL, int x = 0, int y = 0,
ButtonAction action = BUTTON_BUILD); ButtonAction action = BUTTON_BUILD, int colour=0x000000,
int hover_colour=0xff0000, int selected_colour=0x0000ff,
int background_colour=0x888888);
// Selectable buttons change colour for the duration they are selected, // Selectable buttons change colour for the duration they are selected,
// and should ignore clicks while selected // and should ignore clicks while selected
void set_hover(bool is_hovering); void set_selected(bool is_selected);
void draw(SDL_Surface* display, int colour = 0x000000, void set_visible(bool is_visible);
int background_colour = 0x888888);
bool init();
void render(SDL_Surface* display);
void iterate();
bool is_at(int test_x, int test_y); bool is_at(int test_x, int test_y);
ButtonAction get_action() const { return action; } ButtonAction get_action() const { return action; }
// To get some complexity out of the Game class, let's teach MenuButton
// how to handle her own state, based on the current Mode and VertexType
// This isn't wonderful coupling, but it'll do
void set_state(Mode mode, VertexType type, GameVertex* current);
private: private:
string text; string text;
int x; int x;
int y; int y;
int colour;
int hover_colour;
int selected_colour;
int background_colour;
bool hover; bool hover;
bool selected;
bool visible;
TTF_Font* font; TTF_Font* font;