From 1f09c40bb5b8bc69255f29cee5c69f4fc5c66935 Mon Sep 17 00:00:00 2001 From: s473577 Date: Sat, 3 Feb 2024 20:20:01 +0100 Subject: [PATCH] Add collision detection and taking dmg --- grk/project/Bullet.h | 42 ++++++++++++++++- grk/project/Enemy.h | 29 ++++++++---- grk/project/GameEntity.h | 23 +++++++++ grk/project/Spaceship.h | 19 ++++++-- grk/project/grk-project.vcxproj | 1 + grk/project/grk-project.vcxproj.filters | 3 ++ grk/project/src/ex_9_1.hpp | 39 +++++++++++----- grk/project/src/ex_9_1.hpp.orig | 62 ++++++++++++++++--------- 8 files changed, 169 insertions(+), 49 deletions(-) create mode 100644 grk/project/GameEntity.h diff --git a/grk/project/Bullet.h b/grk/project/Bullet.h index ec40915..bbfea5b 100644 --- a/grk/project/Bullet.h +++ b/grk/project/Bullet.h @@ -1,5 +1,7 @@ #include "glm.hpp" #include "src/Shader_Loader.h" +#include +#include "GameEntity.h" #pragma once class Bullet @@ -39,14 +41,52 @@ public: return new Bullet(10, 10, directionNormalized, startPosition, birthTime, simpleRenderContext, 0.01f); } - bool shouldBeDestroyed(float time, GLuint program) { + bool shouldBeDestroyed(float time, GLuint program, std::vector& gameEntities, float attackerDmg) { float age = getAge(time); if (age > lifetime) { return true; } glm::mat4 modelMatrix = glm::translate(glm::mat4(1.0f), startPosition) * glm::translate(directionNormalized * speed * age) * glm::scale(glm::vec3(scale)); Core::drawObjectPBR(renderContext, modelMatrix, glm::vec3(1.f, 0.f, 0.f), 0.3, 0, program); + //std::cout << "x: " << modelMatrix[3].x << std::endl; + //std::cout << "y: " << modelMatrix[3].y << std::endl; + //std::cout << "z: " << modelMatrix[3].z << std::endl; + if (checkCollisionWithGameEntities(gameEntities, modelMatrix, attackerDmg)) { + return true; + } + + return false; } + bool checkCollisionWithGameEntities(std::vector& gameEntities, glm::mat4 bulletModelMatrix, float attackerDmg) { + for (const auto& entity : gameEntities) { + glm::mat4 entityModelMatrix = entity->getModelMatrix(); + + // SprawdŸ kolizję AABB między pociskiem a obiektem z wektora gameEntities + if (checkAABBCollision(bulletModelMatrix, entityModelMatrix)) { + entity->applyDamage(attackerDmg); + return true; + } + } + + return false; + } + bool checkAABBCollision(const glm::mat4& obj1ModelMatrix, const glm::mat4& obj2ModelMatrix) { + // Pobierz rozmiary obiektów z ich macierzy modelu + glm::vec3 obj1Min = glm::vec3(obj1ModelMatrix * glm::vec4(-0.5f, -0.5f, -0.5f, 1.0f)); + glm::vec3 obj1Max = glm::vec3(obj1ModelMatrix * glm::vec4(0.5f, 0.5f, 0.5f, 1.0f)); + + glm::vec3 obj2Min = glm::vec3(obj2ModelMatrix * glm::vec4(-0.5f, -0.5f, -0.5f, 1.0f)); + glm::vec3 obj2Max = glm::vec3(obj2ModelMatrix * glm::vec4(0.5f, 0.5f, 0.5f, 1.0f)); + + // SprawdŸ kolizję wzdłuż trzech osi (x, y, z) + bool collisionX = obj1Max.x >= obj2Min.x && obj1Min.x <= obj2Max.x; + bool collisionY = obj1Max.y >= obj2Min.y && obj1Min.y <= obj2Max.y; + bool collisionZ = obj1Max.z >= obj2Min.z && obj1Min.z <= obj2Max.z; + + // Kolizja występuje tylko wtedy, gdy zachodzi kolizja na wszystkich trzech osiach + return collisionX && collisionY && collisionZ; + } + }; diff --git a/grk/project/Enemy.h b/grk/project/Enemy.h index bef66a5..24b3ed1 100644 --- a/grk/project/Enemy.h +++ b/grk/project/Enemy.h @@ -2,10 +2,11 @@ #include "ext.hpp" #include "src/Render_Utils.h" #include "Bullet.h" +#include "./GameEntity.h" #include "Spaceship.h" #pragma once -class Enemy +class Enemy : public GameEntity { private: std::list bullets; @@ -14,13 +15,13 @@ private: public: glm::mat4 modelMatrix; - int hp; - int initialHp; - int dmg; float aggroRange; - Enemy(int currHp,int initialHp, glm::mat4 initialModelMatrix, int initialDmg, float initialAggroRange) - : hp(currHp), initialHp(initialHp), modelMatrix(initialModelMatrix), dmg(initialDmg), aggroRange(initialAggroRange) + Enemy(float currHp,float initialHp, glm::mat4 initialModelMatrix, float initialDmg, float initialAggroRange) + : + aggroRange(initialAggroRange), + modelMatrix(initialModelMatrix), + GameEntity(currHp, initialHp, initialDmg) {} @@ -34,7 +35,7 @@ public: } virtual bool isAlive() const { - if (this->hp < 0) { + if (this->currentHP <= 0) { return false; } return true; @@ -48,11 +49,11 @@ public: return true; } - void renderBullets(float time, GLuint program) { + void renderBullets(float time, GLuint program, std::vector& gameEntities) { for (auto it = bullets.begin(); it != bullets.end();) { Bullet* bullet = *it; - if (bullet->shouldBeDestroyed(time, program)) { + if (bullet->shouldBeDestroyed(time, program, gameEntities, dmg)) { delete bullet; it = bullets.erase(it); } @@ -61,6 +62,15 @@ public: } } } + glm::vec3 getPosition() const override + { + return modelMatrix[3]; + } + glm::mat4 getModelMatrix() override + { + return modelMatrix; + } + private: void requestShoot(float time) { if (canShoot(time)) { @@ -75,6 +85,7 @@ private: void shoot(float time) { Spaceship* spaceship = Spaceship::getInstance(); glm::vec3 bulletDirection = glm::normalize(spaceship->spaceshipPos - glm::vec3(modelMatrix[3])); + this->bullets.push_back(Bullet::createSimpleBullet(bulletDirection, this->modelMatrix[3], time)); this->lastShootTime = time; } diff --git a/grk/project/GameEntity.h b/grk/project/GameEntity.h new file mode 100644 index 0000000..7a5c189 --- /dev/null +++ b/grk/project/GameEntity.h @@ -0,0 +1,23 @@ +#include "glm.hpp" + +#pragma once +class GameEntity +{ +public: + float currentHP; + float dmg; + float maxHP; + + GameEntity(float currentHP, float maxHP, float initialDmg) + : currentHP(currentHP), maxHP(maxHP), dmg(initialDmg) + { + + } + + virtual void applyDamage(float attackerDmg) { + currentHP = currentHP - attackerDmg; + }; + virtual glm::vec3 getPosition() const = 0; + virtual glm::mat4 getModelMatrix() = 0; +}; + diff --git a/grk/project/Spaceship.h b/grk/project/Spaceship.h index 2e1a0e4..06579a4 100644 --- a/grk/project/Spaceship.h +++ b/grk/project/Spaceship.h @@ -4,10 +4,11 @@ #include #include "Bullet.h" #include "ParticleSystem.h" +#include "GameEntity.h" #pragma once -class Spaceship +class Spaceship : public GameEntity { private: std::list bullets; @@ -16,8 +17,9 @@ private: ParticleSystem* leftParticle; ParticleSystem* rightParticle; - // Prywatny konstruktor, aby zapobiec zewnętrznemu tworzeniu instancji - Spaceship() { + // Prywatny konstruktor, aby zapobiec zewnďż˝trznemu tworzeniu instancji + Spaceship() : GameEntity(100.0f, 100.0f, 10.0f) + { } @@ -164,11 +166,11 @@ public: return cameraMatrix; } - void renderBullets(float time, GLuint program) { + void renderBullets(float time, GLuint program, std::vector& gameEntities) { for (auto it = bullets.begin(); it != bullets.end();) { Bullet* bullet = *it; - if (bullet->shouldBeDestroyed(time, program)) { + if (bullet->shouldBeDestroyed(time, program, gameEntities, dmg)) { delete bullet; it = bullets.erase(it); } @@ -194,4 +196,11 @@ public: bullets.push_back(Bullet::createSimpleBullet(cameraDir, spaceshipPos + perpendicularVector, time)); lastShootTime = time; } + + glm::vec3 getPosition() const override { + return spaceshipPos; + } + glm::mat4 getModelMatrix() override { + return calculateModelMatrix(); + } }; \ No newline at end of file diff --git a/grk/project/grk-project.vcxproj b/grk/project/grk-project.vcxproj index 172044f..e1e7e9f 100644 --- a/grk/project/grk-project.vcxproj +++ b/grk/project/grk-project.vcxproj @@ -29,6 +29,7 @@ + diff --git a/grk/project/grk-project.vcxproj.filters b/grk/project/grk-project.vcxproj.filters index 406cd86..d489eb7 100644 --- a/grk/project/grk-project.vcxproj.filters +++ b/grk/project/grk-project.vcxproj.filters @@ -128,6 +128,9 @@ Header Files + + Header Files + diff --git a/grk/project/src/ex_9_1.hpp b/grk/project/src/ex_9_1.hpp index 2db0268..03f09ca 100644 --- a/grk/project/src/ex_9_1.hpp +++ b/grk/project/src/ex_9_1.hpp @@ -70,7 +70,7 @@ Sun* sun; GLuint VAO,VBO; std::vector enemies; - +std::vector gameEntities; float exposition = 1.f; @@ -94,13 +94,21 @@ void updateDeltaTime(float time) { if (deltaTime > 0.1) deltaTime = 0.1; lastTime = time; } -void renderEnemies() { - glDisable(GL_DEPTH_TEST); +void renderHUD() { glUseProgram(programSpriteBar); + glDisable(GL_DEPTH_TEST); glm::mat4 spaceshipModelMatrix = spaceship->calculateModelMatrix(); glm::mat4 healthBarPosition = glm::translate(spaceshipModelMatrix, glm::vec3(12.0f, -9.0f, 0.0f)); - spriteRenderer->DrawHUDBar(glm::vec3(0.0f, 1.0f, 0.0f), glm::scale(healthBarPosition, glm::vec3(9.0f, 1.1f, 1.0f)), 1.f, programSpriteBar); + spriteRenderer->DrawHUDBar( + glm::vec3(0.0f, 1.0f, 0.0f), + glm::scale(healthBarPosition, glm::vec3(9.0f, 1.1f, 1.0f)), + spaceship->currentHP / spaceship->maxHP, + programSpriteBar); glEnable(GL_DEPTH_TEST); +} +void renderEnemies() { + + glUseProgram(programSpriteBar); for (const auto& enemy : enemies) { if (enemy->isAlive()) { spriteRenderer->DrawSpriteBar( @@ -110,12 +118,13 @@ void renderEnemies() { ), glm::vec3(1.0f, 0.2f, 1.0f) ), - static_cast(enemy->hp / enemy->initialHp), + enemy->currentHP / enemy->maxHP, programSpriteBar); } } glUseProgram(programSprite); for (const auto& enemy : enemies) { + if (enemy->isAlive()) { spriteRenderer->DrawSprite(texture::spriteTexture, enemy->modelMatrix, programSprite); } @@ -125,7 +134,7 @@ void renderEnemies() { for (const auto& enemy : enemies) { if (enemy->isAlive()) { enemy->attack(spaceship->spaceshipPos, glfwGetTime()); - enemy->renderBullets(glfwGetTime(), program); + enemy->renderBullets(glfwGetTime(), program, gameEntities); } } @@ -174,9 +183,8 @@ void renderScene(GLFWwindow* window) glUseProgram(program); - spaceship->renderBullets(glfwGetTime(), program); - - + std::vector gameEntities(enemies.begin(), enemies.end()); + spaceship->renderBullets(glfwGetTime(), program, gameEntities); drawObjectPBR(models::sphereContext, glm::translate(pointlightPos) * glm::scale(glm::vec3(0.1)) * glm::eulerAngleY(time / 3) * glm::translate(glm::vec3(4.f, 0, 0)) * glm::eulerAngleY(time) * glm::translate(glm::vec3(1.f, 0, 0)) * glm::scale(glm::vec3(0.1f)), @@ -190,6 +198,7 @@ void renderScene(GLFWwindow* window) texture::spaceshipTexture, spaceship->roughness, spaceship->metallic, programTex ); +<<<<<<< HEAD <<<<<<< HEAD //Core::SetActiveTexture(texture::earthTexture, "textureSampler", programTex, 0); @@ -219,6 +228,9 @@ void renderScene(GLFWwindow* window) glm::mat4 viewMatrix = Core::createViewMatrix(spaceship->cameraPos, spaceship->cameraDir, cameraUp); spaceship->renderParticles(programParticle, viewMatrix, Core::createPerspectiveMatrix(), time); ======= +======= + renderHUD(); +>>>>>>> 9586849 (Add collision detection and taking dmg) renderEnemies(); //drawObjectPBR(sphereContext, glm::translate(pointlightPos) * glm::scale(glm::vec3(1)) * glm::eulerAngleY(time / 3) * glm::translate(glm::vec3(10.f, 0, 0)) * glm::scale(glm::vec3(0.3f)), glm::vec3(0.2, 0.7, 0.3), 0.3, 0.0, program); @@ -268,9 +280,12 @@ void createSolarSystem(glm::vec3 sunPos, float sunScale, float* planetSizes, int void createEnemies() { - enemies.push_back(new Enemy(100,100, glm::mat4(1.0f), 20, 5.0f)); - enemies.push_back(new Enemy(100,100, glm::translate(glm::mat4(1.0f) , glm::vec3(1.f,1.f,1.f)), 15, 5.0f)); - enemies.push_back(new Enemy(100,100, glm::translate(glm::mat4(1.0f), glm::vec3(-1.f, 2.f, -0.9f)), 25, 5.0f)); + enemies.push_back(new Enemy(100.0f,100.0f, glm::mat4(1.0f), 1.0f, 5.0f)); + enemies.push_back(new Enemy(100.0f,100.0f, glm::translate(glm::mat4(1.0f) , glm::vec3(1.f,1.f,1.f)), 1.0f, 5.0f)); + enemies.push_back(new Enemy(100.0f,100.0f, glm::translate(glm::mat4(1.0f), glm::vec3(-1.f, 2.f, -0.9f)), 1.0f, 5.0f)); + + //obiekty do ktorych bedzie sprawdzana kolizja dla pociskow enemy + gameEntities.push_back(spaceship); } diff --git a/grk/project/src/ex_9_1.hpp.orig b/grk/project/src/ex_9_1.hpp.orig index db43d6d..ac08dc5 100644 --- a/grk/project/src/ex_9_1.hpp.orig +++ b/grk/project/src/ex_9_1.hpp.orig @@ -61,19 +61,16 @@ GLuint programSun; GLuint programTest; GLuint programSprite; GLuint programCubemap; -<<<<<<< HEAD GLuint programParticle; GLuint programTex; -======= GLuint programSpriteBar; ->>>>>>> 6ccdec5 (Add drawing health bars for enemies) std::list planets; Sun* sun; GLuint VAO,VBO; std::vector enemies; - +std::vector gameEntities; float exposition = 1.f; @@ -97,7 +94,20 @@ void updateDeltaTime(float time) { if (deltaTime > 0.1) deltaTime = 0.1; lastTime = time; } +void renderHUD() { + glUseProgram(programSpriteBar); + glDisable(GL_DEPTH_TEST); + glm::mat4 spaceshipModelMatrix = spaceship->calculateModelMatrix(); + glm::mat4 healthBarPosition = glm::translate(spaceshipModelMatrix, glm::vec3(12.0f, -9.0f, 0.0f)); + spriteRenderer->DrawHUDBar( + glm::vec3(0.0f, 1.0f, 0.0f), + glm::scale(healthBarPosition, glm::vec3(9.0f, 1.1f, 1.0f)), + spaceship->currentHP / spaceship->maxHP, + programSpriteBar); + glEnable(GL_DEPTH_TEST); +} void renderEnemies() { + glUseProgram(programSpriteBar); for (const auto& enemy : enemies) { if (enemy->isAlive()) { @@ -108,24 +118,13 @@ void renderEnemies() { ), glm::vec3(1.0f, 0.2f, 1.0f) ), - static_cast(enemy->hp / enemy->initialHp), + enemy->currentHP / enemy->maxHP, programSpriteBar); } - -<<<<<<< HEAD -TextureTuple getRandomPlanetTexture() { - int textureIndex = rand() % planetTextures.size(); - TextureTuple selectedTextures = planetTextures[textureIndex]; - //GLuint textureID = selectedTextures.textureID; - //GLuint normalMapID = selectedTextures.normalMapID; - - return planetTextures[textureIndex]; -} - -======= } glUseProgram(programSprite); for (const auto& enemy : enemies) { + if (enemy->isAlive()) { spriteRenderer->DrawSprite(texture::spriteTexture, enemy->modelMatrix, programSprite); } @@ -135,13 +134,20 @@ TextureTuple getRandomPlanetTexture() { for (const auto& enemy : enemies) { if (enemy->isAlive()) { enemy->attack(spaceship->spaceshipPos, glfwGetTime()); - enemy->renderBullets(glfwGetTime(), program); + enemy->renderBullets(glfwGetTime(), program, gameEntities); } } } ->>>>>>> 6ccdec5 (Add drawing health bars for enemies) +TextureTuple getRandomPlanetTexture() { + int textureIndex = rand() % planetTextures.size(); + TextureTuple selectedTextures = planetTextures[textureIndex]; + //GLuint textureID = selectedTextures.textureID; + //GLuint normalMapID = selectedTextures.normalMapID; + + return planetTextures[textureIndex]; +} void renderShadowapSun() { float time = glfwGetTime(); glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT); @@ -174,10 +180,15 @@ void renderScene(GLFWwindow* window) for (Planet* p : planets) { p->draw(time, programTex); } +<<<<<<< HEAD glUseProgram(program); spaceship->renderBullets(glfwGetTime(), program); +======= + std::vector gameEntities(enemies.begin(), enemies.end()); + spaceship->renderBullets(glfwGetTime(), program, gameEntities); +>>>>>>> 9586849 (Add collision detection and taking dmg) @@ -193,6 +204,7 @@ void renderScene(GLFWwindow* window) texture::spaceshipTexture, spaceship->roughness, spaceship->metallic, programTex ); +<<<<<<< HEAD <<<<<<< HEAD //Core::SetActiveTexture(texture::earthTexture, "textureSampler", programTex, 0); @@ -222,6 +234,9 @@ void renderScene(GLFWwindow* window) glm::mat4 viewMatrix = Core::createViewMatrix(spaceship->cameraPos, spaceship->cameraDir, cameraUp); spaceship->renderParticles(programParticle, viewMatrix, Core::createPerspectiveMatrix(), time); ======= +======= + renderHUD(); +>>>>>>> 9586849 (Add collision detection and taking dmg) renderEnemies(); //drawObjectPBR(sphereContext, glm::translate(pointlightPos) * glm::scale(glm::vec3(1)) * glm::eulerAngleY(time / 3) * glm::translate(glm::vec3(10.f, 0, 0)) * glm::scale(glm::vec3(0.3f)), glm::vec3(0.2, 0.7, 0.3), 0.3, 0.0, program); @@ -271,9 +286,12 @@ void createSolarSystem(glm::vec3 sunPos, float sunScale, float* planetSizes, int void createEnemies() { - enemies.push_back(new Enemy(100,100, glm::mat4(1.0f), 20, 5.0f)); - enemies.push_back(new Enemy(100,100, glm::translate(glm::mat4(1.0f) , glm::vec3(1.f,1.f,1.f)), 15, 5.0f)); - enemies.push_back(new Enemy(100,100, glm::translate(glm::mat4(1.0f), glm::vec3(-1.f, 2.f, -0.9f)), 25, 5.0f)); + enemies.push_back(new Enemy(100.0f,100.0f, glm::mat4(1.0f), 1.0f, 5.0f)); + enemies.push_back(new Enemy(100.0f,100.0f, glm::translate(glm::mat4(1.0f) , glm::vec3(1.f,1.f,1.f)), 1.0f, 5.0f)); + enemies.push_back(new Enemy(100.0f,100.0f, glm::translate(glm::mat4(1.0f), glm::vec3(-1.f, 2.f, -0.9f)), 1.0f, 5.0f)); + + //obiekty do ktorych bedzie sprawdzana kolizja dla pociskow enemy + gameEntities.push_back(spaceship); }