Compare commits
5 Commits
feature/pa
...
250f0963c8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
250f0963c8 | ||
|
|
3d34b68133 | ||
|
|
2f80129dce | ||
|
|
8a9aa8ee5e | ||
|
|
536618d7a7 |
@@ -46,6 +46,47 @@ void Entity::Update(float time_delta) {
|
|||||||
m_Position += m_ActualVelocity * time_delta;
|
m_Position += m_ActualVelocity * time_delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<WorldPos> Entity::GetMoveTarget()
|
||||||
|
{
|
||||||
|
auto& path = GetPath();
|
||||||
|
if (path.empty()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
WorldPos current_pos = GetPosition();
|
||||||
|
WorldPos next_pos = path.front();
|
||||||
|
|
||||||
|
if (current_pos.DistanceTo(next_pos) > 1.0) {
|
||||||
|
// target not reached yet
|
||||||
|
return next_pos;
|
||||||
|
}
|
||||||
|
// target reached, pop it
|
||||||
|
//m_MoveQueue.pop();
|
||||||
|
path.erase(path.begin());
|
||||||
|
// return nothing - if there's next point in the queue,
|
||||||
|
// we'll get it in the next iteration
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Entity::CollidesWith(const Entity& other) const
|
||||||
|
{
|
||||||
|
const auto& A = *this;
|
||||||
|
const auto& B = other;
|
||||||
|
|
||||||
|
auto position_A = A.GetPosition();
|
||||||
|
auto position_B = B.GetPosition();
|
||||||
|
auto distance_sq = position_A.DistanceSquared(position_B);
|
||||||
|
auto collision_distance_sq =
|
||||||
|
A.GetCollisionRadiusSquared() +
|
||||||
|
B.GetCollisionRadiusSquared() +
|
||||||
|
2 * A.GetCollisionRadius() * B.GetCollisionRadius();
|
||||||
|
if (distance_sq < collision_distance_sq)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Player::Player() {
|
Player::Player() {
|
||||||
LOG_DEBUG(".");
|
LOG_DEBUG(".");
|
||||||
if (m_Sprite == nullptr) {
|
if (m_Sprite == nullptr) {
|
||||||
|
|||||||
@@ -5,10 +5,12 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "log.hpp"
|
#include "log.hpp"
|
||||||
#include "math.hpp"
|
#include "math.hpp"
|
||||||
#include "sprite.hpp"
|
#include "sprite.hpp"
|
||||||
|
#include "pathfinder/base.hpp"
|
||||||
|
|
||||||
class Entity {
|
class Entity {
|
||||||
public:
|
public:
|
||||||
@@ -56,14 +58,24 @@ public:
|
|||||||
|
|
||||||
void ZeroActualVelocityInDirection(WorldPos direction);
|
void ZeroActualVelocityInDirection(WorldPos direction);
|
||||||
|
|
||||||
|
const pathfinder::Path& GetPath() const { return m_Path; }
|
||||||
|
pathfinder::Path& GetPath() { return m_Path; }
|
||||||
|
void SetPath(pathfinder::Path& path) { m_Path = path; }
|
||||||
|
std::optional<WorldPos> GetMoveTarget();
|
||||||
|
|
||||||
|
bool CollidesWith(const Entity& other) const;
|
||||||
|
|
||||||
|
bool IsCollisionBoxVisible() const { return m_CollisionBoxVisible; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
WorldPos m_Position;
|
WorldPos m_Position;
|
||||||
WorldPos m_ActualVelocity;
|
WorldPos m_ActualVelocity;
|
||||||
WorldPos m_RequestedVelocity;
|
WorldPos m_RequestedVelocity;
|
||||||
|
pathfinder::Path m_Path;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_FlagExpired = false;
|
bool m_FlagExpired = false;
|
||||||
static constexpr float m_CollisionRadiusSq = 1000.0f;
|
bool m_CollisionBoxVisible = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Player final : public Entity {
|
class Player final : public Entity {
|
||||||
@@ -75,7 +87,7 @@ public:
|
|||||||
constexpr Entity::Type GetType() const override {
|
constexpr Entity::Type GetType() const override {
|
||||||
return Entity::Type::PLAYER;
|
return Entity::Type::PLAYER;
|
||||||
}
|
}
|
||||||
constexpr float GetCollisionRadius() const override { return 50.0f; }
|
constexpr float GetCollisionRadius() const override { return 25.0f; }
|
||||||
bool IsMovable() const override { return true; }
|
bool IsMovable() const override { return true; }
|
||||||
bool IsCollidable() const override { return true; }
|
bool IsCollidable() const override { return true; }
|
||||||
|
|
||||||
|
|||||||
@@ -1,65 +1,73 @@
|
|||||||
#include <thread>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
#include "gameloop.hpp"
|
#include "gameloop.hpp"
|
||||||
|
|
||||||
#include "pathfindingdemo.hpp"
|
|
||||||
#include "window.hpp"
|
|
||||||
#include "user_input.hpp"
|
|
||||||
#include "log.hpp"
|
#include "log.hpp"
|
||||||
#include "pathfinder/base.hpp"
|
|
||||||
#include "math.hpp"
|
#include "math.hpp"
|
||||||
|
#include "pathfinder/base.hpp"
|
||||||
|
#include "pathfindingdemo.hpp"
|
||||||
|
#include "user_input.hpp"
|
||||||
|
#include "window.hpp"
|
||||||
|
|
||||||
|
void GameLoop::Draw() {
|
||||||
|
// draw the map (terrain tiles)
|
||||||
|
const Map &map = m_Game->GetMap();
|
||||||
|
const auto &tiles = map.GetMapTiles();
|
||||||
|
for (size_t row = 0; row < tiles.size(); row++) {
|
||||||
|
for (size_t col = 0; col < tiles[row].size(); col++) {
|
||||||
|
const auto &camera = m_Game->GetCamera();
|
||||||
|
const auto &position = camera.WorldToWindow(map.TileEdgeToWorld(
|
||||||
|
TilePos{static_cast<int32_t>(row), static_cast<int32_t>(col)}));
|
||||||
|
const auto &size = camera.WorldToWindowSize(map.GetTileSize());
|
||||||
|
// LOG_DEBUG("Drawing rect (", row, ", ", col, ")");
|
||||||
|
m_Window->DrawRect(position, size, tiles[row][col]->R, tiles[row][col]->G,
|
||||||
|
tiles[row][col]->B, tiles[row][col]->A);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw the path, if it exists
|
||||||
|
|
||||||
|
for (const auto& entity : m_Game->GetEntities())
|
||||||
|
{
|
||||||
|
WorldPos start_pos = entity->GetPosition();
|
||||||
|
for (const auto &next_pos : entity->GetPath())
|
||||||
|
{
|
||||||
|
const auto &camera = m_Game->GetCamera();
|
||||||
|
m_Window->DrawLine(camera.WorldToWindow(start_pos),
|
||||||
|
camera.WorldToWindow(next_pos));
|
||||||
|
start_pos = next_pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw all the entities (player etc)
|
||||||
|
for (auto &entity : m_Game->GetEntities()) {
|
||||||
|
const auto &camera = m_Game->GetCamera();
|
||||||
|
auto entity_pos_window = camera.WorldToWindow(entity->GetPosition());
|
||||||
|
m_Window->DrawSprite(entity_pos_window,
|
||||||
|
entity->GetSprite(),
|
||||||
|
camera.GetZoom());
|
||||||
|
if (entity->IsCollisionBoxVisible())
|
||||||
|
{
|
||||||
|
m_Window->DrawCircle(entity_pos_window, entity->GetCollisionRadius());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO rethink coupling and dependencies in the game loop class
|
||||||
|
|
||||||
void GameLoop::Run() {
|
void GameLoop::Run() {
|
||||||
LOG_INFO("Running the game");
|
LOG_INFO("Running the game");
|
||||||
while (!m_Game->IsExitRequested()) {
|
while (!m_Game->IsExitRequested()) {
|
||||||
m_Game->HandleActions(m_UserInput->GetActions());
|
m_Game->HandleActions(m_UserInput->GetActions());
|
||||||
m_Game->UpdatePlayerVelocity();
|
m_Game->UpdateWorld();
|
||||||
|
|
||||||
|
// TODO measure fps, draw only if delay for target fps was reached
|
||||||
|
// or create a separate thread for drawing
|
||||||
m_Window->ClearWindow();
|
m_Window->ClearWindow();
|
||||||
|
Draw();
|
||||||
// TODO wrap all of the drawing in some function
|
|
||||||
// TODO rethink coupling and dependencies here
|
|
||||||
|
|
||||||
// draw the map (terrain tiles)
|
|
||||||
const Map &map = m_Game->GetMap();
|
|
||||||
const auto &tiles = map.GetMapTiles();
|
|
||||||
for (size_t row = 0; row < tiles.size(); row++) {
|
|
||||||
for (size_t col = 0; col < tiles[row].size(); col++) {
|
|
||||||
const auto& camera = m_Game->GetCamera();
|
|
||||||
const auto& position = camera.WorldToWindow(
|
|
||||||
map.TileEdgeToWorld(
|
|
||||||
TilePos{static_cast<int32_t>(row), static_cast<int32_t>(col)}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
const auto& size = camera.WorldToWindowSize(
|
|
||||||
map.GetTileSize()
|
|
||||||
);
|
|
||||||
// LOG_DEBUG("Drawing rect (", row, ", ", col, ")");
|
|
||||||
m_Window->DrawRect(
|
|
||||||
position,
|
|
||||||
size,
|
|
||||||
tiles[row][col]->R, tiles[row][col]->G,
|
|
||||||
tiles[row][col]->B, tiles[row][col]->A);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// draw the path, if it exists
|
|
||||||
WorldPos start_pos = m_Game->GetPlayer()->GetPosition();
|
|
||||||
for (const auto& next_pos: m_Game->GetPath()) {
|
|
||||||
const auto& camera = m_Game->GetCamera();
|
|
||||||
m_Window->DrawLine(camera.WorldToWindow(start_pos), camera.WorldToWindow(next_pos));
|
|
||||||
start_pos = next_pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
// draw all the entities (player etc)
|
|
||||||
for (auto &entity : m_Game->GetEntities()) {
|
|
||||||
const auto& camera = m_Game->GetCamera();
|
|
||||||
m_Window->DrawSprite(camera.WorldToWindow(entity->GetPosition()), entity->GetSprite(), camera.GetZoom());
|
|
||||||
}
|
|
||||||
|
|
||||||
m_Window->Flush();
|
m_Window->Flush();
|
||||||
// TODO measure fps
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(30));
|
std::this_thread::sleep_for(std::chrono::milliseconds(30));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void Draw();
|
||||||
|
|
||||||
std::unique_ptr<PathFindingDemo> m_Game;
|
std::unique_ptr<PathFindingDemo> m_Game;
|
||||||
std::unique_ptr<Window> m_Window;
|
std::unique_ptr<Window> m_Window;
|
||||||
std::unique_ptr<UserInput> m_UserInput;
|
std::unique_ptr<UserInput> m_UserInput;
|
||||||
|
|||||||
@@ -165,6 +165,12 @@ public:
|
|||||||
return (a - b).Length();
|
return (a - b).Length();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
T DistanceSquared(const vec &b) const {
|
||||||
|
const vec &a = *this;
|
||||||
|
return (a - b).LengthSquared();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// In-place vector operations
|
// In-place vector operations
|
||||||
//
|
//
|
||||||
@@ -394,4 +400,4 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::array<vec_type, N> m_Array;
|
std::array<vec_type, N> m_Array;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -55,54 +55,108 @@ void PathFindingDemo::CreateMap() {
|
|||||||
m_Map.PaintLine(TilePos{84,81}, TilePos{84,96}, 1.0, TileType::WALL);
|
m_Map.PaintLine(TilePos{84,81}, TilePos{84,96}, 1.0, TileType::WALL);
|
||||||
m_Map.PaintLine(TilePos{78,87}, TilePos{78,100}, 1.0, TileType::WALL);
|
m_Map.PaintLine(TilePos{78,87}, TilePos{78,100}, 1.0, TileType::WALL);
|
||||||
|
|
||||||
// add player
|
// add some controllable entities
|
||||||
m_Entities.clear();
|
m_Entities.clear();
|
||||||
m_Player = std::make_shared<Player>();
|
auto player = std::make_shared<Player>();
|
||||||
m_Player->SetPosition(m_Map.TileToWorld(TilePos{25, 20}));
|
player->SetPosition(m_Map.TileToWorld(TilePos{25, 20}));
|
||||||
m_Entities.push_back(m_Player);
|
AddEntity(player);
|
||||||
|
|
||||||
|
auto player2 = std::make_shared<Player>();
|
||||||
|
player2->SetPosition(m_Map.TileToWorld(TilePos{50, 20}));
|
||||||
|
AddEntity(player2);
|
||||||
|
|
||||||
|
for (int i = 0; i < 1; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < 10; j++)
|
||||||
|
{
|
||||||
|
auto p = std::make_shared<Player>();
|
||||||
|
p->SetPosition(m_Map.TileToWorld(TilePos{10+5*i, 40+5*j}));
|
||||||
|
AddEntity(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// select everything - TODO this is just temporary for testing
|
||||||
|
for (const auto& entity : m_Entities)
|
||||||
|
{
|
||||||
|
m_SelectedEntities.push_back(entity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WorldPos PathFindingDemo::GetRandomPosition() const {
|
WorldPos PathFindingDemo::GetRandomPosition() const {
|
||||||
return WorldPos{0.0f, 0.0f}; // totally random!
|
return WorldPos{0.0f, 0.0f}; // totally random!
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<WorldPos> PathFindingDemo::GetMoveTarget() {
|
|
||||||
WorldPos current_player_pos = GetPlayer()->GetPosition();
|
|
||||||
|
|
||||||
if (m_Path.empty()) {
|
|
||||||
return {};
|
const std::vector<Collision>& PathFindingDemo::GetEntityCollisions()
|
||||||
|
{
|
||||||
|
static std::vector<Collision> m_Collisions;
|
||||||
|
m_Collisions.clear();
|
||||||
|
|
||||||
|
for (const auto &entity_A : m_Entities)
|
||||||
|
{
|
||||||
|
for (const auto &entity_B : m_Entities)
|
||||||
|
{
|
||||||
|
if (entity_A == entity_B)
|
||||||
|
continue;
|
||||||
|
if (!entity_A->IsCollidable() || !entity_B->IsCollidable())
|
||||||
|
continue;
|
||||||
|
if (entity_A->CollidesWith(*entity_B))
|
||||||
|
{
|
||||||
|
// handle collision logic
|
||||||
|
m_Collisions.emplace_back(Collision(entity_A, entity_B));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return m_Collisions;
|
||||||
WorldPos next_player_pos = m_Path.front();
|
|
||||||
|
|
||||||
if (current_player_pos.DistanceTo(next_player_pos) > 1.0) {
|
|
||||||
// target not reached yet
|
|
||||||
return next_player_pos;
|
|
||||||
}
|
|
||||||
// target reached, pop it
|
|
||||||
//m_MoveQueue.pop();
|
|
||||||
m_Path.erase(m_Path.begin());
|
|
||||||
// return nothing - if there's next point in the queue,
|
|
||||||
// we'll get it in the next iteration
|
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PathFindingDemo::UpdatePlayerVelocity() {
|
|
||||||
auto player = GetPlayer();
|
// Update entity positions, handle collisions
|
||||||
auto current_pos = player->GetPosition();
|
void PathFindingDemo::UpdateWorld() {
|
||||||
double tile_velocity_coeff = m_Map.GetTileVelocityCoeff(current_pos);
|
|
||||||
auto next_pos = GetMoveTarget();
|
|
||||||
WorldPos velocity = WorldPos{};
|
|
||||||
if (next_pos)
|
|
||||||
{
|
|
||||||
velocity = next_pos.value() - current_pos;
|
|
||||||
velocity.Normalize();
|
|
||||||
//LOG_DEBUG("I want to move to: ", next_pos.value(),
|
|
||||||
// ", velocity: ", velocity);
|
|
||||||
}
|
|
||||||
player->SetActualVelocity(velocity * tile_velocity_coeff);
|
|
||||||
float time_delta = 1.0f;
|
float time_delta = 1.0f;
|
||||||
player->Update(time_delta);
|
|
||||||
|
for (auto& entity : m_Entities)
|
||||||
|
{
|
||||||
|
// calculate the velocity
|
||||||
|
auto current_pos = entity->GetPosition();
|
||||||
|
double tile_velocity_coeff = m_Map.GetTileVelocityCoeff(current_pos);
|
||||||
|
auto next_pos = entity->GetMoveTarget();
|
||||||
|
WorldPos velocity = WorldPos{};
|
||||||
|
if (next_pos)
|
||||||
|
{
|
||||||
|
velocity = next_pos.value() - current_pos;
|
||||||
|
velocity.Normalize();
|
||||||
|
//LOG_DEBUG("I want to move to: ", next_pos.value(),
|
||||||
|
// ", velocity: ", velocity);
|
||||||
|
}
|
||||||
|
entity->SetActualVelocity(velocity * tile_velocity_coeff);
|
||||||
|
|
||||||
|
for (const auto& collision : GetEntityCollisions())
|
||||||
|
{
|
||||||
|
// TODO this loop is quite "hot", is it good idea to use weak_ptr and promote it?
|
||||||
|
auto weak_A = std::get<0>(collision);
|
||||||
|
auto weak_B = std::get<1>(collision);
|
||||||
|
auto A = weak_A.lock();
|
||||||
|
auto B = weak_B.lock();
|
||||||
|
if (A == nullptr || B == nullptr)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!A->IsMovable())
|
||||||
|
continue;
|
||||||
|
// modify actual speed
|
||||||
|
// LOG_DEBUG("Collision: A is ", A, ", B is ", B);
|
||||||
|
auto AB = B->GetPosition() - A->GetPosition();
|
||||||
|
A->ZeroActualVelocityInDirection(AB);
|
||||||
|
// handle logic
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
// update the position
|
||||||
|
entity->Update(time_delta);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PathFindingDemo::HandleActions(const std::vector<UserAction> &actions)
|
void PathFindingDemo::HandleActions(const std::vector<UserAction> &actions)
|
||||||
@@ -116,10 +170,19 @@ void PathFindingDemo::HandleActions(const std::vector<UserAction> &actions)
|
|||||||
}
|
}
|
||||||
else if (action.type == UserAction::Type::SET_MOVE_TARGET)
|
else if (action.type == UserAction::Type::SET_MOVE_TARGET)
|
||||||
{
|
{
|
||||||
WorldPos wp = m_Camera.WindowToWorld(action.Argument.position);
|
WorldPos target_pos = m_Camera.WindowToWorld(action.Argument.position);
|
||||||
LOG_INFO("Calculating path to target: ", wp);
|
for (auto& selected_entity : m_SelectedEntities)
|
||||||
m_Path = m_PathFinder->CalculatePath(m_Player->GetPosition(), wp);
|
{
|
||||||
LOG_INFO("Done, path node count: ", m_Path.size());
|
LOG_INFO("Calculating path to target: ", target_pos);
|
||||||
|
if (auto sp = selected_entity.lock())
|
||||||
|
{
|
||||||
|
auto path = m_PathFinder->CalculatePath(sp->GetPosition(), target_pos);
|
||||||
|
sp->SetPath(path);
|
||||||
|
LOG_INFO("Done, path node count: ", path.size());
|
||||||
|
} else {
|
||||||
|
LOG_INFO("Cannot calculate path for destroyed entity (weak_ptr.lock() failed)");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (action.type == UserAction::Type::SELECT_PATHFINDER)
|
else if (action.type == UserAction::Type::SELECT_PATHFINDER)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,6 +12,8 @@
|
|||||||
#include "pathfinder/base.hpp"
|
#include "pathfinder/base.hpp"
|
||||||
#include "camera.hpp"
|
#include "camera.hpp"
|
||||||
|
|
||||||
|
using Collision = std::pair<std::weak_ptr<Entity>, std::weak_ptr<Entity>>;
|
||||||
|
|
||||||
class PathFindingDemo {
|
class PathFindingDemo {
|
||||||
public:
|
public:
|
||||||
PathFindingDemo(int width, int height);
|
PathFindingDemo(int width, int height);
|
||||||
@@ -22,26 +24,25 @@ public:
|
|||||||
PathFindingDemo &operator=(const PathFindingDemo &) = delete;
|
PathFindingDemo &operator=(const PathFindingDemo &) = delete;
|
||||||
PathFindingDemo &operator=(PathFindingDemo &&) = delete;
|
PathFindingDemo &operator=(PathFindingDemo &&) = delete;
|
||||||
|
|
||||||
std::shared_ptr<Player> GetPlayer() { return m_Player; }
|
|
||||||
std::vector<std::shared_ptr<Entity>>& GetEntities() { return m_Entities; }
|
std::vector<std::shared_ptr<Entity>>& GetEntities() { return m_Entities; }
|
||||||
const Map& GetMap() const { return m_Map; }
|
const Map& GetMap() const { return m_Map; }
|
||||||
const Camera& GetCamera() const { return m_Camera; }
|
const Camera& GetCamera() const { return m_Camera; }
|
||||||
const pathfinder::Path& GetPath() const { return m_Path; }
|
|
||||||
bool IsExitRequested() const { return m_ExitRequested; }
|
bool IsExitRequested() const { return m_ExitRequested; }
|
||||||
|
|
||||||
void AddEntity(std::shared_ptr<Entity> e);
|
void AddEntity(std::shared_ptr<Entity> e);
|
||||||
void CreateMap();
|
void CreateMap();
|
||||||
std::optional<WorldPos> GetMoveTarget();
|
void UpdateWorld();
|
||||||
void UpdatePlayerVelocity();
|
|
||||||
void HandleActions(const std::vector<UserAction> &actions);
|
void HandleActions(const std::vector<UserAction> &actions);
|
||||||
WorldPos GetRandomPosition() const;
|
WorldPos GetRandomPosition() const;
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
const std::vector<Collision>& GetEntityCollisions();
|
||||||
|
|
||||||
bool m_ExitRequested = false;
|
bool m_ExitRequested = false;
|
||||||
Map m_Map;
|
Map m_Map;
|
||||||
Camera m_Camera;
|
Camera m_Camera;
|
||||||
std::vector<std::shared_ptr<Entity>> m_Entities;
|
std::vector<std::shared_ptr<Entity>> m_Entities;
|
||||||
std::shared_ptr<Player> m_Player;
|
|
||||||
pathfinder::Path m_Path;
|
|
||||||
std::unique_ptr<pathfinder::PathFinderBase> m_PathFinder;
|
std::unique_ptr<pathfinder::PathFinderBase> m_PathFinder;
|
||||||
|
std::vector<std::weak_ptr<Entity>> m_SelectedEntities;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user