@ -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 <iostream>
@ -263,7 +264,7 @@ namespace ZL
//spaceshipTexture = std::make_unique<Texture>(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<Texture>(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());
@ -745,23 +746,31 @@ namespace ZL
projectileEmitter . 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 ) {
float distToSurface = planetObject . distanceToPlanetSurface ( Environment : : shipState . position ) ;
if ( distToSurface < = 0.0f ) {
Vector3f localForward = { 0 , 0 , - 1 } ;
Vector3f worldForward = ( Environment : : shipState . rotation * localForward ) . normalized ( ) ;
const float backDistance = 400.0f ;
Environment : : shipState . position = Environment : : shipState . position - worldForward * backDistance ;
Vector3f dir = ( Environment : : shipState . position - PlanetData : : PLANET_CENTER_OFFSET ) . normalized ( ) ;
Vector3f collisionPoint = PlanetData : : PLANET_CENTER_OFFSET + dir * PlanetData : : PLANET_RADIUS ;
Environment : : shipState . position = PlanetData : : PLANET_CENTER_OFFSET + dir * ( PlanetData : : PLANET_RADIUS + shipCollisionRadius + 0.1f ) ;
shipAlive = false ;
gameOver = true ;
Environment : : shipState . velocity = 0.0f ;
showExplosion = true ;
explosionEmitter . setUseWorldSpace ( fals e) ;
explosionEmitter . setEmissionPoints ( std : : vector < Vector3f > { Vector3f{ 0.0f , 0.0f , 0.0f } } ) ;
explosionEmitter . setUseWorldSpace ( tru e) ;
explosionEmitter . setEmissionPoints ( std : : vector < Vector3f > { collisionPoint } ) ;
explosionEmitter . emit ( ) ;
lastExplosionTime = SDL_GetTicks64 ( ) ;
std : : cerr < < " GAME OVER: collision with planet (moved back and exploded) \n " ;
@ -773,8 +782,14 @@ namespace ZL
this - > uiGameOverShown = false ;
this - > showExplosion = false ;
this - > explosionEmitter . setEmissionPoints ( std : : vector < Vector3f > ( ) ) ;
Environment : : shipState . position = Vector3f { 0 , 0 , 45000.f } ;
Environment : : shipState . velocity = 0.0f ;
Environment : : shipState . rotation = Eigen : : Matrix3f : : Identity ( ) ;
Environment : : inverseShipMatrix = Eigen : : Matrix3f : : Identity ( ) ;
Environment : : zoom = DEFAULT_ZOOM ;
Environment : : tapDownHold = false ;
uiManager . popMenu ( ) ;
std : : cerr < < " Game restarted \n " ;
} ) ;
@ -790,6 +805,109 @@ namespace ZL
}
}
}
else {
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 < int > ( planetObject . planetStones . allInstances . size ( ) ) )
continue ;
if ( planetObject . planetStones . statuses . size ( ) < = static_cast < size_t > ( 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 : : shipState . position - 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 ;
collidedStoneRadius = stoneRadius ;
break ;
}
}
if ( stoneCollided ) break ;
}
if ( stoneCollided ) {
Vector3f away = ( Environment : : shipState . position - collidedStonePos ) ;
if ( away . squaredNorm ( ) < = 1e-6 f ) {
away = Vector3f { 0.0f , 1.0f , 0.0f } ;
}
away . normalize ( ) ;
Environment : : shipState . position = collidedStonePos + away * ( collidedStoneRadius + shipCollisionRadius + 0.1f ) ;
shipAlive = false ;
gameOver = true ;
Environment : : shipState . velocity = 0.0f ;
showExplosion = true ;
explosionEmitter . setUseWorldSpace ( true ) ;
explosionEmitter . setEmissionPoints ( std : : vector < Vector3f > { collidedStonePos } ) ;
explosionEmitter . emit ( ) ;
lastExplosionTime = SDL_GetTicks64 ( ) ;
std : : cerr < < " GAME OVER: collision with stone on triangle " < < collidedTriIdx < < std : : endl ;
if ( collidedTriIdx > = 0 & & collidedTriIdx < static_cast < int > ( 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 < int > ( 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 < Vector3f > ( ) ) ;
Environment : : shipState . position = Vector3f { 0 , 0 , 45000.f } ;
Environment : : shipState . velocity = 0.0f ;
Environment : : shipState . rotation = Eigen : : Matrix3f : : Identity ( ) ;
Environment : : inverseShipMatrix = Eigen : : Matrix3f : : Identity ( ) ;
Environment : : zoom = DEFAULT_ZOOM ;
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 ) {
@ -811,10 +929,42 @@ namespace ZL
explosionEmitter . setUseWorldSpace ( true ) ;
explosionEmitter . setEmissionPoints ( std : : vector < Vector3f > { 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 : : shipState . position ) ;
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 ) ) ;
lastTickCount = newTickCount ;
}