Added ability to actually build different unit types, as well as icons to distinguish them
|
@ -7,7 +7,10 @@ SDL_Surface* DrawUtils::load(string file)
|
||||||
SDL_Surface* raw = NULL;
|
SDL_Surface* raw = NULL;
|
||||||
SDL_Surface* cooked = NULL;
|
SDL_Surface* cooked = NULL;
|
||||||
|
|
||||||
raw = SDL_LoadBMP(file.c_str());
|
string full_path = "res/";
|
||||||
|
full_path += file;
|
||||||
|
|
||||||
|
raw = SDL_LoadBMP(full_path.c_str());
|
||||||
if (raw == NULL) return NULL;
|
if (raw == NULL) return NULL;
|
||||||
|
|
||||||
cooked = SDL_DisplayFormat(raw);
|
cooked = SDL_DisplayFormat(raw);
|
||||||
|
|
70
game.cpp
|
@ -11,6 +11,10 @@ Game::Game(stack<GameState*>* state_stack, SDL_Surface* display)
|
||||||
{
|
{
|
||||||
background = NULL;
|
background = NULL;
|
||||||
font = NULL;
|
font = NULL;
|
||||||
|
|
||||||
|
attacker_icon = NULL;
|
||||||
|
defender_icon = NULL;
|
||||||
|
producer_icon = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -32,21 +36,22 @@ Game::~Game()
|
||||||
bool Game::init()
|
bool Game::init()
|
||||||
{
|
{
|
||||||
background = DrawUtils::load("background.bmp");
|
background = DrawUtils::load("background.bmp");
|
||||||
|
|
||||||
if (background == NULL)
|
|
||||||
{
|
|
||||||
debug("Game::init(): error: Couldn't load background image");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
font = TTF_OpenFont("LiberationSans-Regular.ttf", 12);
|
font = TTF_OpenFont("LiberationSans-Regular.ttf", 12);
|
||||||
|
attacker_icon = DrawUtils::load("attacker_icon.bmp");
|
||||||
|
defender_icon = DrawUtils::load("defender_icon.bmp");
|
||||||
|
producer_icon = DrawUtils::load("producer_icon.bmp");
|
||||||
|
|
||||||
if (font == NULL)
|
if (background == NULL || font == NULL || attacker_icon == NULL ||
|
||||||
|
defender_icon == NULL || producer_icon == NULL)
|
||||||
{
|
{
|
||||||
debug("Game::init(): error: Couldn't load font");
|
debug("Game::init(): error: Couldn't load some resource(s)");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DrawUtils::transpare(attacker_icon);
|
||||||
|
DrawUtils::transpare(defender_icon);
|
||||||
|
DrawUtils::transpare(producer_icon);
|
||||||
|
|
||||||
int row1 = display->h - 95;
|
int row1 = display->h - 95;
|
||||||
int row2 = display->h - 50;
|
int row2 = display->h - 50;
|
||||||
int col1 = 155;
|
int col1 = 155;
|
||||||
|
@ -102,13 +107,11 @@ void Game::render()
|
||||||
range_colour);
|
range_colour);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now paint each vertex, and any edges that it needs
|
// First draw the edges, so that they don't obscure any data
|
||||||
for (list<Vertex*>::iterator cursor = vertices.begin();
|
for (list<Vertex*>::iterator cursor = vertices.begin();
|
||||||
cursor != vertices.end(); cursor++)
|
cursor != vertices.end(); cursor++)
|
||||||
{
|
{
|
||||||
Vertex* v = *cursor;
|
Vertex* v = *cursor;
|
||||||
DrawUtils::draw_circle_filled(display, v->x, v->y, v->r,
|
|
||||||
v->colour);
|
|
||||||
|
|
||||||
for (list<Vertex*>::iterator subcursor = v->neighbors.begin();
|
for (list<Vertex*>::iterator subcursor = v->neighbors.begin();
|
||||||
subcursor != v->neighbors.end(); subcursor++)
|
subcursor != v->neighbors.end(); subcursor++)
|
||||||
|
@ -119,16 +122,6 @@ void Game::render()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add hit points on top of the nodes
|
|
||||||
for (list<Vertex*>::iterator cursor = vertices.begin();
|
|
||||||
cursor != vertices.end(); cursor++)
|
|
||||||
{
|
|
||||||
Vertex* v = *cursor;
|
|
||||||
|
|
||||||
DrawUtils::draw_text(display, itos(v->score), v->x, v->y, font,
|
|
||||||
0x00ff00, true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ring the selected vertex and write info about it
|
// ring the selected vertex and write info about it
|
||||||
if (data.get_current_vertex() != NULL)
|
if (data.get_current_vertex() != NULL)
|
||||||
{
|
{
|
||||||
|
@ -137,6 +130,14 @@ void Game::render()
|
||||||
draw_stats(v);
|
draw_stats(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Draw each node
|
||||||
|
for (list<Vertex*>::iterator cursor = vertices.begin();
|
||||||
|
cursor != vertices.end(); cursor++)
|
||||||
|
{
|
||||||
|
Vertex* v = *cursor;
|
||||||
|
draw_node(v);
|
||||||
|
}
|
||||||
|
|
||||||
// draw the rest of the bottom menu
|
// draw the rest of the bottom menu
|
||||||
|
|
||||||
// horizontal line across the whole thing
|
// horizontal line across the whole thing
|
||||||
|
@ -190,6 +191,29 @@ void Game::draw_button(MenuButton* button)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Game::draw_node(Vertex* v)
|
||||||
|
{
|
||||||
|
DrawUtils::draw_circle_filled(display, v->x, v->y, v->r,
|
||||||
|
v->colour);
|
||||||
|
|
||||||
|
DrawUtils::draw_text(display, itos(v->score), v->x, v->y, font,
|
||||||
|
0x00ff00, true, true);
|
||||||
|
|
||||||
|
switch (dynamic_cast<GameVertex*>(v)->type)
|
||||||
|
{
|
||||||
|
case VERTEX_ATTACKER:
|
||||||
|
DrawUtils::draw(display, attacker_icon, v->x + 5, v-> y + 5);
|
||||||
|
break;
|
||||||
|
case VERTEX_DEFENDER:
|
||||||
|
DrawUtils::draw(display, defender_icon, v->x + 5, v-> y + 5);
|
||||||
|
break;
|
||||||
|
case VERTEX_PRODUCER:
|
||||||
|
DrawUtils::draw(display, producer_icon, v->x + 5, v-> y + 5);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Game::handle_button_press(ButtonAction action)
|
void Game::handle_button_press(ButtonAction action)
|
||||||
{
|
{
|
||||||
switch (action)
|
switch (action)
|
||||||
|
@ -225,7 +249,7 @@ void Game::draw_stats(Vertex* v)
|
||||||
DrawUtils::draw_text(display, "player:", x, y, font);
|
DrawUtils::draw_text(display, "player:", x, y, font);
|
||||||
DrawUtils::draw_text(display, dynamic_cast<GameVertex*>(v)->player->get_name(), x + 50, y, font);
|
DrawUtils::draw_text(display, dynamic_cast<GameVertex*>(v)->player->get_name(), x + 50, y, font);
|
||||||
|
|
||||||
DrawUtils::draw_text(display, "str:", x, y + 14, font);
|
DrawUtils::draw_text(display, "atk:", x, y + 14, font);
|
||||||
DrawUtils::draw_text(display, itos(data.calculate_strength(v)),
|
DrawUtils::draw_text(display, itos(data.calculate_strength(v)),
|
||||||
x + 50, y + 14, font);
|
x + 50, y + 14, font);
|
||||||
|
|
||||||
|
|
4
game.h
|
@ -40,6 +40,7 @@ class Game : public GameState
|
||||||
private:
|
private:
|
||||||
void draw_stats(Vertex* v);
|
void draw_stats(Vertex* v);
|
||||||
void draw_button(MenuButton* button);
|
void draw_button(MenuButton* button);
|
||||||
|
void draw_node(Vertex* v);
|
||||||
|
|
||||||
void handle_button_press(ButtonAction action);
|
void handle_button_press(ButtonAction action);
|
||||||
|
|
||||||
|
@ -52,6 +53,9 @@ class Game : public GameState
|
||||||
// surfaces containing textures to draw
|
// surfaces containing textures to draw
|
||||||
SDL_Surface* background;
|
SDL_Surface* background;
|
||||||
TTF_Font* font;
|
TTF_Font* font;
|
||||||
|
SDL_Surface* attacker_icon;
|
||||||
|
SDL_Surface* defender_icon;
|
||||||
|
SDL_Surface* producer_icon;
|
||||||
|
|
||||||
// menu buttons
|
// menu buttons
|
||||||
list<MenuButton*> buttons;
|
list<MenuButton*> buttons;
|
||||||
|
|
30
gamedata.cpp
|
@ -31,7 +31,7 @@ GameData::GameData()
|
||||||
player1 = Player("player 1", PLAYER1_COLOUR);
|
player1 = Player("player 1", PLAYER1_COLOUR);
|
||||||
player2 = Player("player 2", PLAYER2_COLOUR);
|
player2 = Player("player 2", PLAYER2_COLOUR);
|
||||||
turn = &player1;
|
turn = &player1;
|
||||||
build_type = VERTEX_NONE;
|
build_type = VERTEX_PRODUCER; // first vertex is always a producer
|
||||||
}
|
}
|
||||||
|
|
||||||
GameData::~GameData() { }
|
GameData::~GameData() { }
|
||||||
|
@ -67,8 +67,16 @@ void GameData::toggle_turn()
|
||||||
if (turn == &player1) turn = &player2;
|
if (turn == &player1) turn = &player2;
|
||||||
else if (turn == &player2) turn = &player1;
|
else if (turn == &player2) turn = &player1;
|
||||||
|
|
||||||
if (!turn->has_played()) mode = MODE_BUILD;
|
if (!turn->has_played())
|
||||||
else mode = MODE_SELECT;
|
{
|
||||||
|
mode = MODE_BUILD;
|
||||||
|
build_type = VERTEX_PRODUCER;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mode = MODE_SELECT;
|
||||||
|
build_type = VERTEX_NONE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
current = NULL;
|
current = NULL;
|
||||||
|
@ -125,8 +133,9 @@ bool GameData::select_vertex(int x, int y)
|
||||||
|
|
||||||
bool GameData::add_vertex(int x, int y, int z, int r, int colour)
|
bool GameData::add_vertex(int x, int y, int z, int r, int colour)
|
||||||
{
|
{
|
||||||
GameVertex* v = new GameVertex(x, y, z, r, colour, 10, VERTEX_ATTACKER,
|
if (build_type == VERTEX_NONE) return false;
|
||||||
turn);
|
|
||||||
|
GameVertex* v = new GameVertex(x, y, z, r, colour, 10, build_type, turn);
|
||||||
|
|
||||||
if (current == NULL)
|
if (current == NULL)
|
||||||
{
|
{
|
||||||
|
@ -182,7 +191,9 @@ bool GameData::add_vertex(int x, int y, int z, int r, int colour)
|
||||||
float GameData::calculate_armor(Vertex* node)
|
float GameData::calculate_armor(Vertex* node)
|
||||||
{
|
{
|
||||||
float str = calculate_strength(node);
|
float str = calculate_strength(node);
|
||||||
return str / 10;
|
float armor = str / 10;
|
||||||
|
if (armor < 1) armor = 1;
|
||||||
|
return armor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -287,16 +298,13 @@ int GameData::get_range(Vertex* node)
|
||||||
void GameData::attack_vertex(Vertex* target)
|
void GameData::attack_vertex(Vertex* target)
|
||||||
{
|
{
|
||||||
float atk = calculate_strength(current);
|
float atk = calculate_strength(current);
|
||||||
float armor = calculate_armor(current);
|
float armor = calculate_armor(target);
|
||||||
|
|
||||||
int damage = (int)(atk / armor);
|
int damage = (int)(atk / armor);
|
||||||
|
|
||||||
target->score -= damage;
|
target->score -= damage;
|
||||||
|
|
||||||
if (target->score <= 0) remove_vertex(target);
|
if (target->score <= 0) remove_vertex(target);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr, "debug: GameData::attack_vertex(): atk=%.2f, armor=%.2f, armor=%.2f, damage=%d\n", atk, armor, damage);
|
fprintf(stderr, "debug: GameData::attack_vertex(): atk=%.2f, armor=%.2f, damage=%d\n", atk, armor, damage);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
toggle_turn();
|
toggle_turn();
|
||||||
|
|
|
@ -17,7 +17,7 @@ class GameVertex : public Vertex
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GameVertex(int x, int y, int z, int r, int colour = 0, int score = 0,
|
GameVertex(int x, int y, int z, int r, int colour = 0, int score = 0,
|
||||||
VertexType type = VERTEX_ATTACKER, Player* player = NULL);
|
VertexType type = VERTEX_NONE, Player* player = NULL);
|
||||||
|
|
||||||
VertexType type;
|
VertexType type;
|
||||||
Player* player;
|
Player* player;
|
||||||
|
|
BIN
res/attacker_icon.bmp
Normal file
After Width: | Height: | Size: 822 B |
Before Width: | Height: | Size: 2.3 MiB After Width: | Height: | Size: 2.3 MiB |
BIN
res/defender_icon.bmp
Normal file
After Width: | Height: | Size: 822 B |
BIN
res/producer_icon.bmp
Normal file
After Width: | Height: | Size: 822 B |
Before Width: | Height: | Size: 286 KiB After Width: | Height: | Size: 286 KiB |