added collision box/planet
This commit is contained in:
parent
ec30cbe810
commit
cda1c0de20
15
resources/config/explosion_config.json
Normal file
15
resources/config/explosion_config.json
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"emissionPoints": [
|
||||||
|
{ "position": [0.0, 0.0, 0.0] }
|
||||||
|
],
|
||||||
|
"texture": "resources/spark_white.png",
|
||||||
|
"speedRange": [10.0, 30.0],
|
||||||
|
"zSpeedRange": [-1.0, 1.0],
|
||||||
|
"scaleRange": [0.5, 1.0],
|
||||||
|
"lifeTimeRange": [200.0, 800.0],
|
||||||
|
"emissionRate": 50.0,
|
||||||
|
"maxParticles": 5,
|
||||||
|
"particleSize": 0.5,
|
||||||
|
"biasX": 0.1,
|
||||||
|
"shaderProgramName": "default"
|
||||||
|
}
|
||||||
55
resources/config/game_over.json
Normal file
55
resources/config/game_over.json
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
{
|
||||||
|
"root": {
|
||||||
|
"type": "LinearLayout",
|
||||||
|
"orientation": "vertical",
|
||||||
|
"align": "center",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"width": 1920,
|
||||||
|
"height": 1080,
|
||||||
|
"background": {
|
||||||
|
"color": [0, 0, 0, 0.7]
|
||||||
|
},
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "Button",
|
||||||
|
"name": "gameOverText",
|
||||||
|
"x": 350,
|
||||||
|
"y": 400,
|
||||||
|
"width": 600,
|
||||||
|
"height": 150,
|
||||||
|
"textures": {
|
||||||
|
"normal": "resources/gameover.png",
|
||||||
|
"hover": "resources/gameover.png",
|
||||||
|
"pressed": "resources/gameover.png"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Button",
|
||||||
|
"name": "restartButton",
|
||||||
|
"x": 350,
|
||||||
|
"y": 300,
|
||||||
|
"width": 300,
|
||||||
|
"height": 80,
|
||||||
|
"textures": {
|
||||||
|
"normal": "resources/shoot_normal.png",
|
||||||
|
"hover": "resources/shoot_normal.png",
|
||||||
|
"pressed": "resources/shoot_normal.png"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Button",
|
||||||
|
"name": "gameOverExitButton",
|
||||||
|
"x": 650,
|
||||||
|
"y": 300,
|
||||||
|
"width": 300,
|
||||||
|
"height": 80,
|
||||||
|
"textures": {
|
||||||
|
"normal": "resources/sand2.png",
|
||||||
|
"hover": "resources/sand2.png",
|
||||||
|
"pressed": "resources/sand2.png"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
resources/gameover.png
(Stored with Git LFS)
Normal file
BIN
resources/gameover.png
(Stored with Git LFS)
Normal file
Binary file not shown.
85
src/Game.cpp
85
src/Game.cpp
@ -204,6 +204,8 @@ namespace ZL
|
|||||||
|
|
||||||
bool cfgLoaded = sparkEmitter.loadFromJsonFile("resources/config/spark_config.json", renderer, CONST_ZIP_FILE);
|
bool cfgLoaded = sparkEmitter.loadFromJsonFile("resources/config/spark_config.json", renderer, CONST_ZIP_FILE);
|
||||||
bool projCfgLoaded = projectileEmitter.loadFromJsonFile("resources/config/spark_projectile_config.json", renderer, CONST_ZIP_FILE);
|
bool projCfgLoaded = projectileEmitter.loadFromJsonFile("resources/config/spark_projectile_config.json", renderer, CONST_ZIP_FILE);
|
||||||
|
bool explosionCfgLoaded = explosionEmitter.loadFromJsonFile("resources/config/explosion_config.json", renderer, CONST_ZIP_FILE);
|
||||||
|
explosionEmitter.setEmissionPoints(std::vector<Vector3f>());
|
||||||
projectileEmitter.setEmissionPoints(std::vector<Vector3f>());
|
projectileEmitter.setEmissionPoints(std::vector<Vector3f>());
|
||||||
uiManager.loadFromFile("resources/config/ui.json", renderer, CONST_ZIP_FILE);
|
uiManager.loadFromFile("resources/config/ui.json", renderer, CONST_ZIP_FILE);
|
||||||
|
|
||||||
@ -342,6 +344,7 @@ namespace ZL
|
|||||||
boxRenderArr[i].RefreshVBO();
|
boxRenderArr[i].RefreshVBO();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boxAlive.resize(boxCoordsArr.size(), true);
|
||||||
|
|
||||||
std::cout << "Init step 4 " << std::endl;
|
std::cout << "Init step 4 " << std::endl;
|
||||||
|
|
||||||
@ -454,19 +457,28 @@ namespace ZL
|
|||||||
renderer.TranslateMatrix({ 0,0, -1.0f * Environment::zoom });
|
renderer.TranslateMatrix({ 0,0, -1.0f * Environment::zoom });
|
||||||
|
|
||||||
renderer.TranslateMatrix({ 0, -Environment::zoom * 0.03f, 0 });
|
renderer.TranslateMatrix({ 0, -Environment::zoom * 0.03f, 0 });
|
||||||
|
if (shipAlive) {
|
||||||
glBindTexture(GL_TEXTURE_2D, spaceshipTexture->getTexID());
|
glBindTexture(GL_TEXTURE_2D, spaceshipTexture->getTexID());
|
||||||
renderer.DrawVertexRenderStruct(spaceship);
|
renderer.DrawVertexRenderStruct(spaceship);
|
||||||
|
}
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
for (const auto& p : projectiles) {
|
for (const auto& p : projectiles) {
|
||||||
if (p && p->isActive()) {
|
if (p && p->isActive()) {
|
||||||
p->draw(renderer);
|
p->draw(renderer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (shipAlive) {
|
||||||
sparkEmitter.draw(renderer, Environment::zoom, Environment::width, Environment::height);
|
sparkEmitter.draw(renderer, Environment::zoom, Environment::width, Environment::height);
|
||||||
projectileEmitter.draw(renderer, Environment::zoom, Environment::width, Environment::height);
|
projectileEmitter.draw(renderer, Environment::zoom, Environment::width, Environment::height);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showExplosion) {
|
||||||
|
explosionEmitter.draw(renderer, Environment::zoom, Environment::width, Environment::height);
|
||||||
|
}
|
||||||
|
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
renderer.PopMatrix();
|
renderer.PopMatrix();
|
||||||
renderer.PopProjectionMatrix();
|
renderer.PopProjectionMatrix();
|
||||||
@ -496,6 +508,7 @@ namespace ZL
|
|||||||
|
|
||||||
for (int i = 0; i < boxCoordsArr.size(); i++)
|
for (int i = 0; i < boxCoordsArr.size(); i++)
|
||||||
{
|
{
|
||||||
|
if (!boxAlive[i]) continue;
|
||||||
renderer.PushMatrix();
|
renderer.PushMatrix();
|
||||||
|
|
||||||
renderer.LoadIdentity();
|
renderer.LoadIdentity();
|
||||||
@ -670,6 +683,76 @@ namespace ZL
|
|||||||
sparkEmitter.update(static_cast<float>(delta));
|
sparkEmitter.update(static_cast<float>(delta));
|
||||||
projectileEmitter.update(static_cast<float>(delta));
|
projectileEmitter.update(static_cast<float>(delta));
|
||||||
|
|
||||||
|
explosionEmitter.update(static_cast<float>(delta));
|
||||||
|
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;
|
||||||
|
|
||||||
|
shipAlive = false;
|
||||||
|
gameOver = true;
|
||||||
|
Environment::shipVelocity = 0.0f;
|
||||||
|
showExplosion = true;
|
||||||
|
|
||||||
|
explosionEmitter.setUseWorldSpace(false);
|
||||||
|
explosionEmitter.setEmissionPoints(std::vector<Vector3f>{ Vector3f{ 0.0f,0.0f,0.0f } });
|
||||||
|
explosionEmitter.emit();
|
||||||
|
|
||||||
|
std::cerr << "GAME OVER: collision with planet (moved back and exploded)\n";
|
||||||
|
|
||||||
|
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::shipPosition = Vector3f{ 0, 0, 45000.f };
|
||||||
|
Environment::shipVelocity = 0.0f;
|
||||||
|
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) {
|
||||||
|
if (!boxAlive[i]) continue;
|
||||||
|
Vector3f boxWorld = boxCoordsArr[i].pos + Vector3f{ 0.0f, 0.0f, 45000.0f };
|
||||||
|
Vector3f diff = Environment::shipPosition - boxWorld;
|
||||||
|
float thresh = shipCollisionRadius + boxCollisionRadius;
|
||||||
|
if (diff.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;
|
||||||
|
|
||||||
|
Vector3f rel = boxWorld - Environment::shipPosition;
|
||||||
|
Vector3f camPos = Environment::inverseShipMatrix * rel;
|
||||||
|
explosionEmitter.setUseWorldSpace(true);
|
||||||
|
explosionEmitter.setEmissionPoints(std::vector<Vector3f>{ boxWorld });
|
||||||
|
explosionEmitter.emit();
|
||||||
|
|
||||||
|
std::cerr << "Box destroyed at index " << i << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
uiManager.update(static_cast<float>(delta));
|
uiManager.update(static_cast<float>(delta));
|
||||||
//#endif
|
//#endif
|
||||||
lastTickCount = newTickCount;
|
lastTickCount = newTickCount;
|
||||||
|
|||||||
@ -100,6 +100,7 @@ namespace ZL {
|
|||||||
|
|
||||||
SparkEmitter sparkEmitter;
|
SparkEmitter sparkEmitter;
|
||||||
SparkEmitter projectileEmitter;
|
SparkEmitter projectileEmitter;
|
||||||
|
SparkEmitter explosionEmitter;
|
||||||
PlanetObject planetObject;
|
PlanetObject planetObject;
|
||||||
UiManager uiManager;
|
UiManager uiManager;
|
||||||
|
|
||||||
@ -112,7 +113,13 @@ namespace ZL {
|
|||||||
|
|
||||||
TaskManager taskManager;
|
TaskManager taskManager;
|
||||||
|
|
||||||
|
bool shipAlive = true;
|
||||||
|
bool gameOver = false;
|
||||||
|
std::vector<bool> boxAlive;
|
||||||
|
float shipCollisionRadius = 3.5f;
|
||||||
|
float boxCollisionRadius = 2.0f;
|
||||||
|
bool uiGameOverShown = false;
|
||||||
|
bool showExplosion = false;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -13,10 +13,10 @@ namespace ZL {
|
|||||||
|
|
||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
|
||||||
SparkEmitter::SparkEmitter()
|
SparkEmitter::SparkEmitter()
|
||||||
: emissionRate(100.0f), isActive(true), drawDataDirty(true), maxParticles(200),
|
: emissionRate(100.0f), isActive(true), drawDataDirty(true), maxParticles(200),
|
||||||
shaderProgramName("default"), particleSize(0.04f), biasX(0.3f), configured(false) {
|
shaderProgramName("default"), particleSize(0.04f), biasX(0.3f), configured(false),
|
||||||
|
useWorldSpace(false) {
|
||||||
particles.resize(maxParticles);
|
particles.resize(maxParticles);
|
||||||
drawPositions.reserve(maxParticles * 6);
|
drawPositions.reserve(maxParticles * 6);
|
||||||
drawTexCoords.reserve(maxParticles * 6);
|
drawTexCoords.reserve(maxParticles * 6);
|
||||||
@ -28,7 +28,8 @@ namespace ZL {
|
|||||||
SparkEmitter::SparkEmitter(const std::vector<Vector3f>& positions, float rate)
|
SparkEmitter::SparkEmitter(const std::vector<Vector3f>& positions, float rate)
|
||||||
: emissionPoints(positions), emissionRate(rate), isActive(true),
|
: emissionPoints(positions), emissionRate(rate), isActive(true),
|
||||||
drawDataDirty(true), maxParticles(positions.size() * 100),
|
drawDataDirty(true), maxParticles(positions.size() * 100),
|
||||||
shaderProgramName("default"), particleSize(0.04f), biasX(0.3f), configured(false) {
|
shaderProgramName("default"), particleSize(0.04f), biasX(0.3f), configured(false),
|
||||||
|
useWorldSpace(false) {
|
||||||
particles.resize(maxParticles);
|
particles.resize(maxParticles);
|
||||||
drawPositions.reserve(maxParticles * 6);
|
drawPositions.reserve(maxParticles * 6);
|
||||||
drawTexCoords.reserve(maxParticles * 6);
|
drawTexCoords.reserve(maxParticles * 6);
|
||||||
@ -42,7 +43,8 @@ namespace ZL {
|
|||||||
float rate)
|
float rate)
|
||||||
: emissionPoints(positions), texture(tex), emissionRate(rate),
|
: emissionPoints(positions), texture(tex), emissionRate(rate),
|
||||||
isActive(true), drawDataDirty(true), maxParticles(positions.size() * 100),
|
isActive(true), drawDataDirty(true), maxParticles(positions.size() * 100),
|
||||||
shaderProgramName("default"), particleSize(0.04f), biasX(0.3f), configured(false) {
|
shaderProgramName("default"), particleSize(0.04f), biasX(0.3f), configured(false),
|
||||||
|
useWorldSpace(false) {
|
||||||
particles.resize(maxParticles);
|
particles.resize(maxParticles);
|
||||||
drawPositions.reserve(maxParticles * 6);
|
drawPositions.reserve(maxParticles * 6);
|
||||||
drawTexCoords.reserve(maxParticles * 6);
|
drawTexCoords.reserve(maxParticles * 6);
|
||||||
@ -71,7 +73,15 @@ namespace ZL {
|
|||||||
|
|
||||||
for (const auto& particle : particles) {
|
for (const auto& particle : particles) {
|
||||||
if (particle.active) {
|
if (particle.active) {
|
||||||
sortedParticles.push_back({ &particle, particle.position(2) });
|
Vector3f posCam;
|
||||||
|
if (useWorldSpace) {
|
||||||
|
Vector3f rel = particle.position - Environment::shipPosition;
|
||||||
|
posCam = Environment::inverseShipMatrix * rel;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
posCam = particle.position;
|
||||||
|
}
|
||||||
|
sortedParticles.push_back({ &particle, posCam(2) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,25 +92,33 @@ namespace ZL {
|
|||||||
|
|
||||||
for (const auto& [particlePtr, depth] : sortedParticles) {
|
for (const auto& [particlePtr, depth] : sortedParticles) {
|
||||||
const auto& particle = *particlePtr;
|
const auto& particle = *particlePtr;
|
||||||
Vector3f pos = particle.position;
|
Vector3f posCam;
|
||||||
|
if (useWorldSpace) {
|
||||||
|
Vector3f rel = particle.position - Environment::shipPosition;
|
||||||
|
posCam = Environment::inverseShipMatrix * rel;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
posCam = particle.position;
|
||||||
|
}
|
||||||
|
|
||||||
float size = particleSize * particle.scale;
|
float size = particleSize * particle.scale;
|
||||||
|
|
||||||
drawPositions.push_back({ pos(0) - size, pos(1) - size, pos(2) });
|
drawPositions.push_back({ posCam(0) - size, posCam(1) - size, posCam(2) });
|
||||||
drawTexCoords.push_back({ 0.0f, 0.0f });
|
drawTexCoords.push_back({ 0.0f, 0.0f });
|
||||||
|
|
||||||
drawPositions.push_back({ pos(0) - size, pos(1) + size, pos(2) });
|
drawPositions.push_back({ posCam(0) - size, posCam(1) + size, posCam(2) });
|
||||||
drawTexCoords.push_back({ 0.0f, 1.0f });
|
drawTexCoords.push_back({ 0.0f, 1.0f });
|
||||||
|
|
||||||
drawPositions.push_back({ pos(0) + size, pos(1) + size, pos(2) });
|
drawPositions.push_back({ posCam(0) + size, posCam(1) + size, posCam(2) });
|
||||||
drawTexCoords.push_back({ 1.0f, 1.0f });
|
drawTexCoords.push_back({ 1.0f, 1.0f });
|
||||||
|
|
||||||
drawPositions.push_back({ pos(0) - size, pos(1) - size, pos(2) });
|
drawPositions.push_back({ posCam(0) - size, posCam(1) - size, posCam(2) });
|
||||||
drawTexCoords.push_back({ 0.0f, 0.0f });
|
drawTexCoords.push_back({ 0.0f, 0.0f });
|
||||||
|
|
||||||
drawPositions.push_back({ pos(0) + size, pos(1) + size, pos(2) });
|
drawPositions.push_back({ posCam(0) + size, posCam(1) + size, posCam(2) });
|
||||||
drawTexCoords.push_back({ 1.0f, 1.0f });
|
drawTexCoords.push_back({ 1.0f, 1.0f });
|
||||||
|
|
||||||
drawPositions.push_back({ pos(0) + size, pos(1) - size, pos(2) });
|
drawPositions.push_back({ posCam(0) + size, posCam(1) - size, posCam(2) });
|
||||||
drawTexCoords.push_back({ 1.0f, 0.0f });
|
drawTexCoords.push_back({ 1.0f, 0.0f });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -51,6 +51,7 @@ namespace ZL {
|
|||||||
|
|
||||||
bool configured;
|
bool configured;
|
||||||
void prepareDrawData();
|
void prepareDrawData();
|
||||||
|
bool useWorldSpace;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SparkEmitter();
|
SparkEmitter();
|
||||||
@ -67,6 +68,7 @@ namespace ZL {
|
|||||||
void setParticleSize(float size) { particleSize = size; }
|
void setParticleSize(float size) { particleSize = size; }
|
||||||
void setBiasX(float bias) { biasX = bias; }
|
void setBiasX(float bias) { biasX = bias; }
|
||||||
|
|
||||||
|
void setUseWorldSpace(bool use) { useWorldSpace = use; }
|
||||||
bool loadFromJsonFile(const std::string& path, Renderer& renderer, const std::string& zipFile = "");
|
bool loadFromJsonFile(const std::string& path, Renderer& renderer, const std::string& zipFile = "");
|
||||||
|
|
||||||
void update(float deltaTimeMs);
|
void update(float deltaTimeMs);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user