added projectile collision and some fixed

This commit is contained in:
Vlad 2026-01-15 15:49:32 +06:00
parent 90ad3392cb
commit 52a52ef960
4 changed files with 64 additions and 15 deletions

View File

@ -9,7 +9,7 @@
"lifeTimeRange": [200.0, 800.0], "lifeTimeRange": [200.0, 800.0],
"emissionRate": 50.0, "emissionRate": 50.0,
"maxParticles": 5, "maxParticles": 5,
"particleSize": 0.5, "particleSize": 2,
"biasX": 0.1, "biasX": 0.1,
"shaderProgramName": "default" "shaderProgramName": "default"
} }

View File

@ -1,6 +1,7 @@
#include "Game.h" #include "Game.h"
#include "AnimatedModel.h" #include "AnimatedModel.h"
#include "BoneAnimatedModel.h" #include "BoneAnimatedModel.h"
#include "planet/PlanetData.h"
#include "utils/Utils.h" #include "utils/Utils.h"
#include "render/OpenGlExtensions.h" #include "render/OpenGlExtensions.h"
#include <iostream> #include <iostream>
@ -314,7 +315,7 @@ namespace ZL
//spaceshipTexture = std::make_unique<Texture>(CreateTextureDataFromPng("resources/DefaultMaterial_BaseColor_shine.png", CONST_ZIP_FILE)); //spaceshipTexture = std::make_unique<Texture>(CreateTextureDataFromPng("resources/DefaultMaterial_BaseColor_shine.png", CONST_ZIP_FILE));
//spaceshipBase = LoadFromTextFile02("resources/spaceship006.txt", 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()); //spaceshipBase.RotateByMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(M_PI / 2.0, Eigen::Vector3f::UnitY())).toRotationMatrix());// QuatFromRotateAroundY(M_PI / 2.0).toRotationMatrix());
//spaceshipTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/cap_D.png", CONST_ZIP_FILE)); //spaceshipTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/cap_D.png", CONST_ZIP_FILE));
//spaceshipBase = LoadFromTextFile02("./resources/spaceship006x.txt", 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()); //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<float>(delta)); projectileEmitter.update(static_cast<float>(delta));
explosionEmitter.update(static_cast<float>(delta)); explosionEmitter.update(static_cast<float>(delta));
if (showExplosion) {
uint64_t now = SDL_GetTicks64();
if (lastExplosionTime != 0 && now - lastExplosionTime >= explosionDurationMs) {
showExplosion = false;
explosionEmitter.setEmissionPoints(std::vector<Vector3f>());
explosionEmitter.setUseWorldSpace(false);
}
}
if (shipAlive) { if (shipAlive) {
float distToSurface = planetObject.distanceToPlanetSurface(Environment::shipPosition); float distToSurface = planetObject.distanceToPlanetSurface(Environment::shipPosition);
if (distToSurface <= 0.0f) { if (distToSurface <= 0.0f) {
Vector3f localForward = { 0,0,-1 }; Vector3f dir = (Environment::shipPosition - PlanetData::PLANET_CENTER_OFFSET).normalized();
Vector3f worldForward = (Environment::shipMatrix * localForward).normalized(); Vector3f collisionPoint = PlanetData::PLANET_CENTER_OFFSET + dir * PlanetData::PLANET_RADIUS;
const float backDistance = 400.0f; Environment::shipPosition = PlanetData::PLANET_CENTER_OFFSET + dir * (PlanetData::PLANET_RADIUS + shipCollisionRadius + 0.1f);
Environment::shipPosition = Environment::shipPosition - worldForward * backDistance;
shipAlive = false; shipAlive = false;
gameOver = true; gameOver = true;
Environment::shipVelocity = 0.0f; Environment::shipVelocity = 0.0f;
showExplosion = true; showExplosion = true;
explosionEmitter.setUseWorldSpace(false); explosionEmitter.setUseWorldSpace(true);
explosionEmitter.setEmissionPoints(std::vector<Vector3f>{ Vector3f{ 0.0f,0.0f,0.0f } }); explosionEmitter.setEmissionPoints(std::vector<Vector3f>{ collisionPoint });
explosionEmitter.emit(); explosionEmitter.emit();
lastExplosionTime = SDL_GetTicks64();
std::cerr << "GAME OVER: collision with planet (moved back and exploded)\n"; std::cerr << "GAME OVER: collision with planet (moved back and exploded)\n";
@ -747,6 +756,7 @@ namespace ZL
bool stoneCollided = false; bool stoneCollided = false;
int collidedTriIdx = -1; int collidedTriIdx = -1;
Vector3f collidedStonePos = Vector3f{ 0.0f, 0.0f, 0.0f }; Vector3f collidedStonePos = Vector3f{ 0.0f, 0.0f, 0.0f };
float collidedStoneRadius = 0.0f;
for (int triIdx : planetObject.triangleIndicesToDraw) { for (int triIdx : planetObject.triangleIndicesToDraw) {
if (triIdx < 0 || triIdx >= static_cast<int>(planetObject.planetStones.allInstances.size())) if (triIdx < 0 || triIdx >= static_cast<int>(planetObject.planetStones.allInstances.size()))
@ -772,6 +782,7 @@ namespace ZL
stoneCollided = true; stoneCollided = true;
collidedTriIdx = triIdx; collidedTriIdx = triIdx;
collidedStonePos = stoneWorld; collidedStonePos = stoneWorld;
collidedStoneRadius = stoneRadius;
break; break;
} }
} }
@ -780,10 +791,13 @@ namespace ZL
} }
if (stoneCollided) { if (stoneCollided) {
Vector3f localForward = { 0,0,-1 }; Vector3f away = (Environment::shipPosition - collidedStonePos);
Vector3f worldForward = (Environment::shipMatrix * localForward).normalized(); if (away.squaredNorm() <= 1e-6f) {
const float backDistance = 50.0f; away = Vector3f{ 0.0f, 1.0f, 0.0f };
Environment::shipPosition = Environment::shipPosition - worldForward * backDistance; }
away.normalize();
Environment::shipPosition = collidedStonePos + away * (collidedStoneRadius + shipCollisionRadius + 0.1f);
shipAlive = false; shipAlive = false;
gameOver = true; gameOver = true;
@ -793,6 +807,7 @@ namespace ZL
explosionEmitter.setUseWorldSpace(true); explosionEmitter.setUseWorldSpace(true);
explosionEmitter.setEmissionPoints(std::vector<Vector3f>{ collidedStonePos }); explosionEmitter.setEmissionPoints(std::vector<Vector3f>{ collidedStonePos });
explosionEmitter.emit(); explosionEmitter.emit();
lastExplosionTime = SDL_GetTicks64();
std::cerr << "GAME OVER: collision with stone on triangle " << collidedTriIdx << std::endl; std::cerr << "GAME OVER: collision with stone on triangle " << collidedTriIdx << std::endl;
@ -861,10 +876,42 @@ namespace ZL
explosionEmitter.setUseWorldSpace(true); explosionEmitter.setUseWorldSpace(true);
explosionEmitter.setEmissionPoints(std::vector<Vector3f>{ boxWorld }); explosionEmitter.setEmissionPoints(std::vector<Vector3f>{ boxWorld });
explosionEmitter.emit(); explosionEmitter.emit();
lastExplosionTime = SDL_GetTicks64();
std::cerr << "Box destroyed at index " << i << std::endl; 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<Vector3f>{ boxWorld });
explosionEmitter.emit();
lastExplosionTime = SDL_GetTicks64();
p->deactivate();
std::cerr << "Box destroyed by projectile at index " << i << std::endl;
break;
}
}
}
uiManager.update(static_cast<float>(delta)); uiManager.update(static_cast<float>(delta));
//#endif //#endif
lastTickCount = newTickCount; lastTickCount = newTickCount;

View File

@ -87,14 +87,16 @@ namespace ZL {
int maxProjectiles = 32; int maxProjectiles = 32;
std::vector<Vector3f> shipLocalEmissionPoints; std::vector<Vector3f> shipLocalEmissionPoints;
bool shipAlive = true; bool shipAlive = true;
bool gameOver = false; bool gameOver = false;
std::vector<bool> boxAlive; std::vector<bool> boxAlive;
float shipCollisionRadius = 3.5f; float shipCollisionRadius = 15.0f;
float boxCollisionRadius = 2.0f; float boxCollisionRadius = 2.0f;
bool uiGameOverShown = false; bool uiGameOverShown = false;
bool showExplosion = false; bool showExplosion = false;
uint64_t lastExplosionTime = 0;
const uint64_t explosionDurationMs = 500;
}; };

View File

@ -18,7 +18,7 @@ namespace ZL {
bool isActive() const { return active; } bool isActive() const { return active; }
Vector3f getPosition() const { return pos; } Vector3f getPosition() const { return pos; }
void deactivate() { active = false; }
private: private:
Vector3f pos; Vector3f pos;
Vector3f vel; Vector3f vel;