From 13af968a04c0423f8f8918c2182c82286c44e5b3 Mon Sep 17 00:00:00 2001 From: Vlad Date: Wed, 14 Jan 2026 16:06:32 +0600 Subject: [PATCH] added collision for stones --- src/Game.cpp | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/src/Game.cpp b/src/Game.cpp index 56bd7d2..bc92e89 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -713,6 +713,10 @@ namespace ZL this->explosionEmitter.setEmissionPoints(std::vector()); Environment::shipPosition = Vector3f{ 0, 0, 45000.f }; Environment::shipVelocity = 0.0f; + Environment::shipMatrix = Eigen::Matrix3f::Identity(); + Environment::inverseShipMatrix = Eigen::Matrix3f::Identity(); + Environment::zoom = 18.f; + Environment::tapDownHold = false; uiManager.popMenu(); std::cerr << "Game restarted\n"; }); @@ -728,6 +732,103 @@ namespace ZL } } } + else { + bool stoneCollided = false; + int collidedTriIdx = -1; + Vector3f collidedStonePos = Vector3f{ 0.0f, 0.0f, 0.0f }; + + for (int triIdx : planetObject.triangleIndicesToDraw) { + if (triIdx < 0 || triIdx >= static_cast(planetObject.planetStones.allInstances.size())) + continue; + + if (planetObject.planetStones.statuses.size() <= static_cast(triIdx)) + continue; + + if (planetObject.planetStones.statuses[triIdx] != ChunkStatus::Live) + continue; + + const auto& instances = planetObject.planetStones.allInstances[triIdx]; + for (const auto& inst : instances) { + + Vector3f stoneWorld = inst.position; + Vector3f diff = Environment::shipPosition - stoneWorld; + + float maxScale = (std::max)({ inst.scale(0), inst.scale(1), inst.scale(2) }); + float stoneRadius = StoneParams::BASE_SCALE * maxScale * 0.9f; + float thresh = shipCollisionRadius + stoneRadius; + + if (diff.squaredNorm() <= thresh * thresh) { + stoneCollided = true; + collidedTriIdx = triIdx; + collidedStonePos = stoneWorld; + break; + } + } + + if (stoneCollided) break; + } + + if (stoneCollided) { + Vector3f localForward = { 0,0,-1 }; + Vector3f worldForward = (Environment::shipMatrix * localForward).normalized(); + const float backDistance = 400.0f; + Environment::shipPosition = Environment::shipPosition - worldForward * backDistance; + + shipAlive = false; + gameOver = true; + Environment::shipVelocity = 0.0f; + showExplosion = true; + + explosionEmitter.setUseWorldSpace(true); + explosionEmitter.setEmissionPoints(std::vector{ collidedStonePos }); + explosionEmitter.emit(); + + std::cerr << "GAME OVER: collision with stone on triangle " << collidedTriIdx << std::endl; + + if (collidedTriIdx >= 0 && collidedTriIdx < static_cast(planetObject.stonesToRender.size())) { + planetObject.stonesToRender[collidedTriIdx].data.PositionData.clear(); + planetObject.stonesToRender[collidedTriIdx].vao.reset(); + planetObject.stonesToRender[collidedTriIdx].positionVBO.reset(); + planetObject.stonesToRender[collidedTriIdx].normalVBO.reset(); + planetObject.stonesToRender[collidedTriIdx].tangentVBO.reset(); + planetObject.stonesToRender[collidedTriIdx].binormalVBO.reset(); + planetObject.stonesToRender[collidedTriIdx].colorVBO.reset(); + planetObject.stonesToRender[collidedTriIdx].texCoordVBO.reset(); + } + if (collidedTriIdx >= 0 && collidedTriIdx < static_cast(planetObject.planetStones.statuses.size())) { + planetObject.planetStones.statuses[collidedTriIdx] = ChunkStatus::Empty; + } + + if (!uiGameOverShown) { + if (uiManager.pushMenuFromFile("resources/config/game_over.json", this->renderer, CONST_ZIP_FILE)) { + uiManager.setButtonCallback("restartButton", [this](const std::string& name) { + this->shipAlive = true; + this->gameOver = false; + this->uiGameOverShown = false; + this->showExplosion = false; + this->explosionEmitter.setEmissionPoints(std::vector()); + Environment::shipPosition = Vector3f{ 0, 0, 45000.f }; + Environment::shipVelocity = 0.0f; + Environment::shipMatrix = Eigen::Matrix3f::Identity(); + Environment::inverseShipMatrix = Eigen::Matrix3f::Identity(); + Environment::zoom = 18.f; + Environment::tapDownHold = false; + uiManager.popMenu(); + std::cerr << "Game restarted\n"; + }); + + uiManager.setButtonCallback("gameOverExitButton", [this](const std::string& name) { + Environment::exitGameLoop = true; + }); + + uiGameOverShown = true; + } + else { + std::cerr << "Failed to load game_over.json\n"; + } + } + } + } } for (int i = 0; i < boxCoordsArr.size(); ++i) {