diff --git a/lib/include/chomper/player.hpp b/lib/include/chomper/player.hpp index a96fe7c..065b01c 100644 --- a/lib/include/chomper/player.hpp +++ b/lib/include/chomper/player.hpp @@ -19,7 +19,8 @@ class Player : public IController::IListener, public IDebugInspector, public kli void draw(le::IRenderer& renderer) const; private: - bool selfCollides() const; + [[nodiscard]] bool isCollidingWithSelf(glm::vec2 targetGrid) const; + [[nodiscard]] bool isCollidingWithWall(glm::vec2 targetGrid) const; void move(); // IController::IListener diff --git a/lib/include/chomper/world_space.hpp b/lib/include/chomper/world_space.hpp index e56844e..ef9c337 100644 --- a/lib/include/chomper/world_space.hpp +++ b/lib/include/chomper/world_space.hpp @@ -1,5 +1,6 @@ #pragma once #include "chomper/world_size.hpp" +#include "glm/common.hpp" #include namespace chomper::worldSpace { @@ -16,4 +17,8 @@ constexpr auto gridToWorld(glm::vec2 gridPosition) { constexpr auto worldToGrid(glm::vec2 worldPosition) { return glm::floor((worldPosition - tileOffset) / tileSize_v) + halfGridSize; } + +constexpr auto isOutOfBounds(glm::vec2 gridPoint) { + return gridPoint.x <= 0 || gridPoint.y <= 0 || gridPoint.x > worldSize_v.x || gridPoint.y > worldSize_v.y; +} } // namespace chomper::worldSpace \ No newline at end of file diff --git a/lib/src/player.cpp b/lib/src/player.cpp index 27cada5..9cd6621 100644 --- a/lib/src/player.cpp +++ b/lib/src/player.cpp @@ -27,13 +27,22 @@ void Player::tick(kvf::Seconds dt) { } } -bool Player::selfCollides() const { - auto targetGrid = worldSpace::worldToGrid(m_snake.getSegments().back().transform.position) + headingToDir_v[m_heading]; +bool Player::isCollidingWithSelf(glm::vec2 const targetGrid) const { + if (m_snake.getSegments().empty()) { + return false; + } return std::ranges::any_of(m_snake.getSegments(), [targetGrid](le::RenderInstance const& s) { return worldSpace::worldToGrid(s.transform.position) == targetGrid; }); } +bool Player::isCollidingWithWall(glm::vec2 const targetGrid) const { + if (m_snake.getSegments().empty()) { + return false; + } + return worldSpace::isOutOfBounds(targetGrid); +} + void Player::move() { // no body, no movement if (m_snake.getSegments().empty()) { @@ -45,7 +54,8 @@ void Player::move() { m_headingQueue.erase(m_headingQueue.begin()); } - if (selfCollides()) { + auto const targetGrid = worldSpace::worldToGrid(m_snake.getSegments().back().transform.position) + headingToDir_v[m_heading]; + if (isCollidingWithSelf(targetGrid) || isCollidingWithWall(targetGrid)) { if (m_graceMove) { m_engine->setNextRuntime(); } else {