From 82eb2e25391089ed11424e4b05d2c8875cded93d Mon Sep 17 00:00:00 2001 From: Jan Mrna Date: Sat, 27 Sep 2025 13:49:17 +0200 Subject: [PATCH] Move entities implementation to entity.cpp --- cpp/Makefile | 2 +- cpp/src/entities.cpp | 66 ++++++++++++++++++ cpp/src/entities.hpp | 149 ++++++++++------------------------------- cpp/src/user_input.hpp | 1 + 4 files changed, 104 insertions(+), 114 deletions(-) diff --git a/cpp/Makefile b/cpp/Makefile index 305c39a..d7903b6 100644 --- a/cpp/Makefile +++ b/cpp/Makefile @@ -3,7 +3,7 @@ all: test pathfinding # TODO linter? pathfinding: src/main.cpp src/array.hpp src/sprite.cpp - g++ -Wall -ggdb3 -lSDL3 -lSDL3_image -std=c++23 -lGLEW -lGL -o pathfinding src/main.cpp src/sprite.cpp + g++ -Wall -ggdb3 -lSDL3 -lSDL3_image -std=c++23 -lGLEW -lGL -o pathfinding src/main.cpp src/sprite.cpp src/entities.cpp test: src/test.cpp src/array.hpp g++ -Wall -Wextra -Wpedantic -ggdb3 -std=c++23 -lgtest -o test src/test.cpp diff --git a/cpp/src/entities.cpp b/cpp/src/entities.cpp index e69de29..0122f12 100644 --- a/cpp/src/entities.cpp +++ b/cpp/src/entities.cpp @@ -0,0 +1,66 @@ +#include + +#include "entities.hpp" + +#include "log.hpp" +#include "math.hpp" +#include "sprite.hpp" + +Entity::Entity(WorldPos position) : m_Position(position) { + LOG_DEBUG("spawning entity at position ", position); +} + +std::ostream &operator<<(std::ostream &os, const Entity &obj) { + static constexpr std::array(Entity::Type::COUNT)> + type_name{"NONE", "PLAYER", "TILE"}; + size_t idx = static_cast(obj.GetType()); + assert(idx < type_name.size()); + os << type_name[idx]; + return os; +} + +void Entity::ZeroActualVelocityInDirection(WorldPos direction) { + // Vectors e1, e2 form the basis for a local coord system, + // where e1 is formed by the direction where we want to zero-out + // the velocity, and e2 is the orthogonal vector. + // Scalars q1, q2 are coordinates for e1, e2 basis. + WorldPos e1 = direction.normalized(); + WorldPos e2 = e1.orthogonal(); + + // q1 * e1 + q2 * e2 = v, from this follows: + auto &v = GetActualVelocity(); + float q2 = (v.y * e1.x - v.x * e1.y) / (e2.y * e1.x - e2.x * e1.y); + float q1 = (v.x - q2 * e2.x) / e1.x; + + // We then zero-out the q1, but only if it's positive - meaning + // it is aiming in the direction of "direction", not out. + // (otherwise we're not able to move out from collision with + // another object) + if (q1 > 0.0f) { + SetActualVelocity(q2 * e2); + } +} + +void Entity::Update(float time_delta) { + m_Position += m_ActualVelocity * time_delta; +} + +Player::Player() { + LOG_DEBUG("."); + if (m_Sprite == nullptr) { + LoadResources(); + } +} + +Sprite &Player::GetSprite() { + assert(m_Sprite != nullptr); + return *m_Sprite; +} + +void Player::LoadResources() { + m_Sprite = + std::make_unique("resources/player.png", WorldPos{38.0f, 46.0f}); +} + +std::unique_ptr Player::m_Sprite; diff --git a/cpp/src/entities.hpp b/cpp/src/entities.hpp index a195662..bed7204 100644 --- a/cpp/src/entities.hpp +++ b/cpp/src/entities.hpp @@ -6,141 +6,71 @@ #include #include +#include "log.hpp" #include "math.hpp" #include "sprite.hpp" -#include "log.hpp" class Entity { public: enum class Type : std::uint8_t { NONE, PLAYER, - WALL, TILE, COUNT // must be last }; - Entity(Vec2D position = {0.0f, 0.0f}) : m_Position(position) { - LOG_DEBUG("spawning entity at position ", position); - } + Entity(WorldPos position = {0.0f, 0.0f}); + Entity(const Entity &) = delete; + Entity &operator=(const Entity &) = delete; + Entity(Entity &&) = delete; + Entity &operator=(Entity &&) = delete; - friend std::ostream &operator<<(std::ostream &os, const Entity &obj) { - static constexpr std::array(Entity::Type::COUNT)> - type_name{"NONE", "PLAYER", "WALL", "TILE"}; - size_t idx = static_cast(obj.GetType()); - assert(idx < type_name.size()); - os << type_name[idx]; - return os; - } + friend std::ostream &operator<<(std::ostream &os, const Entity &obj); virtual Sprite &GetSprite() = 0; virtual constexpr float GetCollisionRadius() const = 0; - virtual constexpr float GetCollisionRadiusSquared() { - return GetCollisionRadius() * GetCollisionRadius(); - } - virtual constexpr Type GetType() const = 0; - void SetFlagExpired() { m_FlagExpired = true; } - bool IsFlaggedExpired() { return m_FlagExpired; } - - const Vec2D &GetPosition() const { return m_Position; } - void SetPosition(Vec2D new_pos) { m_Position = new_pos; } - - const Vec2D &GetActualVelocity() const { return m_ActualVelocity; } - const Vec2D &GetRequestedVelocity() const { - return m_RequestedVelocity; - } - void SetActualVelocity(const Vec2D &new_velocity) { - m_ActualVelocity = new_velocity; - } - void SetRequestedVelocity(const Vec2D &new_velocity) { - m_RequestedVelocity = new_velocity; - } - - void ZeroActualVelocityInDirection(Vec2D direction) { - // Vectors e1, e2 form the basis for a local coord system, - // where e1 is formed by the direction where we want to zero-out - // the velocity, and e2 is the orthogonal vector. - // Scalars q1, q2 are coordinates for e1, e2 basis. - Vec2D e1 = direction.normalized(); - Vec2D e2 = e1.orthogonal(); - - // q1 * e1 + q2 * e2 = v, from this follows: - auto &v = GetActualVelocity(); - float q2 = (v.y * e1.x - v.x * e1.y) / (e2.y * e1.x - e2.x * e1.y); - float q1 = (v.x - q2 * e2.x) / e1.x; - - // We then zero-out the q1, but only if it's positive - meaning - // it is aiming in the direction of "direction", not out. - // (otherwise we're not able to move out from collision with - // another object) - if (q1 > 0.0f) { - SetActualVelocity(q2 * e2); - } - } - - virtual void Update(float time_delta) { - m_Position += m_ActualVelocity * time_delta; - } - virtual bool IsMovable() const = 0; virtual bool IsCollidable() const = 0; + virtual void Update(float time_delta); + + virtual constexpr float GetCollisionRadiusSquared() const { + return GetCollisionRadius() * GetCollisionRadius(); + } + + void SetFlagExpired() { m_FlagExpired = true; } + bool IsFlaggedExpired() const { return m_FlagExpired; } + + const WorldPos &GetPosition() const { return m_Position; } + void SetPosition(WorldPos new_pos) { m_Position = new_pos; } + + const WorldPos &GetActualVelocity() const { return m_ActualVelocity; } + const WorldPos &GetRequestedVelocity() const { return m_RequestedVelocity; } + void SetActualVelocity(const WorldPos &new_velocity) { + m_ActualVelocity = new_velocity; + } + void SetRequestedVelocity(const WorldPos &new_velocity) { + m_RequestedVelocity = new_velocity; + } + + void ZeroActualVelocityInDirection(WorldPos direction); + protected: - Vec2D m_Position; - Vec2D m_ActualVelocity; - Vec2D m_RequestedVelocity; + WorldPos m_Position; + WorldPos m_ActualVelocity; + WorldPos m_RequestedVelocity; private: bool m_FlagExpired = false; static constexpr float m_CollisionRadiusSq = 1000.0f; }; -class Wall final : public Entity { -public: - Wall(Vec2D pos = {0.0f, 0.0f}) : Entity(pos) { - LOG_DEBUG("."); - if (m_Sprite == nullptr) { - LoadResources(); - } - } - Wall(const Wall &x) = delete; - Wall(Wall &&x) = delete; - - Sprite &GetSprite() override { - assert(m_Sprite != nullptr); - return *m_Sprite; - } - constexpr Entity::Type GetType() const override { return Entity::Type::WALL; } - constexpr float GetCollisionRadius() const override { return 50.0f; } - bool IsMovable() const override { return false; } - bool IsCollidable() const override { return true; } - -private: - void LoadResources() { - m_Sprite = std::make_unique("resources/wall.png", - Vec2D{50.0f, 50.0f}); - } - static std::unique_ptr m_Sprite; -}; -std::unique_ptr Wall::m_Sprite; - class Player final : public Entity { public: - Player() { - LOG_DEBUG("."); - if (m_Sprite == nullptr) { - LoadResources(); - } - } - Player(const Player &x) = delete; - Player(Player &&x) = delete; + Player(); - Sprite &GetSprite() override { - assert(m_Sprite != nullptr); - return *m_Sprite; - } + Sprite &GetSprite() override; constexpr Entity::Type GetType() const override { return Entity::Type::PLAYER; @@ -150,13 +80,6 @@ public: bool IsCollidable() const override { return true; } private: - void LoadResources() { - m_Sprite = std::make_unique("resources/player.png", - Vec2D{38.0f, 46.0f}); - } + void LoadResources(); static std::unique_ptr m_Sprite; }; - -std::unique_ptr Player::m_Sprite; - - diff --git a/cpp/src/user_input.hpp b/cpp/src/user_input.hpp index 425cefd..c67aae1 100644 --- a/cpp/src/user_input.hpp +++ b/cpp/src/user_input.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "math.hpp" #include "log.hpp"