diff --git a/src/config.h b/src/config.h index 8200033..0ec2fdd 100644 --- a/src/config.h +++ b/src/config.h @@ -50,7 +50,7 @@ #define COLLECTABLES_SIM_POSITION_ITERATIONS 3 #define COLLECTABLES_SIM_LINEAR_DAMPING 0.5f #define COLLECTABLES_SIM_ANGULAR_DAMPING 0.5f -#define COLLECTABLES_SIM_DENSITY 1.f +#define COLLECTABLES_SIM_DENSITY 3.f #define COLLECTABLES_SIM_FRICTION 0.0f #define COLLECTABLES_SIM_RESTITUTION 0.5f #define COLLECTABLES_SIM_SLEEPING true diff --git a/src/game/physics/body_adapter.cpp b/src/game/physics/body_adapter.cpp index 30bd17c..d3dee73 100644 --- a/src/game/physics/body_adapter.cpp +++ b/src/game/physics/body_adapter.cpp @@ -26,8 +26,8 @@ void BodyAdapter::createSquare(b2BodyType type, sf::Vector2f center, sf::Vector2 b2BodyDef bodyDef; bodyDef.type = type; - bodyDef.angularDamping = COLLECTABLES_SIM_ANGULAR_DAMPING; - bodyDef.linearDamping = COLLECTABLES_SIM_LINEAR_DAMPING; +// bodyDef.angularDamping = COLLECTABLES_SIM_ANGULAR_DAMPING; +// bodyDef.linearDamping = COLLECTABLES_SIM_LINEAR_DAMPING; bodyDef.position.Set(center.x, center.y); bodyObject = world->CreateBody(&bodyDef); @@ -42,8 +42,7 @@ b2Body *BodyAdapter::body() const sf::Vector2f BodyAdapter::getCenter() const { auto position = bodyObject->GetPosition(); - auto velocity = bodyObject->GetLinearVelocity(); - return sf::Vector2f(position.x, position.y) + sf::Vector2f(velocity.x, velocity.y); + return {position.x, position.y}; } sf::Vector2f BodyAdapter::getSize() const @@ -53,10 +52,7 @@ sf::Vector2f BodyAdapter::getSize() const void BodyAdapter::setCenter(sf::Vector2f center) { - // Set via velocity - auto velocity = bodyObject->GetLinearVelocity(); - velocity += b2Vec2(center.x, center.y) - bodyObject->GetPosition(); - bodyObject->SetLinearVelocity(velocity); + bodyObject->SetTransform({center.x, center.y}, bodyObject->GetAngle()); } void BodyAdapter::setBoxSize(sf::Vector2f size) @@ -74,8 +70,8 @@ void BodyAdapter::setBoxSize(sf::Vector2f size) b2FixtureDef fixtureDef; fixtureDef.shape = &shape; - fixtureDef.friction = COLLECTABLES_SIM_FRICTION; - fixtureDef.restitution = COLLECTABLES_SIM_RESTITUTION; +// fixtureDef.friction = COLLECTABLES_SIM_FRICTION; +// fixtureDef.restitution = COLLECTABLES_SIM_RESTITUTION; fixtureDef.density = COLLECTABLES_SIM_DENSITY; bodyObject->CreateFixture(&fixtureDef); diff --git a/src/game/physics/holes/collectable_simulation.cpp b/src/game/physics/holes/collectable_simulation.cpp index dc91abd..cc65d49 100644 --- a/src/game/physics/holes/collectable_simulation.cpp +++ b/src/game/physics/holes/collectable_simulation.cpp @@ -13,12 +13,15 @@ CollectableSimulation::CollectableSimulation(const std::shared_ptr // Create ground simGround = std::make_shared(world); -// Todo: Set proper ground width +// Todo: Set proper ground width // Create body collectableBody = std::make_shared(world); auto coordinates = collectable->coordinates->diagonalWorld(); - collectableBody->createSquare(b2_dynamicBody, {coordinates.horizontal, coordinates.vertical}, sf::Vector2f(1, 1)); + +// todo: scale collectable and HOLE WIDTH SIZE based on factor + auto size = sf::Vector2f(1, 1); + collectableBody->createSquare(b2_dynamicBody, {coordinates.horizontal, coordinates.vertical}, size); } void CollectableSimulation::physicsUpdate() @@ -38,18 +41,7 @@ std::shared_ptr CollectableSimulation::getCollectable() const void CollectableSimulation::updateGroundHole() { auto holeLayout = HoleLayout::getInstance()->atDepth(collectable->getDepth()); - - if (holeLayout.holes.empty()) - { - simGround->closeAllHoles(); - return; - } - - // TODO: Remove assumption - // Assume only one hole - auto hole = holeLayout.holes[0]; - -// todo: Update ground hole + simGround->createLayout(holeLayout); } void CollectableSimulation::updateCollectable() @@ -58,6 +50,6 @@ void CollectableSimulation::updateCollectable() collectable->coordinates->setDiagonal({bodyPosition.x, bodyPosition.y, collectable->getDepth()}); // Convert radians to degrees - float angle = collectableBody->body()->GetAngle() * 180 / M_PI; + float angle = -collectableBody->body()->GetAngle() * 180 / M_PI; collectable->setRotation(angle); } diff --git a/src/game/physics/holes/ground/collectable_sim_ground.cpp b/src/game/physics/holes/ground/collectable_sim_ground.cpp index 09f72dc..b6d1a29 100644 --- a/src/game/physics/holes/ground/collectable_sim_ground.cpp +++ b/src/game/physics/holes/ground/collectable_sim_ground.cpp @@ -2,22 +2,47 @@ #include #include "../../../../config.h" +#include "../layouts/depth_hole_layout.hpp" void CollectableSimGround::closeAllHoles() { + // Create one segment for the ground + createSegment(-groundWidth / 2.f, groundWidth / 2.f); +} + +void CollectableSimGround::createLayout(DepthHoleLayout &layout) +{ + // TODO: Check if layout changed at all before clearing segments segments.clear(); - // Create one segment for the ground - auto groundSegment = std::make_shared(world); - groundSegment->body->createSquare(b2_kinematicBody, - {0, -COLLECTABLES_SIM_GROUND_THICKNESS / 2.f}, - {groundWidth, COLLECTABLES_SIM_GROUND_THICKNESS}); + if (layout.holes.empty()) + { + closeAllHoles(); + return; + } - segments.push_back(groundSegment); + // Sort holes from left to right + std::sort(layout.holes.begin(), layout.holes.end(), + [](DepthHoleDescription a, DepthHoleDescription b) + { + return a.x < b.x; + }); + + // Create segments for holes + float leftCorner = -groundWidth / 2.f; + for (auto &hole: layout.holes) + { + auto rightCorner = hole.x - hole.width / 2.f; + createSegment(leftCorner, rightCorner); + + leftCorner = hole.x + hole.width / 2.f; + } + // Create segment for the right side + createSegment(leftCorner, groundWidth / 2.f); } CollectableSimGround::CollectableSimGround(std::shared_ptr world, float groundWidth) - : world(std::move(world)) + : world(std::move(world)), groundWidth(0) { setGroundWidth(groundWidth); closeAllHoles(); @@ -50,14 +75,9 @@ void CollectableSimGround::updateOuterSegmentsToWidth() auto leftSegment = outerSegments.left->body; auto leftCenter = leftSegment->getCenter(); auto leftSize = leftSegment->getSize(); - auto deltaToBorder = borderPoints - abs(leftCenter.x - leftSize.x / 2.f); + auto rightPoint = leftCenter.x + leftSize.x / 2.f; - // Increase width if positive, decrease if negative - leftSize.x += deltaToBorder; - leftCenter.x -= deltaToBorder / 2.f; - - leftSegment->setBoxSize(leftSize); - leftSegment->setCenter(leftCenter); + createSegment(-borderPoints, rightPoint, outerSegments.left); } // Right segment @@ -66,17 +86,32 @@ void CollectableSimGround::updateOuterSegmentsToWidth() auto rightSegment = outerSegments.right->body; auto rightCenter = rightSegment->getCenter(); auto rightSize = rightSegment->getSize(); - auto deltaToBorder = borderPoints - abs(rightCenter.x + rightSize.x / 2.f); + auto leftPoint = rightCenter.x - rightSize.x / 2.f; - // Increase width if positive, decrease if negative - rightSize.x += deltaToBorder; - rightCenter.x += deltaToBorder / 2.f; - - rightSegment->setBoxSize(rightSize); - rightSegment->setCenter(rightCenter); + createSegment(leftPoint, borderPoints, outerSegments.right); } } +void CollectableSimGround::createSegment(float leftCorner, float rightCorner, + std::shared_ptr segment) +{ + if (leftCorner > rightCorner) + { + throw std::runtime_error("Left corner must be less than right corner"); + } + + if (segment == nullptr) + { + segment = std::make_shared(world); + segments.push_back(segment); + } + + auto center = sf::Vector2f((leftCorner + rightCorner) / 2.f, -COLLECTABLES_SIM_GROUND_THICKNESS / 2.f); + auto size = sf::Vector2f(rightCorner - leftCorner, COLLECTABLES_SIM_GROUND_THICKNESS); + + segment->body->createSquare(b2_kinematicBody, center, size); +} + CollectableSimGround::SideSegments CollectableSimGround::getOuterSegments(int holeId) { SideSegments sideSegments; diff --git a/src/game/physics/holes/ground/collectable_sim_ground.hpp b/src/game/physics/holes/ground/collectable_sim_ground.hpp index 3306082..5d6757b 100644 --- a/src/game/physics/holes/ground/collectable_sim_ground.hpp +++ b/src/game/physics/holes/ground/collectable_sim_ground.hpp @@ -5,16 +5,18 @@ #include #include #include "collectable_sim_ground_segment.hpp" +#include "../layouts/depth_hole_layout.hpp" class CollectableSimGround { public: - CollectableSimGround(std::shared_ptr world, float groundWidth = 1000); + explicit CollectableSimGround(std::shared_ptr world, float groundWidth = 1000); - void closeAllHoles(); void setGroundWidth(float width); + void createLayout(DepthHoleLayout &layout); + private: std::vector> segments; std::shared_ptr world; @@ -28,6 +30,10 @@ private: SideSegments getOuterSegments(int holeId = -1); void updateOuterSegmentsToWidth(); + + void createSegment(float leftCorner, float rightCorner, std::shared_ptr segment = nullptr); + + void closeAllHoles(); }; diff --git a/src/game/physics/holes/layouts/hole_description.hpp b/src/game/physics/holes/layouts/hole_description.hpp index 62c550d..1a6e01e 100644 --- a/src/game/physics/holes/layouts/hole_description.hpp +++ b/src/game/physics/holes/layouts/hole_description.hpp @@ -33,8 +33,11 @@ struct HoleDescription } float chordLength = 2.f * std::sqrt(radius * radius - distance * distance); + float chordLengthInDiagonal = chordLength * WORLD_TO_ISO_SCALE; - return {playerId, closestPointAtDepth.x, chordLength}; + auto diagonalWorldCoords = CoordinateTransformer::worldToDiagonal(WorldCoordinates{worldPosition}); + + return {playerId, diagonalWorldCoords.horizontal, chordLengthInDiagonal}; } }; diff --git a/src/game/physics/holes/layouts/hole_layout.cpp b/src/game/physics/holes/layouts/hole_layout.cpp index cca3625..723d029 100644 --- a/src/game/physics/holes/layouts/hole_layout.cpp +++ b/src/game/physics/holes/layouts/hole_layout.cpp @@ -12,14 +12,11 @@ std::shared_ptr HoleLayout::getInstance() void HoleLayout::clear() { - previousHoles.clear(); currentHoles.clear(); } void HoleLayout::lateUpdate() { - // Move history forward - previousHoles = currentHoles; currentHoles.clear(); // Collect hole descriptions of active players @@ -33,7 +30,7 @@ void HoleLayout::lateUpdate() } HoleLayout::HoleLayout() - : currentHoles(), previousHoles() + : currentHoles() {} DepthHoleLayout HoleLayout::atDepth(float depth) const @@ -41,7 +38,13 @@ DepthHoleLayout HoleLayout::atDepth(float depth) const std::vector depthHoles{}; for (const auto &hole: currentHoles) { - depthHoles.push_back(hole.atDepth(depth)); + auto holeAtDepth = hole.atDepth(depth); + if (holeAtDepth.width <= 0) + { + continue; + } + + depthHoles.push_back(holeAtDepth); } return {depth, depthHoles}; } diff --git a/src/game/physics/holes/layouts/hole_layout.hpp b/src/game/physics/holes/layouts/hole_layout.hpp index 0d55f97..75d13f6 100644 --- a/src/game/physics/holes/layouts/hole_layout.hpp +++ b/src/game/physics/holes/layouts/hole_layout.hpp @@ -24,7 +24,6 @@ private: static inline std::shared_ptr singletonInstance = nullptr; std::vector currentHoles; - std::vector previousHoles; }; diff --git a/src/levels.hpp b/src/levels.hpp index 344c8d2..2465dd2 100644 --- a/src/levels.hpp +++ b/src/levels.hpp @@ -12,7 +12,17 @@ std::map const all_levels = { {18, 18}, {0, 18}, {18, 0}}, { - CollectableInLevel("box", {3, 5}) + CollectableInLevel("box", {3, 5}), + CollectableInLevel("box", {4, 5}), + CollectableInLevel("box", {10, 6}), + CollectableInLevel("box", {2, 8}), + CollectableInLevel("box", {1, 2}), + CollectableInLevel("box", {4, 3}), + CollectableInLevel("box", {8, 3}), + CollectableInLevel("box", {6, 7}), + CollectableInLevel("box", {5, 5}), + CollectableInLevel("box", {9, 5}), + CollectableInLevel("box", {7, 4}) }, { // Blues