Refactor some code to have better naming and move Point and related point things into their own .hpp.
This commit is contained in:
parent
c19cd707d1
commit
5a123ae74c
7 changed files with 45 additions and 40 deletions
14
collider.cpp
14
collider.cpp
|
@ -5,20 +5,20 @@ using namespace fmt;
|
|||
|
||||
using DinkyECS::Entity;
|
||||
|
||||
void SpatialHashTable::insert(Point pos, Entity ent) {
|
||||
void spatial_map::insert(Point pos, Entity ent) {
|
||||
table[pos] = ent;
|
||||
}
|
||||
|
||||
void SpatialHashTable::remove(Point pos) {
|
||||
void spatial_map::remove(Point pos) {
|
||||
table.erase(pos);
|
||||
}
|
||||
|
||||
void SpatialHashTable::move(Point from, Point to, Entity ent) {
|
||||
void spatial_map::move(Point from, Point to, Entity ent) {
|
||||
remove(from);
|
||||
insert(to, ent);
|
||||
}
|
||||
|
||||
bool SpatialHashTable::occupied(Point at) const {
|
||||
bool spatial_map::occupied(Point at) const {
|
||||
return table.contains(at);
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ bool SpatialHashTable::occupied(Point at) const {
|
|||
* at.x or at.y is > 0. If either is 0 then there can't be
|
||||
* a neighbor since that's out of bounds.
|
||||
*/
|
||||
inline void find_neighbor(const PointEntityMap &table, FoundList &result, Point at, int dy, int dx) {
|
||||
inline void find_neighbor(const PointEntityMap &table, EntityList &result, Point at, int dy, int dx) {
|
||||
// don't bother checking for cells out of bounds
|
||||
if((dx < 0 && at.x <= 0) || (dy < 0 && at.y <= 0)) {
|
||||
return;
|
||||
|
@ -41,8 +41,8 @@ inline void find_neighbor(const PointEntityMap &table, FoundList &result, Point
|
|||
}
|
||||
}
|
||||
|
||||
std::tuple<bool, FoundList> SpatialHashTable::neighbors(Point cell, bool diag) const {
|
||||
FoundList result;
|
||||
std::tuple<bool, EntityList> spatial_map::neighbors(Point cell, bool diag) const {
|
||||
EntityList result;
|
||||
|
||||
// just unroll the loop since we only check four directions
|
||||
// this also solves the problem that it was detecting that the cell was automatically included as a "neighbor" but it's not
|
||||
|
|
14
collider.hpp
14
collider.hpp
|
@ -3,26 +3,22 @@
|
|||
#include <unordered_map>
|
||||
#include "map.hpp"
|
||||
#include "dinkyecs.hpp"
|
||||
#include "point.hpp"
|
||||
#include <tuple>
|
||||
|
||||
struct PointHash {
|
||||
size_t operator()(const Point& p) const {
|
||||
return std::hash<int>()(p.x) ^ std::hash<int>()(p.y);
|
||||
}
|
||||
};
|
||||
typedef std::vector<DinkyECS::Entity> EntityList;
|
||||
|
||||
typedef std::vector<DinkyECS::Entity> FoundList;
|
||||
typedef std::unordered_map<Point, DinkyECS::Entity, PointHash> PointEntityMap;
|
||||
|
||||
class SpatialHashTable {
|
||||
class spatial_map {
|
||||
public:
|
||||
SpatialHashTable() {}
|
||||
spatial_map() {}
|
||||
|
||||
void insert(Point pos, DinkyECS::Entity obj);
|
||||
void move(Point from, Point to, DinkyECS::Entity ent);
|
||||
void remove(Point pos);
|
||||
bool occupied(Point pos) const;
|
||||
std::tuple<bool, FoundList> neighbors(Point position, bool diag=false) const;
|
||||
std::tuple<bool, EntityList> neighbors(Point position, bool diag=false) const;
|
||||
|
||||
private:
|
||||
PointEntityMap table;
|
||||
|
|
4
gui.cpp
4
gui.cpp
|
@ -278,8 +278,8 @@ void GUI::configure_world() {
|
|||
ActionLog log{{"Welcome to the game!"}};
|
||||
$world.set<ActionLog>(log);
|
||||
|
||||
SpatialHashTable collider;
|
||||
$world.set<SpatialHashTable>(collider);
|
||||
spatial_map collider;
|
||||
$world.set<spatial_map>(collider);
|
||||
|
||||
$world.assign<Position>(player.entity, {$game_map.place_entity(0)});
|
||||
$world.assign<Motion>(player.entity, {0, 0});
|
||||
|
|
11
map.hpp
11
map.hpp
|
@ -5,6 +5,7 @@
|
|||
#include <random>
|
||||
#include <algorithm>
|
||||
#include <fmt/core.h>
|
||||
#include "point.hpp"
|
||||
|
||||
#define INV_WALL 0
|
||||
#define INV_SPACE 1
|
||||
|
@ -15,15 +16,6 @@
|
|||
#define PLAYER_TILE "☺"
|
||||
#define ENEMY_TILE "Ω"
|
||||
|
||||
struct Point {
|
||||
size_t x = 0;
|
||||
size_t y = 0;
|
||||
|
||||
bool operator==(const Point& other) const {
|
||||
return other.x == x && other.y == y;
|
||||
}
|
||||
};
|
||||
|
||||
struct Room {
|
||||
size_t x = 0;
|
||||
size_t y = 0;
|
||||
|
@ -33,7 +25,6 @@ struct Room {
|
|||
Point exit;
|
||||
};
|
||||
|
||||
typedef std::vector<Point> PointList;
|
||||
typedef std::vector<int> MatrixRow;
|
||||
typedef std::vector<MatrixRow> Matrix;
|
||||
|
||||
|
|
18
point.hpp
Normal file
18
point.hpp
Normal file
|
@ -0,0 +1,18 @@
|
|||
#pragma once
|
||||
|
||||
struct Point {
|
||||
size_t x = 0;
|
||||
size_t y = 0;
|
||||
|
||||
bool operator==(const Point& other) const {
|
||||
return other.x == x && other.y == y;
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::vector<Point> PointList;
|
||||
|
||||
struct PointHash {
|
||||
size_t operator()(const Point& p) const {
|
||||
return std::hash<int>()(p.x) ^ std::hash<int>()(p.y);
|
||||
}
|
||||
};
|
|
@ -26,7 +26,7 @@ void System::enemy_pathing(DinkyECS::World &world, Map &game_map, Player &player
|
|||
}
|
||||
|
||||
void System::init_positions(DinkyECS::World &world) {
|
||||
auto &collider = world.get<SpatialHashTable>();
|
||||
auto &collider = world.get<spatial_map>();
|
||||
|
||||
world.system<Position>([&](const auto &ent, auto &pos) {
|
||||
collider.insert(pos.location, ent);
|
||||
|
@ -34,7 +34,7 @@ void System::init_positions(DinkyECS::World &world) {
|
|||
}
|
||||
|
||||
void System::motion(DinkyECS::World &world, Map &game_map) {
|
||||
auto &collider = world.get<SpatialHashTable>();
|
||||
auto &collider = world.get<spatial_map>();
|
||||
|
||||
world.system<Position, Motion>([&](const auto &ent, auto &position, auto &motion) {
|
||||
// don't process entities that don't move
|
||||
|
@ -58,7 +58,7 @@ void System::motion(DinkyECS::World &world, Map &game_map) {
|
|||
|
||||
|
||||
void System::combat(DinkyECS::World &world, Player &player) {
|
||||
const auto& collider = world.get<SpatialHashTable>();
|
||||
const auto& collider = world.get<spatial_map>();
|
||||
const auto& player_position = world.component<Position>(player.entity);
|
||||
auto& player_combat = world.component<Combat>(player.entity);
|
||||
auto& log = world.get<ActionLog>();
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
using DinkyECS::Entity;
|
||||
using namespace fmt;
|
||||
|
||||
FoundList require_found(const SpatialHashTable& collider, Point at, bool diag, size_t expect_size) {
|
||||
EntityList require_found(const spatial_map& collider, Point at, bool diag, size_t expect_size) {
|
||||
println("TEST require_found at={},{}", at.x, at.y);
|
||||
auto [found, nearby] = collider.neighbors(at, diag);
|
||||
REQUIRE(found == true);
|
||||
|
@ -21,7 +21,7 @@ TEST_CASE("confirm basic collision operations", "[collision]") {
|
|||
Entity player = world.entity();
|
||||
Entity enemy = world.entity();
|
||||
|
||||
SpatialHashTable collider;
|
||||
spatial_map collider;
|
||||
collider.insert({11,11}, player);
|
||||
collider.insert({21,21}, enemy);
|
||||
|
||||
|
@ -32,7 +32,7 @@ TEST_CASE("confirm basic collision operations", "[collision]") {
|
|||
}
|
||||
|
||||
// found
|
||||
FoundList nearby = require_found(collider, {10,10}, true, 1);
|
||||
EntityList nearby = require_found(collider, {10,10}, true, 1);
|
||||
REQUIRE(nearby[0] == player);
|
||||
|
||||
{ // removed
|
||||
|
@ -68,13 +68,13 @@ TEST_CASE("confirm multiple entities moving", "[collision]") {
|
|||
Entity e2 = world.entity();
|
||||
Entity e3 = world.entity();
|
||||
|
||||
SpatialHashTable collider;
|
||||
spatial_map collider;
|
||||
collider.insert({11,11}, player);
|
||||
collider.insert({10,10}, e2);
|
||||
collider.insert({11,10}, e3);
|
||||
collider.insert({21,21}, e1);
|
||||
|
||||
FoundList nearby = require_found(collider, {11,11}, false, 1);
|
||||
EntityList nearby = require_found(collider, {11,11}, false, 1);
|
||||
REQUIRE(nearby[0] == e3);
|
||||
|
||||
nearby = require_found(collider, {11,11}, true, 2);
|
||||
|
@ -91,13 +91,13 @@ TEST_CASE("test edge cases that might crash", "[collision]") {
|
|||
Entity player = world.entity();
|
||||
Entity enemy = world.entity();
|
||||
|
||||
SpatialHashTable collider;
|
||||
spatial_map collider;
|
||||
collider.insert({0,0}, player);
|
||||
|
||||
Point enemy_at = {1, 0};
|
||||
collider.insert(enemy_at, enemy);
|
||||
|
||||
FoundList nearby = require_found(collider, {0,0}, true, 1);
|
||||
EntityList nearby = require_found(collider, {0,0}, true, 1);
|
||||
|
||||
collider.move({1,0}, {1,1}, enemy);
|
||||
nearby = require_found(collider, {0,0}, true, 1);
|
||||
|
@ -113,7 +113,7 @@ TEST_CASE("check all diagonal works", "[collision]") {
|
|||
Entity player = world.entity();
|
||||
Entity enemy = world.entity();
|
||||
|
||||
SpatialHashTable collider;
|
||||
spatial_map collider;
|
||||
Point player_at = {1,1};
|
||||
collider.insert(player_at, player);
|
||||
|
||||
|
@ -123,7 +123,7 @@ TEST_CASE("check all diagonal works", "[collision]") {
|
|||
for(size_t x = 0; x <= 2; x++) {
|
||||
for(size_t y = 0; y <= 2; y++) {
|
||||
if(enemy_at.x == player_at.x && enemy_at.y == player_at.y) continue; // skip player spot
|
||||
FoundList nearby = require_found(collider, player_at, true, 1);
|
||||
EntityList nearby = require_found(collider, player_at, true, 1);
|
||||
REQUIRE(nearby[0] == enemy);
|
||||
|
||||
// move the enemy to a new spot around the player
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue