From b5d7dfede94137934f7b00d96e07dadf2a1954a5 Mon Sep 17 00:00:00 2001 From: Maximilian Giller Date: Thu, 29 Jun 2023 21:26:30 +0200 Subject: [PATCH] Fixed and expanded coordinate system, and some more physics WIP --- CMakeLists.txt | 21 ++- TODO.md | 2 +- src/config.h | 5 +- src/coordinates/coordinate_transformer.cpp | 53 +++++++- src/coordinates/coordinate_transformer.h | 4 + src/coordinates/coordinates.h | 21 +++ src/coordinates/translated_coordinates.cpp | 39 ++++-- src/coordinates/translated_coordinates.h | 5 + src/game/collectables/collectable.cpp | 9 +- src/game/collectables/collectable.hpp | 2 +- .../collection/collectables_collection.cpp | 9 +- src/game/game_factory.cpp | 2 +- src/game/game_object.cpp | 5 + src/game/game_object.h | 1 + src/game/level/level_loader.cpp | 9 +- .../physics/holes/collectable_simulation.cpp | 56 +++++--- .../physics/holes/collectable_simulation.hpp | 4 + .../holes/layouts/depth_hole_description.hpp | 4 + .../holes/layouts/depth_hole_layout.hpp | 4 + .../holes/layouts/hole_description.hpp | 17 +++ .../physics/holes/layouts/hole_layout.cpp | 10 ++ .../physics/holes/layouts/hole_layout.hpp | 3 + src/game/player/player_collection.cpp | 4 +- src/prototypes/coordinates_00.cpp | 121 ++++++++++++++++++ src/utilities/vector_utils.hpp | 8 +- 25 files changed, 367 insertions(+), 51 deletions(-) create mode 100644 src/prototypes/coordinates_00.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index cc6fea8..913b59d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -116,20 +116,35 @@ set(SOURCES src/game/physics/holes/collectable_simulation.cpp src/game/physics/holes/collectable_simulation.hpp src/game/physics/holes/holes_simulation.cpp - src/game/physics/holes/holes_simulation.hpp src/game/physics/holes/layouts/hole_description.hpp src/game/physics/holes/layouts/hole_layout.cpp src/game/physics/holes/layouts/hole_layout.hpp src/game/physics/holes/layouts/depth_hole_layout.hpp src/game/physics/holes/layouts/depth_hole_description.hpp) + src/game/physics/holes/holes_simulation.hpp + src/game/physics/holes/layouts/hole_description.hpp + src/game/physics/holes/layouts/hole_layout.cpp + src/game/physics/holes/layouts/hole_layout.hpp + src/game/physics/holes/layouts/depth_hole_layout.hpp + src/game/physics/holes/layouts/depth_hole_description.hpp) set(PHYSICS_00_SOURCES - src/prototypes/physics_00.cpp) + src/prototypes/physics_00.cpp) set(MATH_00_SOURCES src/prototypes/math_00.cpp) +set(COORDINATES_00_SOURCES + src/prototypes/coordinates_00.cpp + src/coordinates/coordinates.h + src/coordinates/coordinate_transformer.h + src/coordinates/coordinate_transformer.cpp + src/coordinates/translated_coordinates.h + src/coordinates/translated_coordinates.cpp) + # Add an executable target add_executable(Holesome ${SOURCES}) add_executable(Physics_00 ${PHYSICS_00_SOURCES}) add_executable(Math_00 ${MATH_00_SOURCES}) +add_executable(Coordinates_00 ${COORDINATES_00_SOURCES}) + # Link SFML and other libraries to your executable target target_link_libraries(Holesome sfml-graphics sfml-audio) target_link_libraries(Holesome Eigen3::Eigen) @@ -139,6 +154,8 @@ target_link_libraries(Physics_00 box2d::box2d) target_link_libraries(Math_00 Eigen3::Eigen) +target_link_libraries(Coordinates_00 Eigen3::Eigen) + # Assets add_custom_target(copy_assets COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_LIST_DIR}/assets ${CMAKE_CURRENT_BINARY_DIR}/assets diff --git a/TODO.md b/TODO.md index 9622f7e..a59aa5b 100644 --- a/TODO.md +++ b/TODO.md @@ -6,7 +6,6 @@ ## Bugs -- Player spawns initially at (0,0) and almost fails to jump to target spawn - Player disconnect in multiplayer sometimes targeting disconnected player or something like that ## High priority @@ -14,6 +13,7 @@ - Physics - Players-join-screen before the game starts +- Short input delay when a new identity connects, to avoid accidental inputs at beginning - Procedural points generation - Game over screen - Proper player graphics diff --git a/src/config.h b/src/config.h index 72edde3..a292354 100644 --- a/src/config.h +++ b/src/config.h @@ -13,7 +13,7 @@ #define PLAYER_RADIUS_PER_LEVEL 0.25f // World -#define WORLD_GRAVITY b2Vec2(0.f, -9.8f) +#define WORLD_GRAVITY b2Vec2(0.f, 0.f) #define SKY_HEIGHT_SCALE 2.f // FPS @@ -49,9 +49,10 @@ #define COLLECTABLES_SIM_LINEAR_DAMPING 0.5f #define COLLECTABLES_SIM_ANGULAR_DAMPING 0.5f #define COLLECTABLES_SIM_DENSITY 1.f -#define COLLECTABLES_SIM_FRICTION 0.3f +#define COLLECTABLES_SIM_FRICTION 0.0f #define COLLECTABLES_SIM_RESTITUTION 0.5f #define COLLECTABLES_SIM_SLEEPING true +#define COLLECTABLES_SIM_GROUND_THICKNESS 0.1f // Directions #define DIRECTION_HARD_ACTIVATION_THRESHOLD 0.1f diff --git a/src/coordinates/coordinate_transformer.cpp b/src/coordinates/coordinate_transformer.cpp index 15a99aa..887a706 100644 --- a/src/coordinates/coordinate_transformer.cpp +++ b/src/coordinates/coordinate_transformer.cpp @@ -1,11 +1,12 @@ #include "coordinate_transformer.h" #include "../config.h" #include "../logging/easylogging++.h" +#include "../utilities/vector_utils.hpp" // Initialize matrix const Eigen::Matrix CoordinateTransformer::worldToIsometricMatrix = (Eigen::Matrix() << - 1, -1, 0, + 1, -1, 0, -ISOMETRIC_SKEW, -ISOMETRIC_SKEW, -1, 1, 1, 0 ).finished(); @@ -17,19 +18,21 @@ IsometricCoordinates CoordinateTransformer::worldToIsometric(WorldCoordinates wo Eigen::Vector3f isoCoordinatesVector = worldToIsometricMatrix * worldCoordinatesVector; - return IsometricCoordinates( + return { isoCoordinatesVector.x() * WORLD_TO_ISO_SCALE, // x isoCoordinatesVector.y() * WORLD_TO_ISO_SCALE, // y isoCoordinatesVector.z() // depth - ); + }; } WorldCoordinates CoordinateTransformer::isometricToWorld(IsometricCoordinates isometricCoordinates) { -Eigen::Vector3f isoCoordinatesVector; - isoCoordinatesVector << isometricCoordinates.x, isometricCoordinates.y, isometricCoordinates.depth; + Eigen::Vector3f isoCoordinatesVector; + isoCoordinatesVector << isometricCoordinates.x / WORLD_TO_ISO_SCALE, + isometricCoordinates.y / WORLD_TO_ISO_SCALE, + isometricCoordinates.depth; - Eigen::Vector3f worldCoordinatesVector = worldToIsometricMatrix.inverse() * isoCoordinatesVector / WORLD_TO_ISO_SCALE; + Eigen::Vector3f worldCoordinatesVector = worldToIsometricMatrix.inverse() * isoCoordinatesVector; return { worldCoordinatesVector.x(), // x @@ -37,3 +40,41 @@ Eigen::Vector3f isoCoordinatesVector; worldCoordinatesVector.z() // z }; } + +float CoordinateTransformer::worldToDepth(sf::Vector2f worldGroundCoordinates) +{ + return CoordinateTransformer::worldToIsometric({worldGroundCoordinates.x, worldGroundCoordinates.y, 0}).depth; +} + +sf::Vector2f CoordinateTransformer::closestWorldPointAtDepth(float depth, sf::Vector2f referenceWorldPoint) +{ + float depthAtReferencePoint = worldToDepth(referenceWorldPoint); + float depthDifference = depth - depthAtReferencePoint; + float stepSizePerAxis = depthDifference / 2.f; + return referenceWorldPoint + sf::Vector2f(stepSizePerAxis, stepSizePerAxis); +} + +DiagonalWorldCoordinates CoordinateTransformer::worldToDiagonal(WorldCoordinates worldCoordinates) +{ + auto depth = CoordinateTransformer::worldToDepth(worldCoordinates.toGroundCoordinates()); + + auto depthCenterCoordinates = CoordinateTransformer::closestWorldPointAtDepth(depth, {0, 0}); + auto horizontal = length(worldCoordinates.toGroundCoordinates() - depthCenterCoordinates); + + return {horizontal, worldCoordinates.z, depth}; +} + +WorldCoordinates CoordinateTransformer::diagonalToWorld(DiagonalWorldCoordinates diagonalWorldCoordinates) +{ + auto depthCenterCoordinates = CoordinateTransformer::closestWorldPointAtDepth(diagonalWorldCoordinates.depth, + {0, 0}); + + auto const horizontalAxis = sf::Vector2f(1, -1); + auto worldGroundCoordinates = depthCenterCoordinates + horizontalAxis * diagonalWorldCoordinates.horizontal; + + return { + worldGroundCoordinates.x, + worldGroundCoordinates.y, + diagonalWorldCoordinates.vertical + }; +} diff --git a/src/coordinates/coordinate_transformer.h b/src/coordinates/coordinate_transformer.h index 49eed93..35508a6 100644 --- a/src/coordinates/coordinate_transformer.h +++ b/src/coordinates/coordinate_transformer.h @@ -12,6 +12,10 @@ private: public: static IsometricCoordinates worldToIsometric(WorldCoordinates worldCoordinates); static WorldCoordinates isometricToWorld(IsometricCoordinates isometricCoordinates); + static DiagonalWorldCoordinates worldToDiagonal(WorldCoordinates worldCoordinates); + static WorldCoordinates diagonalToWorld(DiagonalWorldCoordinates diagonalWorldCoordinates); + static float worldToDepth(sf::Vector2f worldGroundCoordinates); + static sf::Vector2f closestWorldPointAtDepth(float depth, sf::Vector2f referenceWorldPoint); }; diff --git a/src/coordinates/coordinates.h b/src/coordinates/coordinates.h index de1419d..ed55cf6 100644 --- a/src/coordinates/coordinates.h +++ b/src/coordinates/coordinates.h @@ -2,6 +2,9 @@ #define HOLESOME_COORDINATES_H #include +#include "../utilities/vector_utils.hpp" + +class DiagonalWorldCoordinates; struct WorldCoordinates { @@ -54,6 +57,11 @@ struct WorldCoordinates { return !(*this == other); } + + [[nodiscard]] sf::Vector2f toGroundCoordinates() const + { + return {x, y}; + } }; struct IsometricCoordinates @@ -76,6 +84,19 @@ struct IsometricCoordinates {} }; +struct DiagonalWorldCoordinates +{ + float horizontal; + float vertical; + float depth; // Bigger means further back. Can be used for accurate rendering order. + + const sf::Vector2f horizontalAxis = {1, -1}; + + DiagonalWorldCoordinates(float horizontal, float vertical, float depth) : horizontal(horizontal), + vertical(vertical), depth(depth) + {} +}; + struct GridCoordinates { float x; diff --git a/src/coordinates/translated_coordinates.cpp b/src/coordinates/translated_coordinates.cpp index e761c19..07f4d03 100644 --- a/src/coordinates/translated_coordinates.cpp +++ b/src/coordinates/translated_coordinates.cpp @@ -2,7 +2,8 @@ #include -WorldCoordinates TranslatedCoordinates::world() const { +WorldCoordinates TranslatedCoordinates::world() const +{ auto coordinates = worldCoordinates; if (parent != nullptr) { @@ -12,35 +13,42 @@ WorldCoordinates TranslatedCoordinates::world() const { return coordinates; } -IsometricCoordinates TranslatedCoordinates::isometric() const { +IsometricCoordinates TranslatedCoordinates::isometric() const +{ return CoordinateTransformer::worldToIsometric(world()); } -GridCoordinates TranslatedCoordinates::grid() const { +GridCoordinates TranslatedCoordinates::grid() const +{ auto referenceWordCoordinates = world(); // Grid coords are just camera coords without height, and scaled differently return {referenceWordCoordinates.x - 0.5f, referenceWordCoordinates.y - 0.5f}; } -void TranslatedCoordinates::setWorld(WorldCoordinates newWorldCoordinates) { +void TranslatedCoordinates::setWorld(WorldCoordinates newWorldCoordinates) +{ this->worldCoordinates = newWorldCoordinates; } -void TranslatedCoordinates::setIsometric(IsometricCoordinates newIsometricCoordinates) { +void TranslatedCoordinates::setIsometric(IsometricCoordinates newIsometricCoordinates) +{ this->worldCoordinates = CoordinateTransformer::isometricToWorld(newIsometricCoordinates); } -void TranslatedCoordinates::setTranslated(const TranslatedCoordinates& newCoordinates) { +void TranslatedCoordinates::setTranslated(const TranslatedCoordinates &newCoordinates) +{ this->worldCoordinates = newCoordinates.world(); } -void TranslatedCoordinates::move(WorldCoordinates deltaWorldCoordinates) { +void TranslatedCoordinates::move(WorldCoordinates deltaWorldCoordinates) +{ this->worldCoordinates = this->worldCoordinates + deltaWorldCoordinates; } TranslatedCoordinates::TranslatedCoordinates(WorldCoordinates worldCoordinates) - : worldCoordinates(worldCoordinates) { + : worldCoordinates(worldCoordinates) +{ } void TranslatedCoordinates::move(sf::Vector2f deltaWorldCoordinates) @@ -73,3 +81,18 @@ TranslatedCoordinates::TranslatedCoordinates(GridCoordinates gridCoordinates) { setGrid(gridCoordinates); } + +DiagonalWorldCoordinates TranslatedCoordinates::diagonalWorld() const +{ + return CoordinateTransformer::worldToDiagonal(world()); +} + +void TranslatedCoordinates::setDiagonal(DiagonalWorldCoordinates newDiagonalWorldCoordinates) +{ + this->worldCoordinates = CoordinateTransformer::diagonalToWorld(newDiagonalWorldCoordinates); +} + +TranslatedCoordinates::TranslatedCoordinates(DiagonalWorldCoordinates diagonalWorldCoordinates) +{ + setDiagonal(diagonalWorldCoordinates); +} diff --git a/src/coordinates/translated_coordinates.h b/src/coordinates/translated_coordinates.h index d182394..e0482e5 100644 --- a/src/coordinates/translated_coordinates.h +++ b/src/coordinates/translated_coordinates.h @@ -9,6 +9,7 @@ class TranslatedCoordinates { public: explicit TranslatedCoordinates(WorldCoordinates worldCoordinates); + explicit TranslatedCoordinates(DiagonalWorldCoordinates diagonalWorldCoordinates); explicit TranslatedCoordinates(GridCoordinates gridCoordinates); [[nodiscard]] WorldCoordinates world() const; @@ -17,12 +18,16 @@ public: [[nodiscard]] GridCoordinates grid() const; + [[nodiscard]] DiagonalWorldCoordinates diagonalWorld() const; + void setWorld(WorldCoordinates newWorldCoordinates); void setTranslated(const TranslatedCoordinates& newCoordinates); void setIsometric(IsometricCoordinates newIsometricCoordinates); + void setDiagonal(DiagonalWorldCoordinates newDiagonalWorldCoordinates); + void setGrid(GridCoordinates newGridCoordinates); void move(WorldCoordinates deltaWorldCoordinates); diff --git a/src/game/collectables/collectable.cpp b/src/game/collectables/collectable.cpp index 94cdbb6..db56a81 100644 --- a/src/game/collectables/collectable.cpp +++ b/src/game/collectables/collectable.cpp @@ -13,9 +13,9 @@ void Collectable::setRotation(float angle) } -int Collectable::getDepth() const +float Collectable::getDepth() const { - return static_cast(coordinates->isometric().depth); + return coordinates->isometric().depth; } void Collectable::setSprite(const std::string &spriteName) @@ -24,5 +24,8 @@ void Collectable::setSprite(const std::string &spriteName) float sizeWidth = 1.f * WORLD_TO_ISO_SCALE; auto size = sf::Vector2f{sizeWidth, sizeWidth}; auto sprite = std::make_shared(spriteName, size); - addChildScreenOffset(sprite, IsometricCoordinates(-sizeWidth / 2.f, -sizeWidth)); + addChildScreenOffset(sprite, IsometricCoordinates(-size / 2.f)); + + // Set half size offset of coordinates + coordinates->move(WorldCoordinates(0, 0, sizeWidth / 2.f)); } diff --git a/src/game/collectables/collectable.hpp b/src/game/collectables/collectable.hpp index dbb816d..98e6d10 100644 --- a/src/game/collectables/collectable.hpp +++ b/src/game/collectables/collectable.hpp @@ -13,7 +13,7 @@ public: void setRotation(float angle); - int getDepth() const; + float getDepth() const; int getId() const { diff --git a/src/game/collectables/collection/collectables_collection.cpp b/src/game/collectables/collection/collectables_collection.cpp index dabee5c..093d68a 100644 --- a/src/game/collectables/collection/collectables_collection.cpp +++ b/src/game/collectables/collection/collectables_collection.cpp @@ -1,4 +1,6 @@ #include "collectables_collection.hpp" + +#include #include "collectables_depth_collection.hpp" #include "../../../logging/easylogging++.h" @@ -51,10 +53,11 @@ void CollectablesCollection::update() // Then, move collectables to new depth collections for (auto &[depth, depthCollection]: depthCollections) { - for (auto &collectable: depthCollection->collectables) + auto collectables = depthCollection->collectables; + for (auto &collectable: collectables) { - auto newDepth = collectable->getDepth(); - if (newDepth != depth) + int newDepth = std::floor(collectable->getDepth()); + if (newDepth != depth && newDepth < depthCollections.size()) { depthCollection->remove(collectable); depthCollections[newDepth]->add(collectable); diff --git a/src/game/game_factory.cpp b/src/game/game_factory.cpp index 84177e0..30b5104 100644 --- a/src/game/game_factory.cpp +++ b/src/game/game_factory.cpp @@ -39,6 +39,6 @@ sf::ContextSettings GameFactory::getAdditionalSettings() { } void GameFactory::applyAdditionalWindowConfig(sf::RenderWindow *window) { - window->setFramerateLimit(FRAME_RATE); +// window->setFramerateLimit(FRAME_RATE); window->setKeyRepeatEnabled(KEY_REPEAT_ENABLED); } diff --git a/src/game/game_object.cpp b/src/game/game_object.cpp index c75ca70..07bda62 100644 --- a/src/game/game_object.cpp +++ b/src/game/game_object.cpp @@ -79,3 +79,8 @@ void GameObject::physicsUpdate() child->physicsUpdate(); } } + +void GameObject::addDetachedChild(const std::shared_ptr &child) +{ + children.push_back(child); +} diff --git a/src/game/game_object.h b/src/game/game_object.h index a87fede..456092e 100644 --- a/src/game/game_object.h +++ b/src/game/game_object.h @@ -26,6 +26,7 @@ public: void addChildScreenOffset(const std::shared_ptr &child, IsometricCoordinates offset = {0, 0}); void addChildWorldOffset(const std::shared_ptr &child, WorldCoordinates offset); void addChild(const std::shared_ptr &child); + void addDetachedChild(const std::shared_ptr &child); void removeChild(const std::shared_ptr &child); void clearChildren(); [[nodiscard]] std::vector> getChildren() const { return children; } diff --git a/src/game/level/level_loader.cpp b/src/game/level/level_loader.cpp index f117449..859ffcc 100644 --- a/src/game/level/level_loader.cpp +++ b/src/game/level/level_loader.cpp @@ -61,6 +61,13 @@ void LevelLoader::loadLevel(const LevelConfig &levelConfig) } + for (int i = 0; i <= 25; i++) + { + auto debugImage = SpriteFactory::createSingleSprite("edge"); + debugImage->coordinates->setWorld({0, 0, (float) i}); + levelRenderer->addDetachedChild(debugImage); + } + LOG(INFO) << "Finished loading level '" << levelConfig.name << "'."; } @@ -81,7 +88,7 @@ void LevelLoader::spawnCollectable(const CollectableInLevel &collectableInfo) { LOG(INFO) << "Spawning collectable '" << collectableInfo.name << "' ..."; auto collectable = CollectableFactory::createFromInLevelConfig(collectableInfo); - LOG(DEBUG) << "Has depth " << collectable->getDepth() << "."; + LOG(INFO) << "Has depth " << collectable->getDepth() << "."; CollectablesCollection::getInstance()->add(collectable); HolesSimulation::getInstance()->addCollectable(collectable); } diff --git a/src/game/physics/holes/collectable_simulation.cpp b/src/game/physics/holes/collectable_simulation.cpp index 191d605..46ed060 100644 --- a/src/game/physics/holes/collectable_simulation.cpp +++ b/src/game/physics/holes/collectable_simulation.cpp @@ -1,7 +1,8 @@ #include "collectable_simulation.hpp" -#include +#include "../../../logging/easylogging++.h" #include "../../../config.h" +#include "layouts/hole_layout.hpp" CollectableSimulation::CollectableSimulation(const std::shared_ptr &collectable) : collectable(collectable) @@ -11,24 +12,8 @@ CollectableSimulation::CollectableSimulation(const std::shared_ptr world->SetAllowSleeping(COLLECTABLES_SIM_SLEEPING); // Create body - b2BodyDef bodyDef; - bodyDef.type = b2_dynamicBody; - bodyDef.angularDamping = COLLECTABLES_SIM_ANGULAR_DAMPING; - bodyDef.linearDamping = COLLECTABLES_SIM_LINEAR_DAMPING; -// bodyDef.position.Set(collectable->getPosition().x, collectable->getPosition().y); - body = world->CreateBody(&bodyDef); - - // Create shape - b2CircleShape shape; -// shape.m_radius = collectable->getRadius(); - - // Create fixture - b2FixtureDef fixtureDef; - fixtureDef.shape = &shape; - fixtureDef.friction = COLLECTABLES_SIM_FRICTION; - fixtureDef.restitution = COLLECTABLES_SIM_RESTITUTION; - fixtureDef.density = COLLECTABLES_SIM_DENSITY; - body->CreateFixture(&fixtureDef); + auto coordinates = collectable->coordinates->diagonalWorld(); + body = addSquareBody(b2_dynamicBody, {coordinates.horizontal, coordinates.vertical}, sf::Vector2f(1, 1)); } void CollectableSimulation::physicsUpdate() @@ -36,6 +21,30 @@ void CollectableSimulation::physicsUpdate() updateGroundHole(); world->Step(FRAME_TIME.asSeconds(), COLLECTABLES_SIM_VELOCITY_ITERATIONS, COLLECTABLES_SIM_POSITION_ITERATIONS); + + updateCollectable(); +} + +b2Body *CollectableSimulation::addSquareBody(b2BodyType type, sf::Vector2f center, sf::Vector2f size) +{ + b2BodyDef bodyDef; + bodyDef.type = type; + bodyDef.angularDamping = COLLECTABLES_SIM_ANGULAR_DAMPING; + bodyDef.linearDamping = COLLECTABLES_SIM_LINEAR_DAMPING; + bodyDef.position.Set(center.x, center.y); + b2Body *body = world->CreateBody(&bodyDef); + + b2PolygonShape shape; + shape.SetAsBox(size.x / 2.f, size.y / 2.f); + + b2FixtureDef fixtureDef; + fixtureDef.shape = &shape; + fixtureDef.friction = COLLECTABLES_SIM_FRICTION; + fixtureDef.restitution = COLLECTABLES_SIM_RESTITUTION; + fixtureDef.density = COLLECTABLES_SIM_DENSITY; + + body->CreateFixture(&fixtureDef); + return body; } std::shared_ptr CollectableSimulation::getCollectable() const @@ -45,5 +54,12 @@ std::shared_ptr CollectableSimulation::getCollectable() const void CollectableSimulation::updateGroundHole() { - + auto holeLayout = HoleLayout::getInstance()->atDepth(collectable->getDepth()); +} + +void CollectableSimulation::updateCollectable() +{ + auto bodyPosition = body->GetPosition(); + collectable->coordinates->setDiagonal({bodyPosition.x, bodyPosition.y, collectable->getDepth()}); + collectable->setRotation(body->GetAngle()); } diff --git a/src/game/physics/holes/collectable_simulation.hpp b/src/game/physics/holes/collectable_simulation.hpp index 6bf25cf..f04122d 100644 --- a/src/game/physics/holes/collectable_simulation.hpp +++ b/src/game/physics/holes/collectable_simulation.hpp @@ -22,6 +22,10 @@ private: std::shared_ptr collectable; void updateGroundHole(); + + void updateCollectable(); + + b2Body *addSquareBody(b2BodyType type, sf::Vector2f center, sf::Vector2f size); }; diff --git a/src/game/physics/holes/layouts/depth_hole_description.hpp b/src/game/physics/holes/layouts/depth_hole_description.hpp index e804a40..a78958e 100644 --- a/src/game/physics/holes/layouts/depth_hole_description.hpp +++ b/src/game/physics/holes/layouts/depth_hole_description.hpp @@ -6,6 +6,10 @@ struct DepthHoleDescription int playerId; float x; float width; + + DepthHoleDescription(int playerId, float x, float width) + : playerId(playerId), x(x), width(width) + {} }; #endif //HOLESOME_DEPTH_HOLE_DESCRIPTION_HPP diff --git a/src/game/physics/holes/layouts/depth_hole_layout.hpp b/src/game/physics/holes/layouts/depth_hole_layout.hpp index b184c8b..f57c793 100644 --- a/src/game/physics/holes/layouts/depth_hole_layout.hpp +++ b/src/game/physics/holes/layouts/depth_hole_layout.hpp @@ -8,6 +8,10 @@ struct DepthHoleLayout { float depth; std::vector holes; + + DepthHoleLayout(float depth, std::vector holes) + : depth(depth), holes(std::move(holes)) + {} }; #endif //HOLESOME_DEPTH_HOLE_LAYOUT_HPP diff --git a/src/game/physics/holes/layouts/hole_description.hpp b/src/game/physics/holes/layouts/hole_description.hpp index f58c230..fdbaa0e 100644 --- a/src/game/physics/holes/layouts/hole_description.hpp +++ b/src/game/physics/holes/layouts/hole_description.hpp @@ -4,6 +4,8 @@ #include #include "../../../player/player.hpp" +#include "../../../../utilities/vector_utils.hpp" +#include "depth_hole_description.hpp" struct HoleDescription { @@ -19,6 +21,21 @@ struct HoleDescription auto world3d = player->coordinates->world(); worldPosition = sf::Vector2f(world3d.x, world3d.y); } + + [[nodiscard]] DepthHoleDescription atDepth(float depth) const + { + auto closestPointAtDepth = CoordinateTransformer::closestWorldPointAtDepth(depth, worldPosition); + auto distance = length(worldPosition - closestPointAtDepth); + if (distance > radius) + { + // No hole at this depth + return DepthHoleDescription(playerId, 0.f, 0.f); + } + + float chordLength = 2.f * std::sqrt(radius * radius - distance * distance); + + return DepthHoleDescription(playerId, closestPointAtDepth.x, chordLength); + } }; diff --git a/src/game/physics/holes/layouts/hole_layout.cpp b/src/game/physics/holes/layouts/hole_layout.cpp index 30d73fa..3091621 100644 --- a/src/game/physics/holes/layouts/hole_layout.cpp +++ b/src/game/physics/holes/layouts/hole_layout.cpp @@ -35,3 +35,13 @@ void HoleLayout::lateUpdate() HoleLayout::HoleLayout() : currentHoles(), previousHoles() {} + +DepthHoleLayout HoleLayout::atDepth(float depth) const +{ + std::vector depthHoles{}; + for (const auto &hole: currentHoles) + { + depthHoles.push_back(hole.atDepth(depth)); + } + return DepthHoleLayout(depth, depthHoles); +} diff --git a/src/game/physics/holes/layouts/hole_layout.hpp b/src/game/physics/holes/layouts/hole_layout.hpp index 793e79f..450b09c 100644 --- a/src/game/physics/holes/layouts/hole_layout.hpp +++ b/src/game/physics/holes/layouts/hole_layout.hpp @@ -5,6 +5,7 @@ #include #include "../../../game_object.h" #include "hole_description.hpp" +#include "depth_hole_layout.hpp" class HoleLayout : public GameObject { @@ -17,6 +18,8 @@ public: void clear(); + DepthHoleLayout atDepth(float depth) const; + private: static inline std::shared_ptr singletonInstance = nullptr; diff --git a/src/game/player/player_collection.cpp b/src/game/player/player_collection.cpp index e9758f4..7018075 100644 --- a/src/game/player/player_collection.cpp +++ b/src/game/player/player_collection.cpp @@ -28,7 +28,7 @@ std::shared_ptr PlayerCollection::getInstance() void PlayerCollection::addPlayer(const std::shared_ptr &player) { newPlayerBuffer.push_back(player); - addChild(player); + addDetachedChild(player); } void PlayerCollection::clear() @@ -102,7 +102,7 @@ void PlayerCollection::spawnPlayer(const std::shared_ptr &inputId nextSpawnPointIndex = static_cast((nextSpawnPointIndex + 1) % spawnPoints.size()); auto player = std::make_shared(inputIdentity, PLAYER_SKIN, spawn); - PlayerCollection::getInstance()->addPlayer(player); + addPlayer(player); } std::vector> PlayerCollection::getPlayers() const diff --git a/src/prototypes/coordinates_00.cpp b/src/prototypes/coordinates_00.cpp new file mode 100644 index 0000000..9b931ab --- /dev/null +++ b/src/prototypes/coordinates_00.cpp @@ -0,0 +1,121 @@ +#include +#include +#include "../coordinates/translated_coordinates.h" + +enum CoordinateSystem +{ + NONE, + WORLD, + DIAGONAL, + ISOMETRIC +}; + +CoordinateSystem inputCoordinateSystem() +{ + while (true) + { + try + { + std::cout << "Enter coordinate system (w/d/i) or x to close: "; + char coordinateSystemIndicator; + std::cin >> coordinateSystemIndicator; + + switch (coordinateSystemIndicator) + { + case 'x': + std::cout << "Closing ..." << std::endl; + return NONE; + case 'w': + std::cout << "World coordinates" << std::endl; + return WORLD; + case 'd': + std::cout << "Diagonal world coordinates" << std::endl; + return DIAGONAL; + case 'i': + std::cout << "Isometric coordinates" << std::endl; + return ISOMETRIC; + default: + std::cout << "Invalid coordinate system. Try again ..." << std::endl; + continue; + } + } catch (...) + { + + } + } +} + +std::vector input3values(std::string prompt = "Enter 3 values: ") +{ + while (true) + { + try + { + std::vector values(3); + std::cout << prompt; + std::cin >> values[0] >> values[1] >> values[2]; + return values; + } catch (...) + { + + } + } +} + +TranslatedCoordinates worldToTranslated(std::vector values) +{ + return TranslatedCoordinates(WorldCoordinates{values[0], values[1], values[2]}); +} + +TranslatedCoordinates diagonalToTranslated(std::vector values) +{ + return TranslatedCoordinates(DiagonalWorldCoordinates{values[0], values[1], values[2]}); +} + +TranslatedCoordinates isometricToTranslated(std::vector values) +{ + auto world = CoordinateTransformer::isometricToWorld(IsometricCoordinates{values[0], values[1], values[2]}); + return TranslatedCoordinates(world); +} + +void printCoordinates(TranslatedCoordinates coordinates) +{ + std::cout << "World coordinates (x, y, z): " << coordinates.world().x << ", " << coordinates.world().y << ", " + << coordinates.world().z << std::endl; + std::cout << "Diagonal world coordinates (horizontal, vertical, depth): " << coordinates.diagonalWorld().horizontal << ", " + << coordinates.diagonalWorld().vertical << ", " << coordinates.diagonalWorld().depth + << std::endl; + std::cout << "Isometric coordinates (x, y, depth): " << coordinates.isometric().x << ", " + << coordinates.isometric().y << ", " << coordinates.isometric().depth << std::endl; +} + +int main() +{ + while (true) + { + CoordinateSystem coordinateSystem = inputCoordinateSystem(); + TranslatedCoordinates translatedCoordinates = TranslatedCoordinates(WorldCoordinates{0, 0, 0}); + switch (coordinateSystem) + { + case NONE: + return 0; + case WORLD: + translatedCoordinates = worldToTranslated(input3values("Enter world coordinates (x, y, z): ")); + break; + case DIAGONAL: + translatedCoordinates = diagonalToTranslated( + input3values("Enter diagonal world coordinates (horizontal, vertical, depth): ")); + break; + case ISOMETRIC: + translatedCoordinates = isometricToTranslated( + input3values("Enter isometric coordinates (x, y, depth): ")); + break; + } + printCoordinates(translatedCoordinates); + + // Wait for enter, then clear screen + std::cin.ignore(); + std::cin.get(); + std::cout << "\033[2J\033[1;1H"; + } +} \ No newline at end of file diff --git a/src/utilities/vector_utils.hpp b/src/utilities/vector_utils.hpp index f1c8653..2b1df8d 100644 --- a/src/utilities/vector_utils.hpp +++ b/src/utilities/vector_utils.hpp @@ -7,7 +7,7 @@ template float length(sf::Vector2 v) { - return std::sqrt(v.x * v.x + v.y * v.y); + return std::sqrt(pow(v.x, 2) + pow(v.y, 2)); } template @@ -29,4 +29,10 @@ sf::Vector2 abs(sf::Vector2 v) return sf::Vector2(std::abs(v.x), std::abs(v.y)); } +template +T sum(sf::Vector2 v) +{ + return v.x + v.y; +} + #endif //HOLESOME_VECTOR_UTILS_HPP