Added text field for commands.

This commit is contained in:
Tim Schubert 2016-01-27 12:35:50 +01:00
parent 32eae1e97d
commit 59f054cefb
8 changed files with 287 additions and 37 deletions

View file

@ -3,6 +3,7 @@
void Game::handle_event(SDL_Event *event) void Game::handle_event(SDL_Event *event)
{ {
static SDL_Point window_size; static SDL_Point window_size;
std::string input;
switch (event->type) switch (event->type)
{ {
case (SDL_QUIT): case (SDL_QUIT):
@ -15,6 +16,8 @@ void Game::handle_event(SDL_Event *event)
{ {
case SDL_WINDOWEVENT_SIZE_CHANGED: case SDL_WINDOWEVENT_SIZE_CHANGED:
this->grid->update_dimensions({event->window.data1, event->window.data2}); this->grid->update_dimensions({event->window.data1, event->window.data2});
this->text_input_box->update_dimensions({0, event->window.data2 - 12, event->window.data1,
event->window.data2});
break; break;
default: default:
break; break;
@ -22,45 +25,84 @@ void Game::handle_event(SDL_Event *event)
} }
break; break;
case SDL_MOUSEMOTION: case SDL_MOUSEMOTION:
grid->handle_event(event); if (!this->text_input_box->get_active())
this->field_box->handle_event(event); {
this->upgrade_box->handle_event(event); grid->handle_event(event);
this->field_box->handle_event(event);
this->upgrade_box->handle_event(event);
}
break; break;
case SDL_MOUSEWHEEL: case SDL_MOUSEWHEEL:
grid->handle_event(event); if (!this->text_input_box->get_active())
{
grid->handle_event(event);
}
break; break;
case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONDOWN:
this->grid->handle_event(event); if (!this->text_input_box->get_active())
this->field_box->handle_event(event); {
this->upgrade_box->handle_event(event); this->grid->handle_event(event);
this->field_box->handle_event(event);
this->upgrade_box->handle_event(event);
this->next_turn_button->handle_event(event);
}
break; break;
case SDL_KEYDOWN: case SDL_KEYDOWN:
switch (event->key.keysym.sym) switch (event->key.keysym.sym)
{ {
case SDLK_w: case SDLK_w:
this->move[0] = true; if (!this->text_input_box->get_active())
this->move[0] = true;
break; break;
case SDLK_a: case SDLK_a:
this->move[1] = true; if (!this->text_input_box->get_active())
this->move[1] = true;
break; break;
case SDLK_s: case SDLK_s:
this->move[2] = true; if (!this->text_input_box->get_active())
this->move[2] = true;
break; break;
case SDLK_d: case SDLK_d:
this->move[3] = true; if (!this->text_input_box->get_active())
this->move[3] = true;
break; break;
case SDLK_f: case SDLK_f:
window_size = this->window->toggle_fullscreen(); if (!this->text_input_box->get_active())
this->grid->update_dimensions(window_size); {
this->field_box->update_position({0, 20}); window_size = this->window->toggle_fullscreen();
this->upgrade_box->set_visible(false); this->grid->update_dimensions(window_size);
this->text_input_box->update_dimensions({0, window_size.y - window_size.x, 12});
this->next_turn_button->update_position({window_size.x - 100, window_size.y - 100});
this->upgrade_box->set_visible(false);
}
break; break;
case SDLK_ESCAPE: case SDLK_ESCAPE:
this->quit = true; if (this->text_input_box->get_active())
{
this->text_input_box->stop();
this->test_box->set_visible(false);
}
else
{
this->text_input_box->start();
this->test_box->set_visible(true);
}
break;
case SDLK_RETURN:
input = this->text_input_box->get_input();
if (input == "/quit")
{
this->quit = true;
}
break; break;
default: default:
break; break;
} }
if (this->text_input_box->get_active())
{
this->text_input_box->handle_event(event);
}
break; break;
case SDL_KEYUP: case SDL_KEYUP:
switch (event->key.keysym.sym) switch (event->key.keysym.sym)
@ -81,6 +123,17 @@ void Game::handle_event(SDL_Event *event)
break; break;
} }
break; break;
case SDL_TEXTINPUT:
if (this->text_input_box->get_active())
{
this->text_input_box->handle_event(event);
}
break;
case SDL_TEXTEDITING:
if (this->text_input_box->get_active())
{
this->text_input_box->handle_event(event);
}
default: default:
if (event->type == BOB_MARKERUPDATE if (event->type == BOB_MARKERUPDATE
|| event->type == BOB_NEXTROUNDEVENT || event->type == BOB_NEXTROUNDEVENT
@ -92,18 +145,6 @@ void Game::handle_event(SDL_Event *event)
this->field_box->handle_event(event); this->field_box->handle_event(event);
this->upgrade_box->handle_event(event); this->upgrade_box->handle_event(event);
} }
else
{
if (event->type == BOB_NEXTTURNEVENT)
{
this->current_player++;
if (Player::current_player == Player::players.end())
{
Player::current_player = Player::players.begin();
trigger_event(BOB_NEXTROUNDEVENT, 0x0, (void *) *(Player::current_player), nullptr);
}
}
}
break; break;
} }
} }
@ -151,6 +192,8 @@ void Game::render()
this->test_box->render(this->renderer); this->test_box->render(this->renderer);
this->field_box->render(this->renderer); this->field_box->render(this->renderer);
this->upgrade_box->render(this->renderer); this->upgrade_box->render(this->renderer);
this->next_turn_button->render(this->renderer);
this->text_input_box->render(this->renderer);
this->renderer->present(); this->renderer->present();
} }
catch (const SDL_RendererException &err) catch (const SDL_RendererException &err)
@ -189,7 +232,7 @@ int main(int, char **)
} }
SDL_Rect bounds; SDL_Rect bounds;
SDL_GetDisplayBounds(0, &bounds); SDL_GetDisplayBounds(0, &bounds);
SDL_Rect window_dimensions = {SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, bounds.w, bounds.h}; SDL_Rect window_dimensions = {SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 600, 600};
Game *game = new Game(&window_dimensions, 20); Game *game = new Game(&window_dimensions, 20);
int exit_status = 1; int exit_status = 1;
exit_status = game->game_loop(); exit_status = game->game_loop();

