From 1017fee4d3682574ff3cff013128c58a38b65d5a Mon Sep 17 00:00:00 2001 From: Maximilian Giller Date: Wed, 10 May 2023 14:51:09 +0200 Subject: [PATCH] Improved directions systems and made basic player movable --- CMakeLists.txt | 2 +- src/config.h | 3 +- src/coordinates/coordinates.h | 19 ++++- src/coordinates/translated_coordinates.cpp | 9 +++ src/coordinates/translated_coordinates.h | 7 +- src/game/input/direction.cpp | 88 +++++++++++++++++----- src/game/input/direction.h | 23 +++++- src/game/input/input_mapper.cpp | 24 +++--- src/game/input/input_mapper.h | 4 +- src/game/player/player.cpp | 37 +++++++++ src/game/player/player.hpp | 13 +++- src/game/world/ITrackable.h | 14 ++++ src/game/world/world_view.cpp | 4 +- src/main.cpp | 2 + src/primitives/circle_object.cpp | 5 ++ src/primitives/circle_object.h | 2 + src/utilities/vector_utils.hpp | 6 ++ 17 files changed, 217 insertions(+), 45 deletions(-) create mode 100644 src/game/world/ITrackable.h diff --git a/CMakeLists.txt b/CMakeLists.txt index d930f4d..d3ec716 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,7 +44,7 @@ set(SOURCES src/game/input/direction.cpp src/game/player/player.cpp src/game/player/player.hpp - src/game/input/game_inputs.hpp src/game/world/world_view.cpp src/game/world/world_view.h src/utilities/smart_list.cpp src/utilities/smart_list.h src/utilities/vector_utils.hpp) + src/game/input/game_inputs.hpp src/game/world/world_view.cpp src/game/world/world_view.h src/utilities/smart_list.cpp src/utilities/smart_list.h src/utilities/vector_utils.hpp src/game/world/ITrackable.h) set(PHYSICS_00_SOURCES src/prototypes/physics_00.cpp) diff --git a/src/config.h b/src/config.h index 842ad34..56fa47a 100644 --- a/src/config.h +++ b/src/config.h @@ -18,7 +18,8 @@ #define ISOMETRIC_SKEW 0.3f #define WORLD_TO_ISO_SCALE 10.0f - +// Directions +#define DIRECTION_HARD_ACTIVATION_THRESHOLD 0.45f // DEBUG diff --git a/src/coordinates/coordinates.h b/src/coordinates/coordinates.h index 04d75ee..f93d441 100644 --- a/src/coordinates/coordinates.h +++ b/src/coordinates/coordinates.h @@ -1,12 +1,18 @@ -// -// Created by max on 27.04.23. -// - #ifndef HOLESOME_COORDINATES_H #define HOLESOME_COORDINATES_H +#include + struct WorldCoordinates { + WorldCoordinates() = default; + + WorldCoordinates(float x, float y, float z = 0) : x(x), y(y), z(z) + {} + + WorldCoordinates(sf::Vector2f vector) : x(vector.x), y(vector.y), z(0) + {} + float x; float y; float z; // Height @@ -55,6 +61,11 @@ struct IsometricCoordinates float x; float y; float depth; // Bigger means further back. Can be used for accurate rendering order. + + sf::Vector2f toScreen() const + { + return {x, y}; + } }; struct GridCoordinates diff --git a/src/coordinates/translated_coordinates.cpp b/src/coordinates/translated_coordinates.cpp index 57f970e..82d959b 100644 --- a/src/coordinates/translated_coordinates.cpp +++ b/src/coordinates/translated_coordinates.cpp @@ -21,6 +21,10 @@ void TranslatedCoordinates::set(WorldCoordinates newWorldCoordinates) { this->worldCoordinates = newWorldCoordinates; } +void TranslatedCoordinates::set(TranslatedCoordinates newCoordinates) { + this->worldCoordinates = newCoordinates.world(); +} + void TranslatedCoordinates::move(WorldCoordinates deltaWorldCoordinates) { this->worldCoordinates = this->worldCoordinates + deltaWorldCoordinates; } @@ -29,4 +33,9 @@ TranslatedCoordinates::TranslatedCoordinates(WorldCoordinates worldCoordinates) : worldCoordinates(worldCoordinates) { } +void TranslatedCoordinates::move(sf::Vector2f deltaWorldCoordinates) +{ + move({deltaWorldCoordinates.x, deltaWorldCoordinates.y, 0}); +} + diff --git a/src/coordinates/translated_coordinates.h b/src/coordinates/translated_coordinates.h index 598f759..7ad9038 100644 --- a/src/coordinates/translated_coordinates.h +++ b/src/coordinates/translated_coordinates.h @@ -11,7 +11,8 @@ #define INITIAL_WORLD_TO_GRID_FACTOR 0.25f -class TranslatedCoordinates { +class TranslatedCoordinates +{ public: explicit TranslatedCoordinates(WorldCoordinates worldCoordinates); @@ -23,8 +24,12 @@ public: void set(WorldCoordinates newWorldCoordinates); + void set(TranslatedCoordinates newCoordinates); + void move(WorldCoordinates deltaWorldCoordinates); + void move(sf::Vector2f deltaWorldCoordinates); + private: WorldCoordinates worldCoordinates; const float worldToGridFactor = INITIAL_WORLD_TO_GRID_FACTOR; diff --git a/src/game/input/direction.cpp b/src/game/input/direction.cpp index c23ce52..f2be262 100644 --- a/src/game/input/direction.cpp +++ b/src/game/input/direction.cpp @@ -1,51 +1,105 @@ #include #include "direction.h" #include "../../utilities/vector_utils.hpp" +#include "../../config.h" -InputDirection Direction::getDirection(sf::Keyboard::Key key) +HardDirection Direction::getKeyDirection(sf::Keyboard::Key key) { - auto map = std::map(); - map[sf::Keyboard::W] = InputDirection::UP; - map[sf::Keyboard::S] = InputDirection::DOWN; - map[sf::Keyboard::A] = InputDirection::LEFT; - map[sf::Keyboard::D] = InputDirection::RIGHT; - map[sf::Keyboard::Up] = InputDirection::UP; - map[sf::Keyboard::Down] = InputDirection::DOWN; - map[sf::Keyboard::Left] = InputDirection::LEFT; - map[sf::Keyboard::Right] = InputDirection::RIGHT; + auto map = std::map(); + map[sf::Keyboard::W] = HardDirection::UP; + map[sf::Keyboard::S] = HardDirection::DOWN; + map[sf::Keyboard::A] = HardDirection::LEFT; + map[sf::Keyboard::D] = HardDirection::RIGHT; + map[sf::Keyboard::Up] = HardDirection::UP; + map[sf::Keyboard::Down] = HardDirection::DOWN; + map[sf::Keyboard::Left] = HardDirection::LEFT; + map[sf::Keyboard::Right] = HardDirection::RIGHT; if (map.find(key) == map.end()) - return InputDirection::NONE; + return HardDirection::NONE; return map[key]; } -sf::Vector2f Direction::getVector(InputDirection direction) +sf::Vector2f Direction::getVector(HardDirection direction) { auto vector = sf::Vector2f(0.0f, 0.0f); - if (direction == InputDirection::NONE) + if (direction == HardDirection::NONE) { return vector; } // Combine all relevant directions into one vector - if (direction & InputDirection::UP) + if (direction & HardDirection::UP) { vector.y -= 1; } - if (direction & InputDirection::DOWN) + if (direction & HardDirection::DOWN) { vector.y += 1; } - if (direction & InputDirection::LEFT) + if (direction & HardDirection::LEFT) { vector.x -= 1; } - if (direction & InputDirection::RIGHT) + if (direction & HardDirection::RIGHT) { vector.x += 1; } return normalize(vector); } + +HardDirection Direction::getHardDirection(sf::Vector2f vector) +{ + HardDirection direction = HardDirection::NONE; + vector = normalize(vector); + auto absVector = abs(vector); + + // X axis + if (absVector.x >= DIRECTION_HARD_ACTIVATION_THRESHOLD) + { + if (vector.x > 0) + { + direction = static_cast(direction | HardDirection::RIGHT); + } else + { + direction = static_cast(direction | HardDirection::LEFT); + } + } + + // Y axis + if (absVector.y >= DIRECTION_HARD_ACTIVATION_THRESHOLD) + { + if (vector.y > 0) + { + direction = static_cast(direction | HardDirection::DOWN); + } else + { + direction = static_cast(direction | HardDirection::UP); + } + } + + return direction; +} + +sf::Vector2f Direction::asVector() const +{ + return directionVector; +} + +HardDirection Direction::asHardDirection() const +{ + return getHardDirection(directionVector); +} + +Direction::Direction(sf::Vector2f directionVector) +{ + this->directionVector = directionVector; +} + +Direction::Direction(HardDirection direction) +{ + this->directionVector = getVector(direction); +} diff --git a/src/game/input/direction.h b/src/game/input/direction.h index 47b7dd9..db9ebad 100644 --- a/src/game/input/direction.h +++ b/src/game/input/direction.h @@ -4,7 +4,7 @@ #include #include -enum InputDirection +enum HardDirection { NONE = 0, UP = 1, @@ -13,11 +13,26 @@ enum InputDirection RIGHT = 8 }; -class Direction +struct Direction { public: - static InputDirection getDirection(sf::Keyboard::Key key); - static sf::Vector2f getVector(InputDirection direction); + explicit Direction(sf::Vector2f directionVector); + + explicit Direction(HardDirection direction); + + static HardDirection getKeyDirection(sf::Keyboard::Key key); + + static sf::Vector2f getVector(HardDirection direction); + + static HardDirection getHardDirection(sf::Vector2f vector); + +public: + sf::Vector2f asVector() const; + + HardDirection asHardDirection() const; + +private: + sf::Vector2f directionVector; }; #endif //HOLESOME_DIRECTION_H diff --git a/src/game/input/input_mapper.cpp b/src/game/input/input_mapper.cpp index aa1fe78..af70a98 100644 --- a/src/game/input/input_mapper.cpp +++ b/src/game/input/input_mapper.cpp @@ -40,33 +40,33 @@ void InputMapper::handleKeyPress(sf::Event::KeyEvent event) return; } - // Handle direction - auto direction = Direction::getDirection(event.code); - if (direction != InputDirection::NONE) + // Handle directionVector + auto direction = Direction::getKeyDirection(event.code); + if (direction != HardDirection::NONE) { inputDirectionBuffer.push_back(direction); } } -InputDirection InputMapper::getInputDirection() +Direction InputMapper::getInputDirection() { - InputDirection direction = InputDirection::NONE; + HardDirection direction = HardDirection::NONE; - for (InputDirection directionPart: inputDirectionBuffer) + for (HardDirection directionPart: inputDirectionBuffer) { - direction = static_cast(direction | directionPart); + direction = static_cast(direction | directionPart); } - return direction; + return Direction(direction); } void InputMapper::handleKeyRelease(sf::Event::KeyEvent event) { - // Handle direction - auto direction = Direction::getDirection(event.code); - if (direction != InputDirection::NONE) + // Handle directionVector + auto direction = Direction::getKeyDirection(event.code); + if (direction != HardDirection::NONE) { - // Remove direction from buffer + // Remove directionVector from buffer inputDirectionBuffer.erase(std::remove(inputDirectionBuffer.begin(), inputDirectionBuffer.end(), direction), inputDirectionBuffer.end()); } diff --git a/src/game/input/input_mapper.h b/src/game/input/input_mapper.h index 61c80a3..849de26 100644 --- a/src/game/input/input_mapper.h +++ b/src/game/input/input_mapper.h @@ -18,12 +18,12 @@ public: static void processEvents(); - static InputDirection getInputDirection(); + static Direction getInputDirection(); private: static inline Game *game = nullptr; - static inline std::vector inputDirectionBuffer = std::vector(); + static inline std::vector inputDirectionBuffer = std::vector(); static void handleKeyPress(sf::Event::KeyEvent event); diff --git a/src/game/player/player.cpp b/src/game/player/player.cpp index 5015568..ecb7807 100644 --- a/src/game/player/player.cpp +++ b/src/game/player/player.cpp @@ -1 +1,38 @@ #include "player.hpp" + +sf::Vector2f Player::getTrackablePosition() const +{ + return coordinates.isometric().toScreen(); +} + +sf::Vector2f Player::getTrackableSize() const +{ + // TODO: Proper implementation + return {static_cast(circle->getRadius() * 2), static_cast(circle->getRadius() * 2)}; +} + +void Player::update(Game *game) +{ + auto moveDirection = InputMapper::getInputDirection().asVector(); + auto moveDelta = moveDirection * 10.0f * FRAME_TIME.asSeconds(); + coordinates.move(moveDelta); + circle->coordinates.set(coordinates); +} + +void Player::draw(sf::RenderWindow *window) const +{ + circle->draw(window); +} + +Player::~Player() +{ + delete circle; +} + +Player::Player(const sf::Color color, WorldCoordinates initCoordinates) +{ + coordinates.set(initCoordinates); + + circle = new CircleObject(50, color); + circle->coordinates.set(coordinates); +} diff --git a/src/game/player/player.hpp b/src/game/player/player.hpp index 7949e57..30a5124 100644 --- a/src/game/player/player.hpp +++ b/src/game/player/player.hpp @@ -2,17 +2,28 @@ #define HOLESOME_PLAYER_HPP #include "../game_object.h" +#include "../world/ITrackable.h" +#include "../../primitives/circle_object.h" -class Player : GameObject +class Player : public GameObject, public ITrackable { public: Player(); + Player(const sf::Color color, WorldCoordinates initCoordinates); + ~Player(); void draw(sf::RenderWindow *window) const override; void update(Game *game) override; + + sf::Vector2f getTrackablePosition() const override; + + sf::Vector2f getTrackableSize() const override; + +private: + CircleObject *circle; }; diff --git a/src/game/world/ITrackable.h b/src/game/world/ITrackable.h new file mode 100644 index 0000000..a143a4c --- /dev/null +++ b/src/game/world/ITrackable.h @@ -0,0 +1,14 @@ +#ifndef HOLESOME_ITRACKABLE_H +#define HOLESOME_ITRACKABLE_H + +#include + +class ITrackable +{ +public: + virtual sf::Vector2f getTrackablePosition() const = 0; + + virtual sf::Vector2f getTrackableSize() const = 0; +}; + +#endif //HOLESOME_ITRACKABLE_H diff --git a/src/game/world/world_view.cpp b/src/game/world/world_view.cpp index e4338c4..0c39cb0 100644 --- a/src/game/world/world_view.cpp +++ b/src/game/world/world_view.cpp @@ -51,8 +51,8 @@ void WorldView::setSize(sf::Vector2u windowSize) void WorldView::moveViewByControls() { - auto moveDirection = InputMapper::getInputDirection(); - if (moveDirection == InputDirection::NONE) + auto moveDirection = InputMapper::getInputDirection().asHardDirection(); + if (moveDirection == HardDirection::NONE) { return; } diff --git a/src/main.cpp b/src/main.cpp index 501ce1d..589efd1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,6 +4,7 @@ #include "game/game_factory.hpp" #include "debug/grid_debug_layer.h" #include "game/world/world_view.h" +#include "game/player/player.hpp" INITIALIZE_EASYLOGGINGPP @@ -15,6 +16,7 @@ int main(int argc, char *argv[]) game->addGameObject(new GridDebugLayer(0, 50, 0, 50)); game->addGameObject(new WorldView()); + game->addGameObject(new Player(sf::Color::Blue, WorldCoordinates(0, 0))); game->run(); } diff --git a/src/primitives/circle_object.cpp b/src/primitives/circle_object.cpp index 19f5f99..6752545 100644 --- a/src/primitives/circle_object.cpp +++ b/src/primitives/circle_object.cpp @@ -20,4 +20,9 @@ void CircleObject::update(Game *game) } +int CircleObject::getRadius() const +{ + return radius; +} + diff --git a/src/primitives/circle_object.h b/src/primitives/circle_object.h index 8e2f9cc..f4081da 100644 --- a/src/primitives/circle_object.h +++ b/src/primitives/circle_object.h @@ -12,6 +12,8 @@ public: void draw(sf::RenderWindow *window) const override; void update(Game *game) override; + int getRadius() const; + private: int radius; sf::Color color; diff --git a/src/utilities/vector_utils.hpp b/src/utilities/vector_utils.hpp index be0a814..2391f1e 100644 --- a/src/utilities/vector_utils.hpp +++ b/src/utilities/vector_utils.hpp @@ -16,4 +16,10 @@ sf::Vector2 normalize(sf::Vector2 v) return v; } +template +sf::Vector2 abs(sf::Vector2 v) +{ + return sf::Vector2(std::abs(v.x), std::abs(v.y)); +} + #endif //HOLESOME_VECTOR_UTILS_HPP