Fix include guard position. Move contents of Grid.*pp to Gameplay.*pp to avoid a circular dependency.
This commit is contained in:
parent
ac0d35e053
commit
100065e158
11 changed files with 536 additions and 528 deletions
22
src/Bob.cpp
22
src/Bob.cpp
|
@ -21,13 +21,13 @@ void Game::handle_event(SDL_Event *event)
|
|||
}
|
||||
break;
|
||||
case SDL_MOUSEMOTION:
|
||||
grid->handle_event(event);
|
||||
grid->handle_event(event, this->event_context);
|
||||
break;
|
||||
case SDL_MOUSEWHEEL:
|
||||
grid->handle_event(event);
|
||||
grid->handle_event(event, this->event_context);
|
||||
break;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
grid->handle_event(event);
|
||||
grid->handle_event(event, this->event_context);
|
||||
break;
|
||||
case SDL_KEYDOWN:
|
||||
switch (event->key.keysym.sym)
|
||||
|
@ -73,6 +73,14 @@ void Game::handle_event(SDL_Event *event)
|
|||
break;
|
||||
}
|
||||
break;
|
||||
case SDL_USEREVENT:
|
||||
switch (event->type - this->event_context->base_event)
|
||||
{
|
||||
case BOB_NEXTTURNEVENT:
|
||||
this->grid->handle_event(event, this->event_context);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -86,15 +94,15 @@ int Game::game_loop()
|
|||
Uint32 frame_counter = 0;
|
||||
while (!this->quit)
|
||||
{
|
||||
if (move_timer->get_timer() > 16)
|
||||
if (this->move_timer->get_timer() > 16)
|
||||
{
|
||||
move_timer->reset_timer();
|
||||
this->move_timer->reset_timer();
|
||||
SDL_Point move_by = {(this->move[1] - this->move[3]) * 20, (this->move[0] - this->move[2]) * 20};
|
||||
this->grid->move(move_by);
|
||||
}
|
||||
if (frame_timer->get_timer() > 255)
|
||||
if (this->frame_timer->get_timer() > 255)
|
||||
{
|
||||
fps = frame_counter / (frame_timer->reset_timer() / 1000.0);
|
||||
fps = frame_counter / (this->frame_timer->reset_timer() / 1000.0);
|
||||
frame_counter = 0;
|
||||
this->test_box->load_text(std::to_string(fps));
|
||||
}
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
#ifndef _BOB_H
|
||||
#define _BOB_H
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
@ -9,9 +12,6 @@
|
|||
#include "Events.hpp"
|
||||
#include "Gui.hpp"
|
||||
|
||||
#ifndef _BOB_H
|
||||
#define _BOB_H
|
||||
|
||||
const int SCREEN_WIDTH = 800;
|
||||
const int SCREEN_HEIGTH = 600;
|
||||
const int SIDEBAR_WIDTH = 200;
|
||||
|
@ -23,7 +23,7 @@ class Game
|
|||
public:
|
||||
Game(SDL_Rect *window_dimensions, Sint16 size)
|
||||
{
|
||||
this->event_context = new EventContext(4);
|
||||
this->event_context = new EventContext();
|
||||
this->layout = new Layout(pointy_orientation, size,
|
||||
{window_dimensions->w / 2, window_dimensions->h / 2},
|
||||
{0, 0, window_dimensions->w - SIDEBAR_WIDTH, window_dimensions->h});
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
add_executable(Bob Bob.cpp Bob.hpp Grid.cpp Grid.hpp Gameplay.cpp Gameplay.hpp Gui.hpp Gui.cpp Events.cpp Exceptions.hpp)
|
||||
add_executable(Bob Bob.cpp Bob.hpp Gameplay.cpp Gameplay.hpp Gui.hpp Gui.cpp Events.cpp Exceptions.hpp)
|
||||
target_link_libraries(Bob ${SDL2_LIB} ${SDL2_GFX_LIB} ${SDL2_TTF_LIB} ${Boost_LIBRARIES})
|
|
@ -21,9 +21,4 @@ Uint32 Timer::reset_timer()
|
|||
Uint32 EventContext::register_events(Uint32 num_events)
|
||||
{
|
||||
return SDL_RegisterEvents(num_events);
|
||||
}
|
||||
|
||||
Uint32 EventContext::get_event(Bob_Event event)
|
||||
{
|
||||
return this->base_event + event;
|
||||
}
|
|
@ -1,27 +1,26 @@
|
|||
#include <SDL2/SDL.h>
|
||||
#include <boost/uuid/uuid.hpp>
|
||||
#include "Grid.hpp"
|
||||
#include "Gameplay.hpp"
|
||||
|
||||
#ifndef _EVENTS_H
|
||||
#define _EVENTS_H
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
#include <boost/uuid/uuid.hpp>
|
||||
|
||||
enum Bob_Event
|
||||
{
|
||||
BOB_NEXTTURNEVENT,
|
||||
BOB_FIELDUPDATEEVENT
|
||||
};
|
||||
|
||||
class EventContext
|
||||
{
|
||||
public:
|
||||
enum Bob_Event
|
||||
{
|
||||
Bob_NextTurnEvent,
|
||||
Bob_FieldUpdateEvent
|
||||
};
|
||||
|
||||
EventContext(Uint32 num_events)
|
||||
EventContext()
|
||||
: base_event(register_events(num_events)) { }
|
||||
|
||||
Uint32 get_event(Bob_Event event);
|
||||
const Uint32 base_event;
|
||||
|
||||
private:
|
||||
const Uint32 base_event;
|
||||
|
||||
static const int num_events = 2;
|
||||
|
||||
static Uint32 register_events(Uint32 n);
|
||||
};
|
||||
|
@ -46,7 +45,9 @@ struct NextTurn
|
|||
|
||||
struct FieldUpdate
|
||||
{
|
||||
FieldMeta *field;
|
||||
Sint16 x;
|
||||
Sint16 y;
|
||||
Sint16 z;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,9 +1,9 @@
|
|||
#include <stdexcept>
|
||||
#include <SDL2/SDL_ttf.h>
|
||||
|
||||
#ifndef BOB_EXCEPTIONS_H
|
||||
#define BOB_EXCEPTIONS_H
|
||||
|
||||
#include <stdexcept>
|
||||
#include <SDL2/SDL_ttf.h>
|
||||
|
||||
class SDL_Exception : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
|
|
201
src/Gameplay.cpp
201
src/Gameplay.cpp
|
@ -1,5 +1,129 @@
|
|||
#include "Gameplay.hpp"
|
||||
|
||||
SDL_Point operator+(SDL_Point left, SDL_Point right)
|
||||
{
|
||||
return {left.x + right.x, left.y + right.y};
|
||||
}
|
||||
|
||||
SDL_Point operator-(SDL_Point left, SDL_Point right)
|
||||
{
|
||||
return {left.x - right.x, left.y - right.y};
|
||||
}
|
||||
|
||||
SDL_Point operator*(SDL_Point left, SDL_Point right)
|
||||
{
|
||||
return {left.x * right.x, left.y * right.y};
|
||||
}
|
||||
|
||||
SDL_Point operator/(SDL_Point left, SDL_Point right)
|
||||
{
|
||||
return {(left.x / right.x), (left.x / right.y)};
|
||||
}
|
||||
|
||||
SDL_Point operator*(double left, SDL_Point right)
|
||||
{
|
||||
int x = (int) (left * right.x);
|
||||
int y = (int) (left * right.y);
|
||||
return {x, y};
|
||||
}
|
||||
|
||||
SDL_Point operator*(SDL_Point left, double right)
|
||||
{
|
||||
return right * left;
|
||||
}
|
||||
|
||||
SDL_Point operator/(SDL_Point left, double right)
|
||||
{
|
||||
return (1 / right) * left;
|
||||
}
|
||||
|
||||
double operator!(SDL_Point left)
|
||||
{
|
||||
double length = std::sqrt(left.x * left.x + left.y * left.y);
|
||||
return length;
|
||||
}
|
||||
|
||||
Field Field::cubic_round(double x, double y, double z)
|
||||
{
|
||||
Sint8 round_x = (Sint8) std::round(x);
|
||||
Sint8 round_y = (Sint8) std::round(y);
|
||||
Sint8 round_z = (Sint8) std::round(z);
|
||||
double x_err = std::abs(round_x - x);
|
||||
double y_err = std::abs(round_y - y);
|
||||
double z_err = std::abs(round_z - z);
|
||||
if (x_err > y_err && x_err > z_err)
|
||||
{
|
||||
round_x = -round_y - round_z;
|
||||
} else if (y_err > z_err)
|
||||
{
|
||||
round_y = -round_x - round_z;
|
||||
} else
|
||||
{
|
||||
round_z = -round_x - round_y;
|
||||
}
|
||||
return Field(round_x, round_y, round_z);
|
||||
}
|
||||
|
||||
|
||||
Field Field::hex_direction(Uint8 direction)
|
||||
{
|
||||
assert (0 <= direction && direction <= 5);
|
||||
return hex_directions[direction];
|
||||
}
|
||||
|
||||
Field Field::get_neighbor(Uint8 direction) const
|
||||
{
|
||||
return hex_direction(direction) + *this;
|
||||
}
|
||||
|
||||
Point Field::field_to_point(const Layout *layout) const
|
||||
{
|
||||
const Orientation m = layout->orientation;
|
||||
double x = (m.f0 * this->x + m.f1 * this->y) * layout->size;
|
||||
double y = (m.f2 * this->x + m.f3 * this->y) * layout->size;
|
||||
return {x + layout->origin.x, y + layout->origin.y};
|
||||
}
|
||||
|
||||
Field Point::point_to_field(const Layout *layout) const
|
||||
{
|
||||
const Orientation m = layout->orientation;
|
||||
double rel_x = (this->x - layout->origin.x) / layout->size;
|
||||
double rel_y = (this->y - layout->origin.y) / layout->size;
|
||||
double x = m.b0 * rel_x + m.b1 * rel_y;
|
||||
double y = m.b2 * rel_x + m.b3 * rel_y;
|
||||
return Field::cubic_round(x, y, -x - y);
|
||||
}
|
||||
|
||||
Point field_corner_offset(Uint8 corner, const Layout *layout)
|
||||
{
|
||||
double angle = 2.0 * M_PI * (corner + layout->orientation.start_angle) / 6;
|
||||
double x = (layout->size * cos(angle));
|
||||
double y = (layout->size * sin(angle));
|
||||
return {x, y};
|
||||
}
|
||||
|
||||
std::vector<Point> Field::field_to_polygon(const Layout *layout) const
|
||||
{
|
||||
std::vector<Point> corners = this->field_to_polygon_normalized(layout);
|
||||
Point center = this->field_to_point(layout);
|
||||
for (Point &p : corners)
|
||||
{
|
||||
p = p + center;
|
||||
}
|
||||
return corners;
|
||||
}
|
||||
|
||||
std::vector<Point> Field::field_to_polygon_normalized(const Layout *layout) const
|
||||
{
|
||||
std::vector<Point> corners;
|
||||
for (uint8_t i = 0; i < 6; i++)
|
||||
{
|
||||
Point offset = field_corner_offset(i, layout);
|
||||
corners.push_back(offset);
|
||||
}
|
||||
return corners;
|
||||
}
|
||||
|
||||
void FieldMeta::render(SDL_Renderer *renderer, Layout *layout)
|
||||
{
|
||||
Point precise_location = this->field.field_to_point(layout);
|
||||
|
@ -23,37 +147,34 @@ void FieldMeta::render(SDL_Renderer *renderer, Layout *layout)
|
|||
inverse.g = (Uint8) (0xff - color.g);
|
||||
inverse.b = (Uint8) (0xff - color.b);
|
||||
inverse.a = 0xff;
|
||||
|
||||
Uint16 resource_size = (Uint16) (layout->size / 3);
|
||||
if (this->resources_base.circle > 0)
|
||||
{
|
||||
circleRGBA(renderer, (Sint16) (location.x), (Sint16) (location.y), (Sint16) (resource_size), inverse.r,
|
||||
inverse.g, inverse.b, inverse.a);
|
||||
}
|
||||
double resource_size = layout->size / 4;
|
||||
if (this->resources_base.triangle > 0)
|
||||
{
|
||||
static const SDL_Point trigon[] = {{-1, 1},
|
||||
{1, 1},
|
||||
{0, -1}};
|
||||
static const SDL_Point trigon[] = {{0, -1},
|
||||
{-1, 1},
|
||||
{1, 1}};
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
vx[i] = (Sint16) (location.x + (trigon[i].x) * resource_size);
|
||||
vy[i] = (Sint16) (location.y + (trigon[i].y) * resource_size);
|
||||
vx[i] = (Sint16) (location.x + (trigon[i].x * resource_size));
|
||||
vy[i] = (Sint16) (location.y + (trigon[i].y * resource_size));
|
||||
}
|
||||
trigonRGBA(renderer, vx[0], vy[0], vx[1], vy[1], vx[2], vy[2], inverse.r, inverse.g, inverse.b, inverse.a);
|
||||
}
|
||||
|
||||
if (this->resources_base.circle > 0)
|
||||
{
|
||||
circleRGBA(renderer, (Sint16) (location.x), Sint16(location.y), (Sint16) resource_size, inverse.r, inverse.g,
|
||||
inverse.b, inverse.a);
|
||||
}
|
||||
if (this->resources_base.square > 0)
|
||||
{
|
||||
|
||||
static const SDL_Point square[] = {{-1, -1},
|
||||
{-1, 1},
|
||||
{1, 1},
|
||||
{1, -1}};
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
vx[i] = (Sint16) (location.x + (square[i].x) * resource_size);
|
||||
vy[i] = (Sint16) (location.y + (square[i].y) * resource_size);
|
||||
vx[i] = (Sint16) (location.x + square[i].x * resource_size);
|
||||
vy[i] = (Sint16) (location.y + square[i].y * resource_size);
|
||||
}
|
||||
polygonRGBA(renderer, vx, vy, 4, inverse.r, inverse.g, inverse.b, inverse.a);
|
||||
}
|
||||
|
@ -190,9 +311,16 @@ bool Player::fight(FieldMeta *field)
|
|||
return false;
|
||||
}
|
||||
|
||||
void FieldMeta::handle_event(const SDL_Event *event)
|
||||
void FieldMeta::handle_event(const SDL_Event *event, EventContext *context)
|
||||
{
|
||||
this->regenerate_resources();
|
||||
switch (event->type - context->base_event)
|
||||
{
|
||||
case BOB_FIELDUPDATEEVENT:
|
||||
this->regenerate_resources();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool HexagonGrid::render(SDL_Renderer *renderer)
|
||||
|
@ -222,15 +350,16 @@ bool HexagonGrid::render(SDL_Renderer *renderer)
|
|||
return true;
|
||||
}
|
||||
|
||||
void Grid::handle_event(SDL_Event *event)
|
||||
void Grid::handle_event(SDL_Event *event, EventContext *context)
|
||||
{
|
||||
if (event->type == SDL_MOUSEWHEEL)
|
||||
SDL_Point mouse = {0, 0};
|
||||
SDL_GetMouseState(&mouse.x, &mouse.y);
|
||||
int scroll = this->layout->size / 10 * event->wheel.y;
|
||||
double old_size = this->layout->size;
|
||||
SDL_Point old_origin = this->layout->origin;
|
||||
switch (event->type)
|
||||
{
|
||||
SDL_Point mouse = {0, 0};
|
||||
SDL_GetMouseState(&mouse.x, &mouse.y);
|
||||
int scroll = this->layout->size / 10 * event->wheel.y;
|
||||
double old_size = this->layout->size;
|
||||
SDL_Point old_origin = this->layout->origin;
|
||||
case SDL_MOUSEWHEEL:
|
||||
if (old_size + scroll < 10)
|
||||
{
|
||||
this->layout->size = 10;
|
||||
|
@ -244,9 +373,8 @@ void Grid::handle_event(SDL_Event *event)
|
|||
this->layout->size += scroll;
|
||||
}
|
||||
this->move(((1.0 - (double) this->layout->size / old_size) * (mouse - old_origin)));
|
||||
}
|
||||
if (event->type == SDL_MOUSEMOTION)
|
||||
{
|
||||
break;
|
||||
case SDL_MOUSEMOTION:
|
||||
if (this->panning)
|
||||
{
|
||||
SDL_Point mouse = {0, 0};
|
||||
|
@ -258,10 +386,19 @@ void Grid::handle_event(SDL_Event *event)
|
|||
this->move(mouse - p);
|
||||
}
|
||||
this->update_marker();
|
||||
}
|
||||
if (event->type == SDL_MOUSEBUTTONDOWN && event->button.button == SDL_BUTTON_MIDDLE)
|
||||
{
|
||||
this->panning = !(this->panning);
|
||||
break;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
switch (event->button.button)
|
||||
{
|
||||
case SDL_BUTTON_MIDDLE:
|
||||
this->panning = !(this->panning);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
333
src/Gameplay.hpp
333
src/Gameplay.hpp
|
@ -1,22 +1,339 @@
|
|||
#ifndef _GAMEPLAY_H
|
||||
#define _GAMEPLAY_H
|
||||
|
||||
#include <random>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
#include <assert.h>
|
||||
#include <bitset>
|
||||
#include <unordered_set>
|
||||
#include <unordered_map>
|
||||
#include <boost/uuid/uuid.hpp>
|
||||
#include <boost/uuid/uuid_generators.hpp>
|
||||
#include <boost/random/mersenne_twister.hpp>
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL_pixels.h>
|
||||
#include <SDL2/SDL_render.h>
|
||||
#include <bitset>
|
||||
#include "Grid.hpp"
|
||||
#include <stdexcept>
|
||||
|
||||
#ifndef _GAMEPLAY_H
|
||||
#define _GAMEPLAY_H
|
||||
#include <SDL2/SDL2_gfxPrimitives.h>
|
||||
#include "Events.hpp"
|
||||
|
||||
#define NUM_UPGRADES 10
|
||||
|
||||
SDL_Point operator+(SDL_Point left, SDL_Point right);
|
||||
|
||||
SDL_Point operator-(SDL_Point left, SDL_Point right);
|
||||
|
||||
SDL_Point operator*(SDL_Point left, SDL_Point right);
|
||||
|
||||
SDL_Point operator/(SDL_Point left, SDL_Point right);
|
||||
|
||||
SDL_Point operator/(SDL_Point left, SDL_Point right);
|
||||
|
||||
SDL_Point operator*(double left, SDL_Point right);
|
||||
|
||||
SDL_Point operator*(SDL_Point left, double right);
|
||||
|
||||
SDL_Point operator/(SDL_Point left, double right);
|
||||
|
||||
double operator!(SDL_Point left);
|
||||
|
||||
struct Orientation
|
||||
{
|
||||
// cubic to point
|
||||
const double f0, f1, f2, f3;
|
||||
// point to cubic
|
||||
const double b0, b1, b2, b3;
|
||||
// in multiples of 60 deg
|
||||
const double start_angle;
|
||||
|
||||
Orientation(double f0_, double f1_, double f2_, double f3_, double b0_, double b1_, double b2_, double b3_,
|
||||
double start_angle_)
|
||||
: f0(f0_), f1(f1_), f2(f2_), f3(f3_), b0(b0_), b1(b1_), b2(b2_), b3(b3_),
|
||||
start_angle(start_angle_) { }
|
||||
};
|
||||
|
||||
const Orientation pointy_orientation = Orientation(sqrt(3.0), sqrt(3.0) / 2.0, 0.0, 3.0 / 2.0, sqrt(3.0) / 3.0,
|
||||
-1.0 / 3.0, 0.0, 2.0 / 3.0, 0.5);
|
||||
const Orientation flat_orientation = Orientation(3.0 / 2.0, 0.0, sqrt(3.0) / 2.0, sqrt(3.0), 2.0 / 3.0, 0.0, -1.0 / 3.0,
|
||||
sqrt(3.0) / 3.0, 0);
|
||||
|
||||
struct Layout
|
||||
{
|
||||
const Orientation orientation;
|
||||
Sint16 size;
|
||||
SDL_Point origin;
|
||||
SDL_Rect box;
|
||||
|
||||
Layout(Orientation orientation_, Sint16 size_, SDL_Point origin_, SDL_Rect box_)
|
||||
: orientation(orientation_), size(size_), origin(origin_), box(box_) { }
|
||||
};
|
||||
|
||||
struct Field;
|
||||
|
||||
struct Point
|
||||
{
|
||||
double x;
|
||||
double y;
|
||||
|
||||
Point(double x_, double y_) : x(x_), y(y_) { }
|
||||
|
||||
bool operator==(const Point &rhs) const
|
||||
{
|
||||
return (this->x == rhs.x && this->y == rhs.y);
|
||||
}
|
||||
|
||||
inline bool operator!=(const Point &rhs) const
|
||||
{
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
Point &operator+=(const Point &rhs)
|
||||
{
|
||||
this->x += rhs.x;
|
||||
this->y += rhs.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend Point operator+(Point lhs, const Point &rhs)
|
||||
{
|
||||
lhs += rhs;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
Point &operator-=(const Point &rhs)
|
||||
{
|
||||
this->x -= rhs.x;
|
||||
this->y -= rhs.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend Point operator-(Point lhs, const Point &rhs)
|
||||
{
|
||||
lhs -= rhs;
|
||||
return rhs;
|
||||
}
|
||||
|
||||
Point &operator*=(const Point &rhs)
|
||||
{
|
||||
this->x *= rhs.x;
|
||||
this->y *= rhs.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend Point operator*(Point lhs, const Point &rhs)
|
||||
{
|
||||
lhs *= rhs;
|
||||
return rhs;
|
||||
}
|
||||
|
||||
Point &operator/=(const Point &rhs)
|
||||
{
|
||||
this->x /= rhs.x;
|
||||
this->y /= rhs.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend Point operator/(Point lhs, const Point &rhs)
|
||||
{
|
||||
lhs /= rhs;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
Point &operator*=(const double &rhs)
|
||||
{
|
||||
this->x *= rhs;
|
||||
this->y *= rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend Point operator*(Point lhs, const double &rhs)
|
||||
{
|
||||
lhs *= rhs;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
Point &operator/=(const double &rhs)
|
||||
{
|
||||
this->x /= rhs;
|
||||
this->y /= rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend Point operator/(Point lhs, const double &rhs)
|
||||
{
|
||||
lhs /= rhs;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
double operator!()
|
||||
{
|
||||
return std::sqrt(this->x * this->x + this->y * this->y);
|
||||
}
|
||||
|
||||
Field point_to_field(const Layout *layout) const;
|
||||
};
|
||||
|
||||
struct Field
|
||||
{
|
||||
Sint16 x, y, z;
|
||||
|
||||
Field(Sint16 x_, Sint16 y_, Sint16 z_) : x(x_), y(y_), z(z_)
|
||||
{
|
||||
assert(x + y + z == 0);
|
||||
}
|
||||
|
||||
bool operator==(const Field &rhs) const
|
||||
{
|
||||
return (this->x == rhs.x && this->y == rhs.y);
|
||||
}
|
||||
|
||||
inline bool operator!=(const Field &rhs) const
|
||||
{
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
Field &operator+=(const Field &rhs)
|
||||
{
|
||||
this->x += rhs.x;
|
||||
this->y += rhs.y;
|
||||
this->z += rhs.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend Field operator+(Field lhs, const Field &rhs)
|
||||
{
|
||||
lhs += rhs;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
Field &operator-=(const Field &rhs)
|
||||
{
|
||||
this->x -= rhs.x;
|
||||
this->y -= rhs.y;
|
||||
this->z -= rhs.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend Field operator-(Field lhs, const Field &rhs)
|
||||
{
|
||||
lhs -= rhs;
|
||||
return rhs;
|
||||
}
|
||||
|
||||
Field &operator*=(const Field &rhs)
|
||||
{
|
||||
this->x *= rhs.x;
|
||||
this->y *= rhs.y;
|
||||
this->z *= rhs.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend Field operator*(Field lhs, const Field &rhs)
|
||||
{
|
||||
lhs *= rhs;
|
||||
return rhs;
|
||||
}
|
||||
|
||||
Field &operator/=(const Field &rhs)
|
||||
{
|
||||
double x = this->x / rhs.x;
|
||||
double y = this->y / rhs.y;
|
||||
double z = this->z / rhs.z;
|
||||
Field f = cubic_round(x, y, z);
|
||||
*this = f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend Field operator/(Field lhs, const Field &rhs)
|
||||
{
|
||||
lhs /= rhs;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
Field &operator*=(const double &rhs)
|
||||
{
|
||||
double x = this->x * rhs;
|
||||
double y = this->y * rhs;
|
||||
double z = this->z * rhs;
|
||||
Field f = cubic_round(x, y, z);
|
||||
*this = f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend Field operator*(Field lhs, const double &rhs)
|
||||
{
|
||||
lhs *= rhs;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
Field &operator/=(const double &rhs)
|
||||
{
|
||||
double x = this->x / rhs;
|
||||
double y = this->y / rhs;
|
||||
double z = this->z / rhs;
|
||||
Field f = cubic_round(x, y, z);
|
||||
*this = f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend Field operator/(Field lhs, const double &rhs)
|
||||
{
|
||||
lhs /= rhs;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
int operator&(const Field &rhs)
|
||||
{
|
||||
return (abs(this->x - rhs.x) + abs(this->y - rhs.y) + abs(this->z - rhs.z)) / 2;
|
||||
}
|
||||
|
||||
Field get_neighbor(Uint8 direction) const;
|
||||
|
||||
Point field_to_point(const Layout *layout) const;
|
||||
|
||||
std::vector<Point> field_to_polygon_normalized(const Layout *layout) const;
|
||||
|
||||
std::vector<Point> field_to_polygon(const Layout *layout) const;
|
||||
|
||||
static Field cubic_round(double x, double y, double z);
|
||||
|
||||
static Field hex_direction(Uint8 direction);
|
||||
};
|
||||
|
||||
// from upper right corner
|
||||
const std::vector<Field> hex_directions = {Field(1, 0, -1), Field(0, 1, -1), Field(-1, 1, 0), Field(-1, 0, 1),
|
||||
Field(-1, 1, 0)};
|
||||
|
||||
Point field_corner_offset(Uint8 corner, const Layout *layout);
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<>
|
||||
struct hash<Field>
|
||||
{
|
||||
size_t operator()(const Field &f) const
|
||||
{
|
||||
hash<Sint16> int_hash;
|
||||
size_t hx = int_hash(f.x);
|
||||
size_t hy = int_hash(f.y);
|
||||
// hz would be redundant, since f.z is redundant
|
||||
// combine hashes
|
||||
return hx ^ (hy + 0x9e3779b9 + (hx << 6) + (hx >> 2));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
inline std::ostream &operator<<(std::ostream &os, const Field &rhs)
|
||||
{
|
||||
os << "(" << rhs.x << "," << rhs.y << ",";
|
||||
return os;
|
||||
}
|
||||
|
||||
typedef std::bitset<NUM_UPGRADES> UpgradeFlags;
|
||||
|
||||
struct Resource
|
||||
|
@ -242,7 +559,7 @@ public:
|
|||
|
||||
bool upgrade(Upgrade upgrade);
|
||||
|
||||
void handle_event(const SDL_Event *event);
|
||||
void handle_event(const SDL_Event *event, EventContext *context);
|
||||
|
||||
FieldMeta *get_neighbor(Uint8 direction);
|
||||
|
||||
|
@ -287,7 +604,7 @@ public:
|
|||
|
||||
virtual bool render(SDL_Renderer *renderer) { return false; };
|
||||
|
||||
void handle_event(SDL_Event *event);
|
||||
void handle_event(SDL_Event *event, EventContext *context);
|
||||
|
||||
void update_box(SDL_Point dimensions);
|
||||
|
||||
|
|
125
src/Grid.cpp
125
src/Grid.cpp
|
@ -1,125 +0,0 @@
|
|||
#include "Grid.hpp"
|
||||
|
||||
SDL_Point operator+(SDL_Point left, SDL_Point right)
|
||||
{
|
||||
return {left.x + right.x, left.y + right.y};
|
||||
}
|
||||
|
||||
SDL_Point operator-(SDL_Point left, SDL_Point right)
|
||||
{
|
||||
return {left.x - right.x, left.y - right.y};
|
||||
}
|
||||
|
||||
SDL_Point operator*(SDL_Point left, SDL_Point right)
|
||||
{
|
||||
return {left.x * right.x, left.y * right.y};
|
||||
}
|
||||
|
||||
SDL_Point operator/(SDL_Point left, SDL_Point right)
|
||||
{
|
||||
return {(left.x / right.x), (left.x / right.y)};
|
||||
}
|
||||
|
||||
SDL_Point operator*(double left, SDL_Point right)
|
||||
{
|
||||
int x = (int) (left * right.x);
|
||||
int y = (int) (left * right.y);
|
||||
return {x, y};
|
||||
}
|
||||
|
||||
SDL_Point operator*(SDL_Point left, double right)
|
||||
{
|
||||
return right * left;
|
||||
}
|
||||
|
||||
SDL_Point operator/(SDL_Point left, double right)
|
||||
{
|
||||
return (1 / right) * left;
|
||||
}
|
||||
|
||||
double operator!(SDL_Point left)
|
||||
{
|
||||
double length = std::sqrt(left.x * left.x + left.y * left.y);
|
||||
return length;
|
||||
}
|
||||
|
||||
Field Field::cubic_round(double x, double y, double z)
|
||||
{
|
||||
Sint8 round_x = (Sint8) std::round(x);
|
||||
Sint8 round_y = (Sint8) std::round(y);
|
||||
Sint8 round_z = (Sint8) std::round(z);
|
||||
double x_err = std::abs(round_x - x);
|
||||
double y_err = std::abs(round_y - y);
|
||||
double z_err = std::abs(round_z - z);
|
||||
if (x_err > y_err && x_err > z_err)
|
||||
{
|
||||
round_x = -round_y - round_z;
|
||||
} else if (y_err > z_err)
|
||||
{
|
||||
round_y = -round_x - round_z;
|
||||
} else
|
||||
{
|
||||
round_z = -round_x - round_y;
|
||||
}
|
||||
return Field(round_x, round_y, round_z);
|
||||
}
|
||||
|
||||
|
||||
Field Field::hex_direction(Uint8 direction)
|
||||
{
|
||||
assert (0 <= direction && direction <= 5);
|
||||
return hex_directions[direction];
|
||||
}
|
||||
|
||||
Field Field::get_neighbor(Uint8 direction) const
|
||||
{
|
||||
return hex_direction(direction) + *this;
|
||||
}
|
||||
|
||||
Point Field::field_to_point(const Layout *layout) const
|
||||
{
|
||||
const Orientation m = layout->orientation;
|
||||
double x = (m.f0 * this->x + m.f1 * this->y) * layout->size;
|
||||
double y = (m.f2 * this->x + m.f3 * this->y) * layout->size;
|
||||
return {x + layout->origin.x, y + layout->origin.y};
|
||||
}
|
||||
|
||||
Field Point::point_to_field(const Layout *layout) const
|
||||
{
|
||||
const Orientation m = layout->orientation;
|
||||
double rel_x = (this->x - layout->origin.x) / layout->size;
|
||||
double rel_y = (this->y - layout->origin.y) / layout->size;
|
||||
double x = m.b0 * rel_x + m.b1 * rel_y;
|
||||
double y = m.b2 * rel_x + m.b3 * rel_y;
|
||||
return Field::cubic_round(x, y, -x - y);
|
||||
}
|
||||
|
||||
Point field_corner_offset(Uint8 corner, const Layout *layout)
|
||||
{
|
||||
double angle = 2.0 * M_PI * (corner + layout->orientation.start_angle) / 6;
|
||||
double x = (layout->size * cos(angle));
|
||||
double y = (layout->size * sin(angle));
|
||||
return {x, y};
|
||||
}
|
||||
|
||||
std::vector<Point> Field::field_to_polygon(const Layout *layout) const
|
||||
{
|
||||
std::vector<Point> corners = this->field_to_polygon_normalized(layout);
|
||||
Point center = this->field_to_point(layout);
|
||||
for (Point &p : corners)
|
||||
{
|
||||
p = p + center;
|
||||
}
|
||||
return corners;
|
||||
}
|
||||
|
||||
std::vector<Point> Field::field_to_polygon_normalized(const Layout *layout) const
|
||||
{
|
||||
std::vector<Point> corners;
|
||||
for (uint8_t i = 0; i < 6; i++)
|
||||
{
|
||||
Point offset = field_corner_offset(i, layout);
|
||||
corners.push_back(offset);
|
||||
}
|
||||
return corners;
|
||||
}
|
325
src/Grid.hpp
325
src/Grid.hpp
|
@ -1,325 +0,0 @@
|
|||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL2_gfxPrimitives.h>
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
#include <assert.h>
|
||||
#include <unordered_set>
|
||||
|
||||
#ifndef _GRID_H
|
||||
#define _GRID_H
|
||||
|
||||
SDL_Point operator+(SDL_Point left, SDL_Point right);
|
||||
|
||||
SDL_Point operator-(SDL_Point left, SDL_Point right);
|
||||
|
||||
SDL_Point operator*(SDL_Point left, SDL_Point right);
|
||||
|
||||
SDL_Point operator/(SDL_Point left, SDL_Point right);
|
||||
|
||||
SDL_Point operator/(SDL_Point left, SDL_Point right);
|
||||
|
||||
SDL_Point operator*(double left, SDL_Point right);
|
||||
|
||||
SDL_Point operator*(SDL_Point left, double right);
|
||||
|
||||
SDL_Point operator/(SDL_Point left, double right);
|
||||
|
||||
double operator!(SDL_Point left);
|
||||
|
||||
struct Orientation
|
||||
{
|
||||
// cubic to point
|
||||
const double f0, f1, f2, f3;
|
||||
// point to cubic
|
||||
const double b0, b1, b2, b3;
|
||||
// in multiples of 60 deg
|
||||
const double start_angle;
|
||||
|
||||
Orientation(double f0_, double f1_, double f2_, double f3_, double b0_, double b1_, double b2_, double b3_,
|
||||
double start_angle_)
|
||||
: f0(f0_), f1(f1_), f2(f2_), f3(f3_), b0(b0_), b1(b1_), b2(b2_), b3(b3_),
|
||||
start_angle(start_angle_)
|
||||
{ }
|
||||
};
|
||||
|
||||
const Orientation pointy_orientation = Orientation(sqrt(3.0), sqrt(3.0) / 2.0, 0.0, 3.0 / 2.0, sqrt(3.0) / 3.0,
|
||||
-1.0 / 3.0, 0.0, 2.0 / 3.0, 0.5);
|
||||
const Orientation flat_orientation = Orientation(3.0 / 2.0, 0.0, sqrt(3.0) / 2.0, sqrt(3.0), 2.0 / 3.0, 0.0, -1.0 / 3.0,
|
||||
sqrt(3.0) / 3.0, 0);
|
||||
|
||||
struct Layout
|
||||
{
|
||||
const Orientation orientation;
|
||||
Sint16 size;
|
||||
SDL_Point origin;
|
||||
SDL_Rect box;
|
||||
|
||||
Layout(Orientation orientation_, Sint16 size_, SDL_Point origin_, SDL_Rect box_)
|
||||
: orientation(orientation_), size(size_), origin(origin_), box(box_)
|
||||
{ }
|
||||
};
|
||||
|
||||
struct Field;
|
||||
|
||||
struct Point
|
||||
{
|
||||
double x;
|
||||
double y;
|
||||
|
||||
Point(double x_, double y_) : x(x_), y(y_) { }
|
||||
|
||||
bool operator==(const Point &rhs) const
|
||||
{
|
||||
return (this->x == rhs.x && this->y == rhs.y);
|
||||
}
|
||||
|
||||
inline bool operator!=(const Point &rhs) const
|
||||
{
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
Point &operator+=(const Point &rhs)
|
||||
{
|
||||
this->x += rhs.x;
|
||||
this->y += rhs.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend Point operator+(Point lhs, const Point &rhs)
|
||||
{
|
||||
lhs += rhs;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
Point &operator-=(const Point &rhs)
|
||||
{
|
||||
this->x -= rhs.x;
|
||||
this->y -= rhs.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend Point operator-(Point lhs, const Point &rhs)
|
||||
{
|
||||
lhs -= rhs;
|
||||
return rhs;
|
||||
}
|
||||
|
||||
Point &operator*=(const Point &rhs)
|
||||
{
|
||||
this->x *= rhs.x;
|
||||
this->y *= rhs.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend Point operator*(Point lhs, const Point &rhs)
|
||||
{
|
||||
lhs *= rhs;
|
||||
return rhs;
|
||||
}
|
||||
|
||||
Point &operator/=(const Point &rhs)
|
||||
{
|
||||
this->x /= rhs.x;
|
||||
this->y /= rhs.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend Point operator/(Point lhs, const Point &rhs)
|
||||
{
|
||||
lhs /= rhs;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
Point &operator*=(const double &rhs)
|
||||
{
|
||||
this->x *= rhs;
|
||||
this->y *= rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend Point operator*(Point lhs, const double &rhs)
|
||||
{
|
||||
lhs *= rhs;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
Point &operator/=(const double &rhs)
|
||||
{
|
||||
this->x /= rhs;
|
||||
this->y /= rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend Point operator/(Point lhs, const double &rhs)
|
||||
{
|
||||
lhs /= rhs;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
double operator!()
|
||||
{
|
||||
return std::sqrt(this->x * this->x + this->y * this->y);
|
||||
}
|
||||
|
||||
Field point_to_field(const Layout *layout) const;
|
||||
};
|
||||
|
||||
struct Field
|
||||
{
|
||||
Sint16 x, y, z;
|
||||
|
||||
Field(Sint16 x_, Sint16 y_, Sint16 z_) : x(x_), y(y_), z(z_)
|
||||
{
|
||||
assert(x + y + z == 0);
|
||||
}
|
||||
|
||||
bool operator==(const Field &rhs) const
|
||||
{
|
||||
return (this->x == rhs.x && this->y == rhs.y);
|
||||
}
|
||||
|
||||
inline bool operator!=(const Field &rhs) const
|
||||
{
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
Field &operator+=(const Field &rhs)
|
||||
{
|
||||
this->x += rhs.x;
|
||||
this->y += rhs.y;
|
||||
this->z += rhs.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend Field operator+(Field lhs, const Field &rhs)
|
||||
{
|
||||
lhs += rhs;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
Field &operator-=(const Field &rhs)
|
||||
{
|
||||
this->x -= rhs.x;
|
||||
this->y -= rhs.y;
|
||||
this->z -= rhs.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend Field operator-(Field lhs, const Field &rhs)
|
||||
{
|
||||
lhs -= rhs;
|
||||
return rhs;
|
||||
}
|
||||
|
||||
Field &operator*=(const Field &rhs)
|
||||
{
|
||||
this->x *= rhs.x;
|
||||
this->y *= rhs.y;
|
||||
this->z *= rhs.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend Field operator*(Field lhs, const Field &rhs)
|
||||
{
|
||||
lhs *= rhs;
|
||||
return rhs;
|
||||
}
|
||||
|
||||
Field &operator/=(const Field &rhs)
|
||||
{
|
||||
double x = this->x / rhs.x;
|
||||
double y = this->y / rhs.y;
|
||||
double z = this->z / rhs.z;
|
||||
Field f = cubic_round(x, y, z);
|
||||
*this = f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend Field operator/(Field lhs, const Field &rhs)
|
||||
{
|
||||
lhs /= rhs;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
Field &operator*=(const double &rhs)
|
||||
{
|
||||
double x = this->x * rhs;
|
||||
double y = this->y * rhs;
|
||||
double z = this->z * rhs;
|
||||
Field f = cubic_round(x, y, z);
|
||||
*this = f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend Field operator*(Field lhs, const double &rhs)
|
||||
{
|
||||
lhs *= rhs;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
Field &operator/=(const double &rhs)
|
||||
{
|
||||
double x = this->x / rhs;
|
||||
double y = this->y / rhs;
|
||||
double z = this->z / rhs;
|
||||
Field f = cubic_round(x, y, z);
|
||||
*this = f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend Field operator/(Field lhs, const double &rhs)
|
||||
{
|
||||
lhs /= rhs;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
int operator&(const Field &rhs)
|
||||
{
|
||||
return (abs(this->x - rhs.x) + abs(this->y - rhs.y) + abs(this->z - rhs.z)) / 2;
|
||||
}
|
||||
|
||||
Field get_neighbor(Uint8 direction) const;
|
||||
|
||||
Point field_to_point(const Layout *layout) const;
|
||||
|
||||
std::vector<Point> field_to_polygon_normalized(const Layout *layout) const;
|
||||
|
||||
std::vector<Point> field_to_polygon(const Layout *layout) const;
|
||||
|
||||
static Field cubic_round(double x, double y, double z);
|
||||
|
||||
static Field hex_direction(Uint8 direction);
|
||||
};
|
||||
|
||||
// from upper right corner
|
||||
const std::vector<Field> hex_directions = {Field(1, 0, -1), Field(0, 1, -1), Field(-1, 1, 0), Field(-1, 0, 1),
|
||||
Field(-1, 1, 0)};
|
||||
|
||||
Point field_corner_offset(Uint8 corner, const Layout *layout);
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<>
|
||||
struct hash<Field>
|
||||
{
|
||||
size_t operator()(const Field &f) const
|
||||
{
|
||||
hash<Sint16> int_hash;
|
||||
size_t hx = int_hash(f.x);
|
||||
size_t hy = int_hash(f.y);
|
||||
// hz would be redundant, since f.z is redundant
|
||||
// combine hashes
|
||||
return hx ^ (hy + 0x9e3779b9 + (hx << 6) + (hx >> 2));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
inline std::ostream &operator<<(std::ostream &os, const Field &rhs)
|
||||
{
|
||||
os << "(" << rhs.x << "," << rhs.y << ",";
|
||||
return os;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,3 +1,6 @@
|
|||
#ifndef _GUI_H
|
||||
#define _GUI_H
|
||||
|
||||
#include "SDL2/SDL.h"
|
||||
#include "SDL2/SDL_ttf.h"
|
||||
#include <stdio.h>
|
||||
|
@ -10,9 +13,6 @@
|
|||
#include "Gameplay.hpp"
|
||||
#include "Events.hpp"
|
||||
|
||||
#ifndef _GUI_H
|
||||
#define _GUI_H
|
||||
|
||||
SDL_Color operator!(const SDL_Color &color);
|
||||
|
||||
class Window
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue