#include "collectable_sim_ground.hpp" #include #include "../../../../config.h" void CollectableSimGround::closeAllHoles() { 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}); segments.push_back(groundSegment); } CollectableSimGround::CollectableSimGround(std::shared_ptr world, float groundWidth) : world(std::move(world)) { setGroundWidth(groundWidth); closeAllHoles(); } void CollectableSimGround::setGroundWidth(float width) { if (width <= 0) { throw std::runtime_error("Ground width must be greater than 0"); } if (width == groundWidth) { return; } groundWidth = width; updateOuterSegmentsToWidth(); } void CollectableSimGround::updateOuterSegmentsToWidth() { auto outerSegments = getOuterSegments(); auto borderPoints = groundWidth / 2.f; // Left segment if (outerSegments.left != nullptr) { auto leftSegment = outerSegments.left->body; auto leftCenter = leftSegment->getCenter(); auto leftSize = leftSegment->getSize(); auto deltaToBorder = borderPoints - abs(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); } // Right segment if (outerSegments.right != nullptr) { auto rightSegment = outerSegments.right->body; auto rightCenter = rightSegment->getCenter(); auto rightSize = rightSegment->getSize(); auto deltaToBorder = borderPoints - abs(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); } } CollectableSimGround::SideSegments CollectableSimGround::getOuterSegments(int holeId) { SideSegments sideSegments; for (const auto &segment: segments) { // If valid holeId, match left hole id // If invalid holeId, get outer segment if ((segment->leftHoleId == holeId && holeId >= 0) || (segment->rightHoleId < 0 && holeId < 0)) { sideSegments.right = segment; } if ((segment->rightHoleId == holeId && holeId >= 0) || (segment->leftHoleId < 0 && holeId < 0)) { sideSegments.left = segment; } } return sideSegments; }