View file

@ -29,10 +29,14 @@ public:
} }
this->quit = false; this->quit = false;
SDL_Color fg = {0x00, 0x00, 0x00, 0xff}; SDL_Color fg = {0x00, 0x00, 0x00, 0xff};
this->players = std::vector<Player *>();
Player *default_player = new Player();
this->players.push_back(default_player);
try try
{ {
this->font = load_font_from_file("/usr/share/fonts/dejavu/DejaVuSans.ttf", 12); this->font = load_font_from_file("/usr/share/fonts/dejavu/DejaVuSans.ttf", 12);
this->window = new Window(TITLE, window_dimensions, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN); this->window = new Window(TITLE, window_dimensions, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
SDL_Point window_size = this->window->get_size();
this->renderer = new Renderer(this->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC this->renderer = new Renderer(this->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC
| SDL_RENDERER_TARGETTEXTURE); | SDL_RENDERER_TARGETTEXTURE);
this->grid = new HexagonGrid(size, this->layout, this->renderer); this->grid = new HexagonGrid(size, this->layout, this->renderer);
@ -41,6 +45,12 @@ public:
this->upgrade_box = new UpgradeBox(this->renderer, {0, 0, 1, 1}, fg, this->font, center); this->upgrade_box = new UpgradeBox(this->renderer, {0, 0, 1, 1}, fg, this->font, center);
this->test_box = new TextBox(this->renderer, {0, 0, 1, 1}, fg, this->font); this->test_box = new TextBox(this->renderer, {0, 0, 1, 1}, fg, this->font);
this->test_box->set_visible(true); this->test_box->set_visible(true);
this->next_turn_button = new NextTurnButtonBox(this->renderer,
{window_size.x - 100, window_size.y - 100, 1, 1}, fg,
this->font, &(this->players));
this->text_input_box = new TextInputBox(this->renderer, {0, window_size.y - 12, window_size.x, 12}, fg,
this->font);
this->text_input_box->stop();
} }
catch (const SDL_Exception &sdl_except) catch (const SDL_Exception &sdl_except)
{ {
@ -52,6 +62,12 @@ public:
~Game() ~Game()
{ {
for (auto player : this->players)
{
delete player;
}
delete text_input_box;
delete this->next_turn_button;
delete this->test_box; delete this->test_box;
delete this->upgrade_box; delete this->upgrade_box;
delete this->field_box; delete this->field_box;
@ -70,7 +86,9 @@ public:
int game_loop(); int game_loop();
private: private:
TextInputBox *text_input_box;
std::vector<Player *> players;
NextTurnButtonBox *next_turn_button;
UpgradeBox *upgrade_box; UpgradeBox *upgrade_box;
FieldBox *field_box; FieldBox *field_box;
TextBox *test_box; TextBox *test_box;

View file

@ -6,6 +6,8 @@ const Uint32 BOB_FIELDUPDATEEVENT = register_events(1);
const Uint32 BOB_FIELDSELECTEDEVENT = register_events(1); const Uint32 BOB_FIELDSELECTEDEVENT = register_events(1);
const Uint32 BOB_FIELDUPGRADEVENT = register_events(1); const Uint32 BOB_FIELDUPGRADEVENT = register_events(1);
const Uint32 BOB_NEXTTURNEVENT = register_events(1); const Uint32 BOB_NEXTTURNEVENT = register_events(1);
const Uint32 BOB_ATTACKEVENTS = register_events(1);
bool Timer::MOUSE_LOCKED = false; bool Timer::MOUSE_LOCKED = false;

View file

@ -13,6 +13,7 @@ extern const Uint32 BOB_FIELDUPDATEEVENT;
extern const Uint32 BOB_FIELDSELECTEDEVENT; extern const Uint32 BOB_FIELDSELECTEDEVENT;
extern const Uint32 BOB_FIELDUPGRADEVENT; extern const Uint32 BOB_FIELDUPGRADEVENT;
extern const Uint32 BOB_NEXTTURNEVENT; extern const Uint32 BOB_NEXTTURNEVENT;
extern const Uint32 BOB_ATTACKEVENTS;
#endif #endif
Uint32 register_events(Uint32 n); Uint32 register_events(Uint32 n);

View file

@ -1,6 +1,6 @@
#include "Gameplay.hpp" #include "Gameplay.hpp"
static std::vector<Player *>::iterator Player::current_player = Player::players.end(); Player *Player::current_player = nullptr;
SDL_Point operator+(SDL_Point left, SDL_Point right) SDL_Point operator+(SDL_Point left, SDL_Point right)
{ {
@ -315,6 +315,8 @@ void FieldMeta::load(SDL_Renderer *renderer, Layout *layout)
} }
if (this->owner->get_id().is_nil()) if (this->owner->get_id().is_nil())
color = {0x77, 0x77, 0x77, 0xff}; color = {0x77, 0x77, 0x77, 0xff};
if (this->fighting)
color = {0x0, 0x77, 0x77, 0xff};
filledPolygonRGBA(renderer, vx, vy, 6, color.r, color.g, color.b, 0x77); filledPolygonRGBA(renderer, vx, vy, 6, color.r, color.g, color.b, 0x77);
SDL_Color inverse; SDL_Color inverse;
inverse.r = (Uint8) (color.r + 0x77); inverse.r = (Uint8) (color.r + 0x77);
@ -420,6 +422,8 @@ void HexagonGrid::render(Renderer *renderer)
void HexagonGrid::handle_event(SDL_Event *event) void HexagonGrid::handle_event(SDL_Event *event)
{ {
Player *attacking;
Player *owner;
SDL_Point mouse = {0, 0}; SDL_Point mouse = {0, 0};
SDL_GetMouseState(&mouse.x, &mouse.y); SDL_GetMouseState(&mouse.x, &mouse.y);
int scroll = this->layout->size / 10 * event->wheel.y; int scroll = this->layout->size / 10 * event->wheel.y;
@ -472,7 +476,23 @@ void HexagonGrid::handle_event(SDL_Event *event)
trigger_event(BOB_FIELDSELECTEDEVENT, 0, (void *) this->marker, nullptr); trigger_event(BOB_FIELDSELECTEDEVENT, 0, (void *) this->marker, nullptr);
break; break;
case SDL_BUTTON_LEFT: case SDL_BUTTON_LEFT:
trigger_event(BOB_FIELDSELECTEDEVENT, 1, (void *) this->marker, nullptr); owner = this->marker->get_owner();
if (*owner == *(Player::current_player))
{
if (this->first_attack != nullptr)
{
this->first_attack->set_fighting(false);
}
this->first_attack = this->marker;
this->first_attack->set_fighting(true);
}
else if (this->first_attack != nullptr)
{
attacking = this->first_attack->get_owner();
attacking->fight(this->marker);
this->first_attack->set_fighting(false);
this->first_attack = nullptr;
}
break; break;
default: default:
break; break;

View file

@ -543,8 +543,8 @@ public:
return !(*this == rhs); return !(*this == rhs);
} }
static std::vector<Player *> players; static Player *current_player;
static std::vector<Player *>::iterator current_player;
private: private:
boost::uuids::uuid uuid; boost::uuids::uuid uuid;
SDL_Color color; SDL_Color color;
@ -561,6 +561,7 @@ public:
FieldMeta(HexagonGrid *grid_, Field field_, Player *owner_) FieldMeta(HexagonGrid *grid_, Field field_, Player *owner_)
: grid(grid_), field(field_), owner(owner_) : grid(grid_), field(field_), owner(owner_)
{ {
this->fighting = false;
this->upgrades = 0; this->upgrades = 0;
static std::random_device rd; static std::random_device rd;
std::mt19937 rng(rd()); std::mt19937 rng(rd());
@ -601,7 +602,11 @@ public:
FieldMeta *get_neighbor(Uint8 direction); FieldMeta *get_neighbor(Uint8 direction);
bool get_fighting() { return this->fighting; }
void set_fighting(bool state) { this->fighting = state; }
private: private:
bool fighting;
const Field field; const Field field;
HexagonGrid *grid; HexagonGrid *grid;
Player *owner; Player *owner;
@ -620,6 +625,7 @@ public:
HexagonGrid(Sint16 grid_radius, Layout *layout_, Renderer *renderer_) HexagonGrid(Sint16 grid_radius, Layout *layout_, Renderer *renderer_)
: layout(layout_), radius(grid_radius), renderer(renderer_) : layout(layout_), radius(grid_radius), renderer(renderer_)
{ {
this->first_attack = nullptr;
this->texture = nullptr; this->texture = nullptr;
this->panning = false; this->panning = false;
std::unordered_map<Field, FieldMeta *> fields = std::unordered_map<Field, FieldMeta *>(); std::unordered_map<Field, FieldMeta *> fields = std::unordered_map<Field, FieldMeta *>();
@ -681,6 +687,7 @@ public:
private: private:
bool changed; bool changed;
FieldMeta *first_attack;
Renderer *renderer; Renderer *renderer;
SDL_Texture *texture; SDL_Texture *texture;
std::unordered_map<Field, FieldMeta *> fields; std::unordered_map<Field, FieldMeta *> fields;

View file

@ -21,6 +21,7 @@ TTF_Font *load_font_from_file(std::string path_to_file, int size)
bool TextBox::load_text(std::string text) bool TextBox::load_text(std::string text)
{ {
this->renderer->set_draw_color({0, 0, 0, 0xff});
const char *displayed_text = text.c_str(); const char *displayed_text = text.c_str();
SDL_Surface *text_surface = TTF_RenderUTF8_Blended_Wrapped(this->font, displayed_text, this->color, 100); SDL_Surface *text_surface = TTF_RenderUTF8_Blended_Wrapped(this->font, displayed_text, this->color, 100);
if (text_surface == nullptr) if (text_surface == nullptr)
@ -196,7 +197,10 @@ void UpgradeButtonBox::handle_event(const SDL_Event *event)
if (inside_target(&(this->dimensions), &pos)) if (inside_target(&(this->dimensions), &pos))
{ {
FieldMeta *field = this->box->get_field(); FieldMeta *field = this->box->get_field();
field->upgrade(this->upgrade); if (*(Player::current_player) == *(field->get_owner()))
{
field->upgrade(this->upgrade);
}
} }
} }
} }
@ -276,4 +280,111 @@ void FieldBox::update_position(SDL_Point point)
{ {
this->dimensions.x = point.x; this->dimensions.x = point.x;
this->dimensions.y = point.y - this->dimensions.h - 6; this->dimensions.y = point.y - this->dimensions.h - 6;
}
void NextTurnButtonBox::handle_event(const SDL_Event *event)
{
if (event->type == SDL_MOUSEBUTTONDOWN)
{
SDL_Point mouse;
SDL_GetMouseState(&(mouse.x), &(mouse.y));
if (inside_target(&(this->dimensions), &mouse))
{
Player *last_player = Player::current_player;
this->current_player = this->current_player + 1;
if (this->current_player == players->end())
{
this->current_player = players->begin();
trigger_event(BOB_NEXTROUNDEVENT, 0, last_player, Player::current_player);
}
else
{
trigger_event(BOB_NEXTTURNEVENT, 0, last_player, Player::current_player);
}
Player::current_player = *(this->current_player);
std::ostringstream text;
text << "NEXT TURN" << "\n\n" << Player::current_player->get_name();
this->load_text(text.str());
}
}
}
void TextInputBox::start()
{
this->visible = true;
SDL_StartTextInput();
}
void TextInputBox::stop()
{
this->visible = false;
SDL_StopTextInput();
}
void TextInputBox::handle_event(const SDL_Event *event)
{
bool changed = false;
if (event->type == SDL_KEYDOWN)
{
if (event->key.keysym.sym == SDLK_RETURN)
{
this->input = "";
changed = true;
}
else if (event->key.keysym.sym == SDLK_BACKSPACE && this->input.length() > 0)
{
input.pop_back();
changed = true;
}
else if (event->key.keysym.sym == SDLK_c && SDL_GetModState() & KMOD_CTRL)
{
SDL_SetClipboardText(input.c_str());
changed = true;
}
else if (event->key.keysym.sym == SDLK_v && SDL_GetModState() & KMOD_CTRL)
{
input = SDL_GetClipboardText();
}
}
else if (event->type == SDL_TEXTINPUT)
{
if (!((event->text.text[0] == 'c' || event->text.text[0] == 'C')
&& (event->text.text[0] == 'v' || event->text.text[0] == 'V') && SDL_GetModState() & KMOD_CTRL))
{
input += event->text.text;
changed = true;
}
}
else if (event->type == SDL_TEXTEDITING)
{
// nothin atm
}
if (changed)
{
std::string foo = input; // because SDL_ttf will complain if not
foo += " ";
this->load_text(foo);
}
}
void TextInputBox::render(Renderer *ext_renderer)
{
if (this->texture != nullptr && this->visible)
{
ext_renderer->set_draw_color({0xff, 0xff, 0xff, 0x00});
SDL_RenderFillRect(ext_renderer->get_renderer(), &(bg_dimensions));
ext_renderer->copy(this->texture, nullptr, &(this->dimensions));
}
}
void TextInputBox::update_dimensions(SDL_Rect rect)
{
this->bg_dimensions = rect;
this->dimensions = bg_dimensions;
}
bool TextInputBox::get_active()
{
return SDL_IsTextInputActive() == SDL_TRUE;
} }

View file

@ -61,6 +61,35 @@ protected:
TTF_Font *font; TTF_Font *font;
}; };
class TextInputBox : TextBox
{
public:
TextInputBox(Renderer *renderer_, SDL_Rect dimensions_, SDL_Color color_, TTF_Font *font_)
: TextBox(renderer_, dimensions_, color_, font_), bg_dimensions(dimensions_), input("")
{
this->visible = false;
this->load_text(" ");
}
void start();
void stop();
bool get_active();
void handle_event(const SDL_Event *event);
void render(Renderer *ext_renderer);
void update_dimensions(SDL_Rect rect);
std::string get_input() { return this->input; }
private:
SDL_Rect bg_dimensions;
std::string input;
};
class FieldBox : public TextBox class FieldBox : public TextBox
{ {
public: public:
@ -98,10 +127,29 @@ private:
bool active; // this upgrade has been unlocked bool active; // this upgrade has been unlocked
}; };
/*class NextTurnButtonBox : public TextBox class NextTurnButtonBox : public TextBox
{ {
public:
NextTurnButtonBox(Renderer *renderer, SDL_Rect dimensions, SDL_Color color, TTF_Font *font_,
std::vector<Player *> *players_)
: TextBox(renderer, dimensions, color, font_), players(players_)
{
this->current_player = this->players->begin();
Player::current_player = *(this->current_player);
std::ostringstream text;
// Warning, next line looks ugly @.@
text << "NEXT TURN" << "\n\n" << (*(this->current_player))->get_name();
this->load_text(text.str());
this->visible = true;
}
void handle_event(const SDL_Event *event);
private:
std::vector<Player *> *players;
std::vector<Player *>::iterator current_player;
}; };
*/
class UpgradeBox : public Box class UpgradeBox : public Box
{ {