Laid the groundwork for a more complex game - introduced a couple of bugs (can attack from anywhere, can't select another of your own vertices in attack mode...)
This commit is contained in:
parent
d1c11799f4
commit
4daaced5d7
2
Makefile
2
Makefile
|
@ -7,7 +7,7 @@ LDFLAGS=`sdl-config --libs` -lSDL_ttf
|
|||
OBJECTS=\
|
||||
main.o \
|
||||
drawutils.o mathutils.o timer.o itos.o \
|
||||
graph.o gamedata.o \
|
||||
graph.o gamedata.o player.o \
|
||||
mainevent.o gamestate.o game.o titlescreen.o
|
||||
|
||||
all: $(PROJECT)
|
||||
|
|
12
game.cpp
12
game.cpp
|
@ -5,8 +5,6 @@
|
|||
#include "itos.h"
|
||||
#include <SDL.h>
|
||||
|
||||
int Game::NODE_RADIUS = 10;
|
||||
|
||||
|
||||
Game::Game(stack<GameState*>* state_stack, SDL_Surface* display)
|
||||
: GameState(state_stack, display)
|
||||
|
@ -54,9 +52,12 @@ void Game::render()
|
|||
|
||||
switch(data.get_mode())
|
||||
{
|
||||
case MODE_MOVE:
|
||||
case MODE_BUILD:
|
||||
range_colour = 0x0000ff;
|
||||
break;
|
||||
case MODE_MOVE:
|
||||
range_colour = 0x00ff00;
|
||||
break;
|
||||
case MODE_ATTACK:
|
||||
range_colour = 0xff0000;
|
||||
break;
|
||||
|
@ -68,7 +69,7 @@ void Game::render()
|
|||
list<Vertex*> vertices = data.get_vertices();
|
||||
|
||||
// Now paint on the targeting circle
|
||||
if (data.get_current_vertex() != NULL)
|
||||
if (data.get_current_vertex(true) != NULL)
|
||||
{
|
||||
Vertex* v = data.get_current_vertex();
|
||||
DrawUtils::draw_circle_filled(display, v->x, v->y, range,
|
||||
|
@ -104,7 +105,7 @@ void Game::render()
|
|||
|
||||
void Game::on_lbutton_down(int x, int y)
|
||||
{
|
||||
data.do_vertex(x, y, NODE_RADIUS);
|
||||
if (!data.endgame()) data.handle_click(x, y);
|
||||
}
|
||||
|
||||
|
||||
|
@ -119,4 +120,5 @@ 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);
|
||||
if (sym == SDLK_b) data.set_mode(MODE_BUILD);
|
||||
}
|
||||
|
|
107
gamedata.cpp
107
gamedata.cpp
|
@ -10,102 +10,114 @@ using std::list;
|
|||
int GameData::PLAYER1_COLOUR = 0x4a483f;
|
||||
int GameData::PLAYER2_COLOUR = 0x090c7a;
|
||||
|
||||
int GameData::BASE_MOVE_RADIUS = 75;
|
||||
int GameData::BASE_BUILD_RADIUS = 75;
|
||||
int GameData::NODE_RADIUS = 10;
|
||||
|
||||
GameData::GameData()
|
||||
: Graph(true)
|
||||
{
|
||||
current = NULL;
|
||||
player = PLAYER1;
|
||||
mode = MODE_MOVE;
|
||||
mode = MODE_BUILD;
|
||||
player1 = Player(PLAYER1_COLOUR);
|
||||
player2 = Player(PLAYER2_COLOUR);
|
||||
turn = &player1;
|
||||
}
|
||||
|
||||
GameData::~GameData() { }
|
||||
|
||||
|
||||
Vertex* GameData::get_current_vertex(bool only_mine) const
|
||||
{
|
||||
if (only_mine)
|
||||
{
|
||||
if (current != NULL &&
|
||||
current->colour == turn->get_colour()) return current;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
|
||||
void GameData::toggle_turn()
|
||||
{
|
||||
mode = MODE_MOVE;
|
||||
current = NULL;
|
||||
if (!turn->has_played())
|
||||
{
|
||||
set_mode(MODE_BUILD);
|
||||
turn->set_played();
|
||||
}
|
||||
else set_mode(MODE_SELECT);
|
||||
|
||||
if (!endgame())
|
||||
{
|
||||
if (player == PLAYER1) player = PLAYER2;
|
||||
else if (player == PLAYER2) player = PLAYER1;
|
||||
if (turn == &player1) turn = &player2;
|
||||
else if (turn == &player2) turn = &player1;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GameData::do_vertex(int x, int y, int r)
|
||||
void GameData::handle_click(int x, int y)
|
||||
{
|
||||
if (current != NULL &&
|
||||
(MathUtils::distance(current->x, current->y, current->z, x, y, 0)
|
||||
> get_range()))
|
||||
{
|
||||
select_vertex(x, y);
|
||||
return;
|
||||
}
|
||||
int r = 10;
|
||||
|
||||
int colour;
|
||||
if (player == PLAYER1) colour = PLAYER1_COLOUR;
|
||||
if (player == PLAYER2) colour = PLAYER2_COLOUR;
|
||||
colour = turn->get_colour();
|
||||
|
||||
if (mode == MODE_MOVE)
|
||||
if (mode == MODE_SELECT)
|
||||
{
|
||||
if (point_in_vertex(x, y, 0)) select_vertex(x, y);
|
||||
else add_vertex(x, y, 0, r, colour);
|
||||
}
|
||||
if (mode == MODE_ATTACK)
|
||||
else if (mode == MODE_BUILD)
|
||||
{
|
||||
if (point_in_vertex(x, y, 0)) select_vertex(x, y, true);
|
||||
if (!point_in_vertex(x, y, 0)) add_vertex(x, y, 0, r, colour);
|
||||
}
|
||||
else if (mode == MODE_ATTACK)
|
||||
{
|
||||
Vertex* v = vertex_at(x, y, 0);
|
||||
if (v == NULL) return;
|
||||
|
||||
if (v->colour == colour) select_vertex(x, y);
|
||||
else attack_vertex(v);
|
||||
if (v->colour != colour) attack_vertex(v);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GameData::select_vertex(int x, int y)
|
||||
void GameData::select_vertex(int x, int y, bool only_mine)
|
||||
{
|
||||
Vertex * v = vertex_at(x, y, 0);
|
||||
if (v == NULL) return;
|
||||
|
||||
for (list<Vertex*>::iterator cursor = vertices.begin();
|
||||
cursor != vertices.end(); cursor++)
|
||||
{
|
||||
Vertex* v = *cursor;
|
||||
if ((MathUtils::distance(v->x, v->y, v->z, x, y, 0) <= v->r) &&
|
||||
(v->colour == PLAYER1_COLOUR && player == PLAYER1 ||
|
||||
v->colour == PLAYER2_COLOUR && player == PLAYER2))
|
||||
if (only_mine && v->colour == turn->get_colour())
|
||||
{
|
||||
current = v;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
current = v;
|
||||
}
|
||||
|
||||
|
||||
bool GameData::add_vertex(int x, int y, int z, int r, int colour)
|
||||
{
|
||||
if (mode == MODE_ATTACK) return false;
|
||||
|
||||
if (current == NULL)
|
||||
{
|
||||
// this is the special case for adding the first vertex for each player
|
||||
if ((player == PLAYER1 && !player1_played) ||
|
||||
(player == PLAYER2 && !player2_played))
|
||||
if (!turn->has_played())
|
||||
{
|
||||
Graph::add_vertex(x, y, z, r, colour, 10);
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "debug: GameData::add_vertex(): strength=%2.f\n",
|
||||
calculate_strength(*(vertices.rbegin())));
|
||||
#endif
|
||||
if (player == PLAYER1) player1_played = true;
|
||||
if (player == PLAYER2) player2_played = true;
|
||||
toggle_turn();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (current->colour != turn->get_colour()) return false;
|
||||
|
||||
if (Graph::add_vertex(x, y, z, r, colour, 10, current))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
|
@ -176,15 +188,22 @@ float GameData::calculate_strength_r(Vertex* node, unsigned int depth, list<Vert
|
|||
}
|
||||
|
||||
|
||||
Mode GameData::set_mode(Mode m)
|
||||
{
|
||||
mode = m;
|
||||
}
|
||||
|
||||
|
||||
int GameData::get_range(Vertex* node)
|
||||
{
|
||||
if (node == NULL) node = current;
|
||||
|
||||
if (node == NULL) return 0;
|
||||
else if (mode == MODE_MOVE) return BASE_MOVE_RADIUS;
|
||||
else if (mode == MODE_MOVE) return turn->get_energy();
|
||||
else if (mode == MODE_BUILD) return BASE_BUILD_RADIUS;
|
||||
else if (mode == MODE_ATTACK)
|
||||
{
|
||||
int range = BASE_MOVE_RADIUS;
|
||||
int range = BASE_BUILD_RADIUS;
|
||||
list<Vertex*> neighbors = node->neighbors;
|
||||
|
||||
for(list<Vertex*>::iterator cursor = neighbors.begin();
|
||||
|
@ -223,17 +242,15 @@ void GameData::attack_vertex(Vertex* target)
|
|||
|
||||
bool GameData::endgame()
|
||||
{
|
||||
if (!(player1_played && player2_played)) return false;
|
||||
if (!(player1.has_played() && player2.has_played())) return false;
|
||||
|
||||
if (get_colour(PLAYER1_COLOUR).empty())
|
||||
if (get_colour(player1.get_colour()).empty())
|
||||
{
|
||||
player = WIN2;
|
||||
debug("Gamedata::endgame(): player 2 wins\n");
|
||||
return true;
|
||||
}
|
||||
if (get_colour(PLAYER2_COLOUR).empty())
|
||||
if (get_colour(player2.get_colour()).empty())
|
||||
{
|
||||
player = WIN1;
|
||||
debug("Gamedata::endgame(): player 1 wins\n");
|
||||
return true;
|
||||
}
|
||||
|
|
22
gamedata.h
22
gamedata.h
|
@ -7,9 +7,9 @@
|
|||
#define _GAMEDATA_H_
|
||||
|
||||
#include "graph.h"
|
||||
#include "player.h"
|
||||
|
||||
enum Turn {PLAYER1, PLAYER2, WIN1, WIN2};
|
||||
enum Mode {MODE_MOVE, MODE_ATTACK};
|
||||
enum Mode {MODE_MOVE, MODE_ATTACK, MODE_BUILD, MODE_SELECT};
|
||||
enum VertexType {ATTACKER, DEFENDER, PRODUCER};
|
||||
|
||||
class GameVertex : public Vertex
|
||||
|
@ -25,20 +25,20 @@ class GameData : public Graph
|
|||
GameData();
|
||||
~GameData();
|
||||
|
||||
Vertex* get_current_vertex() const { return current; }
|
||||
Vertex* get_current_vertex(bool only_mine = false) const;
|
||||
void clear_current_vertex() { current = NULL; }
|
||||
|
||||
void toggle_turn();
|
||||
|
||||
// select or add vertex, as appropriate
|
||||
void do_vertex(int x, int y, int r);
|
||||
void select_vertex(int x, int y);
|
||||
void handle_click(int x, int y);
|
||||
void select_vertex(int x, int y, bool only_mine = false);
|
||||
void attack_vertex(Vertex* target);
|
||||
|
||||
bool add_vertex(int x, int y, int z, int r, int colour);
|
||||
|
||||
Mode get_mode() const { return mode; }
|
||||
Mode set_mode(Mode m) { mode = m; }
|
||||
Mode set_mode(Mode m);
|
||||
|
||||
// returns the move/attack range for the specified node
|
||||
// (or the selected node if node == NULL)
|
||||
|
@ -46,22 +46,22 @@ class GameData : public Graph
|
|||
|
||||
// check for (and set, if needed) winner
|
||||
bool endgame();
|
||||
Turn get_turn() const { return player; }
|
||||
Player* get_turn() const { return turn; }
|
||||
float calculate_strength(Vertex* node);
|
||||
|
||||
private:
|
||||
float calculate_strength_r(Vertex* node, unsigned int depth, list<Vertex*>& visited);
|
||||
|
||||
Vertex* current;
|
||||
Turn player;
|
||||
Mode mode;
|
||||
bool player1_played;
|
||||
bool player2_played;
|
||||
Player player1, player2;
|
||||
Player* turn;
|
||||
|
||||
static int PLAYER1_COLOUR;
|
||||
static int PLAYER2_COLOUR;
|
||||
|
||||
static int BASE_MOVE_RADIUS;
|
||||
static int BASE_BUILD_RADIUS;
|
||||
static int NODE_RADIUS;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
28
player.cpp
Normal file
28
player.cpp
Normal file
|
@ -0,0 +1,28 @@
|
|||
#include "player.h"
|
||||
|
||||
Player::Player(unsigned int colour)
|
||||
{
|
||||
this->colour = colour;
|
||||
energy = 50;
|
||||
}
|
||||
|
||||
|
||||
void Player::add_energy(unsigned int amount)
|
||||
{
|
||||
energy += amount;
|
||||
}
|
||||
|
||||
|
||||
bool Player::spend_energy(unsigned int amount)
|
||||
{
|
||||
if (amount > energy) return false;
|
||||
|
||||
energy -= amount;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Player::set_played()
|
||||
{
|
||||
played = true;
|
||||
}
|
27
player.h
Normal file
27
player.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
/* Holds some useful data about each player
|
||||
*/
|
||||
|
||||
#ifndef _PLAYER_H_
|
||||
#define _PLAYER_H_
|
||||
|
||||
class Player
|
||||
{
|
||||
public:
|
||||
Player(unsigned int colour = 0x000000);
|
||||
|
||||
unsigned int get_energy() const { return energy; }
|
||||
unsigned int get_colour() const { return colour; }
|
||||
|
||||
void add_energy(unsigned int amount);
|
||||
bool spend_energy(unsigned int amount);
|
||||
|
||||
bool has_played() const { return played; }
|
||||
void set_played();
|
||||
|
||||
private:
|
||||
unsigned int energy;
|
||||
unsigned int colour;
|
||||
bool played;
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user