diff --git a/resources/config/explosion_config.json b/resources/config/explosion_config.json index 2e461e8..fc0a2bc 100644 --- a/resources/config/explosion_config.json +++ b/resources/config/explosion_config.json @@ -9,7 +9,7 @@ "lifeTimeRange": [200.0, 800.0], "emissionRate": 50.0, "maxParticles": 5, - "particleSize": 0.5, + "particleSize": 2, "biasX": 0.1, "shaderProgramName": "default" } \ No newline at end of file diff --git a/src/Game.cpp b/src/Game.cpp index 8d2cca6..46af558 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -1,6 +1,7 @@ #include "Game.h" #include "AnimatedModel.h" #include "BoneAnimatedModel.h" +#include "planet/PlanetData.h" #include "utils/Utils.h" #include "render/OpenGlExtensions.h" #include @@ -314,7 +315,7 @@ namespace ZL //spaceshipTexture = std::make_unique(CreateTextureDataFromPng("resources/DefaultMaterial_BaseColor_shine.png", CONST_ZIP_FILE)); //spaceshipBase = LoadFromTextFile02("resources/spaceship006.txt", CONST_ZIP_FILE); //spaceshipBase.RotateByMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(M_PI / 2.0, Eigen::Vector3f::UnitY())).toRotationMatrix());// QuatFromRotateAroundY(M_PI / 2.0).toRotationMatrix()); - + //spaceshipTexture = std::make_unique(CreateTextureDataFromPng("./resources/cap_D.png", CONST_ZIP_FILE)); //spaceshipBase = LoadFromTextFile02("./resources/spaceship006x.txt", CONST_ZIP_FILE); //spaceshipBase.RotateByMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(-M_PI / 2.0, Eigen::Vector3f::UnitY())).toRotationMatrix());// QuatFromRotateAroundY(M_PI / 2.0).toRotationMatrix()); @@ -695,22 +696,30 @@ namespace ZL projectileEmitter.update(static_cast(delta)); explosionEmitter.update(static_cast(delta)); + if (showExplosion) { + uint64_t now = SDL_GetTicks64(); + if (lastExplosionTime != 0 && now - lastExplosionTime >= explosionDurationMs) { + showExplosion = false; + explosionEmitter.setEmissionPoints(std::vector()); + explosionEmitter.setUseWorldSpace(false); + } + } if (shipAlive) { float distToSurface = planetObject.distanceToPlanetSurface(Environment::shipPosition); if (distToSurface <= 0.0f) { - Vector3f localForward = { 0,0,-1 }; - Vector3f worldForward = (Environment::shipMatrix * localForward).normalized(); - const float backDistance = 400.0f; - Environment::shipPosition = Environment::shipPosition - worldForward * backDistance; + Vector3f dir = (Environment::shipPosition - PlanetData::PLANET_CENTER_OFFSET).normalized(); + Vector3f collisionPoint = PlanetData::PLANET_CENTER_OFFSET + dir * PlanetData::PLANET_RADIUS; + Environment::shipPosition = PlanetData::PLANET_CENTER_OFFSET + dir * (PlanetData::PLANET_RADIUS + shipCollisionRadius + 0.1f); shipAlive = false; gameOver = true; Environment::shipVelocity = 0.0f; showExplosion = true; - explosionEmitter.setUseWorldSpace(false); - explosionEmitter.setEmissionPoints(std::vector{ Vector3f{ 0.0f,0.0f,0.0f } }); + explosionEmitter.setUseWorldSpace(true); + explosionEmitter.setEmissionPoints(std::vector{ collisionPoint }); explosionEmitter.emit(); + lastExplosionTime = SDL_GetTicks64(); std::cerr << "GAME OVER: collision with planet (moved back and exploded)\n"; @@ -747,6 +756,7 @@ namespace ZL bool stoneCollided = false; int collidedTriIdx = -1; Vector3f collidedStonePos = Vector3f{ 0.0f, 0.0f, 0.0f }; + float collidedStoneRadius = 0.0f; for (int triIdx : planetObject.triangleIndicesToDraw) { if (triIdx < 0 || triIdx >= static_cast(planetObject.planetStones.allInstances.size())) @@ -772,6 +782,7 @@ namespace ZL stoneCollided = true; collidedTriIdx = triIdx; collidedStonePos = stoneWorld; + collidedStoneRadius = stoneRadius; break; } } @@ -780,10 +791,13 @@ namespace ZL } if (stoneCollided) { - Vector3f localForward = { 0,0,-1 }; - Vector3f worldForward = (Environment::shipMatrix * localForward).normalized(); - const float backDistance = 50.0f; - Environment::shipPosition = Environment::shipPosition - worldForward * backDistance; + Vector3f away = (Environment::shipPosition - collidedStonePos); + if (away.squaredNorm() <= 1e-6f) { + away = Vector3f{ 0.0f, 1.0f, 0.0f }; + } + away.normalize(); + + Environment::shipPosition = collidedStonePos + away * (collidedStoneRadius + shipCollisionRadius + 0.1f); shipAlive = false; gameOver = true; @@ -793,6 +807,7 @@ namespace ZL explosionEmitter.setUseWorldSpace(true); explosionEmitter.setEmissionPoints(std::vector{ collidedStonePos }); explosionEmitter.emit(); + lastExplosionTime = SDL_GetTicks64(); std::cerr << "GAME OVER: collision with stone on triangle " << collidedTriIdx << std::endl; @@ -861,10 +876,42 @@ namespace ZL explosionEmitter.setUseWorldSpace(true); explosionEmitter.setEmissionPoints(std::vector{ boxWorld }); explosionEmitter.emit(); + lastExplosionTime = SDL_GetTicks64(); std::cerr << "Box destroyed at index " << i << std::endl; } } + + const float projectileHitRadius = 1.5f; + for (auto& p : projectiles) { + if (!p || !p->isActive()) continue; + Vector3f ppos = p->getPosition(); + Vector3f projInBoxSpace = Environment::inverseShipMatrix * (ppos - Environment::shipPosition); + for (int i = 0; i < boxCoordsArr.size(); ++i) { + if (!boxAlive[i]) continue; + Vector3f boxWorld = boxCoordsArr[i].pos + Vector3f{ 0.0f, 6.0f, 45000.0f }; + Vector3f dd = ppos - boxWorld; + float thresh = boxCollisionRadius + projectileHitRadius; + if (dd.squaredNorm() <= thresh * thresh) { + boxAlive[i] = false; + boxRenderArr[i].data.PositionData.clear(); + boxRenderArr[i].vao.reset(); + boxRenderArr[i].positionVBO.reset(); + boxRenderArr[i].texCoordVBO.reset(); + + showExplosion = true; + explosionEmitter.setUseWorldSpace(true); + explosionEmitter.setEmissionPoints(std::vector{ boxWorld }); + explosionEmitter.emit(); + lastExplosionTime = SDL_GetTicks64(); + + p->deactivate(); + std::cerr << "Box destroyed by projectile at index " << i << std::endl; + break; + } + } + } + uiManager.update(static_cast(delta)); //#endif lastTickCount = newTickCount; diff --git a/src/Game.h b/src/Game.h index 40cc6c8..9a9d45d 100644 --- a/src/Game.h +++ b/src/Game.h @@ -87,14 +87,16 @@ namespace ZL { int maxProjectiles = 32; std::vector shipLocalEmissionPoints; - + bool shipAlive = true; bool gameOver = false; std::vector boxAlive; - float shipCollisionRadius = 3.5f; + float shipCollisionRadius = 15.0f; float boxCollisionRadius = 2.0f; bool uiGameOverShown = false; bool showExplosion = false; + uint64_t lastExplosionTime = 0; + const uint64_t explosionDurationMs = 500; }; diff --git a/src/Projectile.h b/src/Projectile.h index 1a5a62f..872177f 100644 --- a/src/Projectile.h +++ b/src/Projectile.h @@ -18,7 +18,7 @@ namespace ZL { bool isActive() const { return active; } Vector3f getPosition() const { return pos; } - + void deactivate() { active = false; } private: Vector3f pos; Vector3f vel;