From fcda12e32195dd38d5f63731c7a9e690f043bfb9 Mon Sep 17 00:00:00 2001 From: Persson-dev Date: Mon, 2 Jan 2023 16:37:18 +0100 Subject: [PATCH] add hit "animation" --- include/game/Mobs.h | 17 ++- include/render/Renderer.h | 1 + include/render/shaders/EntityShader.h | 2 + src/game/Mobs.cpp | 153 +++++++++++++------------- src/render/Renderer.cpp | 1 + src/render/WorldRenderer.cpp | 1 + src/render/shaders/EntityShader.cpp | 17 ++- 7 files changed, 109 insertions(+), 83 deletions(-) diff --git a/include/game/Mobs.h b/include/game/Mobs.h index 3d1f5a7..062a1ea 100644 --- a/include/game/Mobs.h +++ b/include/game/Mobs.h @@ -89,6 +89,7 @@ private: Direction m_Direction; std::vector m_Effects; const Tower* m_LastDamage; // the last tower that damaged the mob + float m_HitCooldown; utils::Timer m_EffectFireTimer; utils::Timer m_EffectPoisonTimer; @@ -99,7 +100,7 @@ private: public: Mob(MobID id, MobLevel level, PlayerID sender) : m_Sender(sender), m_Level(level), - m_EffectFireTimer(1000), m_EffectPoisonTimer(1000), + m_HitCooldown(0), m_EffectFireTimer(1000), m_EffectPoisonTimer(1000), m_EffectHealTimer(1000), m_CastleTarget(nullptr), m_AttackTimer(1000) { } @@ -123,8 +124,16 @@ public: const Tower* GetLastDamageTower() { return m_LastDamage; } bool HasReachedEnemyCastle() { return m_CastleTarget != nullptr; } - void Damage(float dmg, const Tower* damager) { m_Health = std::max(0.0f, m_Health - dmg); m_LastDamage = damager; } - void Heal(float heal) { m_Health = std::min(static_cast(GetStats()->GetMaxLife()), m_Health + heal); } + void Damage(float dmg, const Tower* damager) { + m_Health = std::max(0.0f, m_Health - dmg); + m_LastDamage = damager; + m_HitCooldown = 0.1; + } + + void Heal(float heal) { + m_Health = std::min(static_cast(GetStats()->GetMaxLife()), m_Health + heal); + } + void SetMobReachedCastle(TeamCastle* castle) { m_CastleTarget = castle; } // used when mob is in front of the castle bool IsImmuneTo(TowerType type); @@ -133,6 +142,8 @@ public: void AddEffect(EffectType type, float durationSec, Tower* tower); bool HasEffect(EffectType type); + bool HasTakenDamage() { return m_HitCooldown > 0; } + float GetTileX() { return GetCenterX() - static_cast(static_cast(GetCenterX())); } // returns a float between 0 and 1 excluded float GetTileY() { return GetCenterY() - static_cast(static_cast(GetCenterY())); } // returns a float between 0 and 1 excluded diff --git a/include/render/Renderer.h b/include/render/Renderer.h index 5f2570c..e71bbde 100644 --- a/include/render/Renderer.h +++ b/include/render/Renderer.h @@ -16,6 +16,7 @@ public: struct Model { GL::VertexArray* vao; Vec2f positon; + Vec3f color = { 1, 1, 1 }; }; private: std::unique_ptr m_WorldShader; diff --git a/include/render/shaders/EntityShader.h b/include/render/shaders/EntityShader.h index 824ade6..2912f40 100644 --- a/include/render/shaders/EntityShader.h +++ b/include/render/shaders/EntityShader.h @@ -13,6 +13,7 @@ private: unsigned int m_LocationAspectRatio = 0; unsigned int m_LocationTranslation = 0; unsigned int m_LocationViewtype = 0; + unsigned int m_LocationColorEffect = 0; protected: virtual void GetAllUniformLocation(); public: @@ -24,6 +25,7 @@ public: void SetAspectRatio(float aspectRatio); void SetModelPos(const Vec2f& modelPos); void SetIsometricView(float isometric); + void SetColorEffect(const Vec3f& color); }; } // namespace shader diff --git a/src/game/Mobs.cpp b/src/game/Mobs.cpp index c9e7ac6..dff0472 100644 --- a/src/game/Mobs.cpp +++ b/src/game/Mobs.cpp @@ -51,21 +51,21 @@ void Mob::Walk(std::uint64_t delta, World* world) { switch (GetDirection()) { case Direction::NegativeX: { - SetCenterX(GetCenterX() - walkAmount); - break; - } + SetCenterX(GetCenterX() - walkAmount); + break; + } case Direction::PositiveX: { - SetCenterX(GetCenterX() + walkAmount); - break; - } + SetCenterX(GetCenterX() + walkAmount); + break; + } case Direction::NegativeY: { - SetCenterY(GetCenterY() - walkAmount); - break; - } + SetCenterY(GetCenterY() - walkAmount); + break; + } case Direction::PositiveY: { - SetCenterY(GetCenterY() + walkAmount); - break; - } + SetCenterY(GetCenterY() + walkAmount); + break; + } default: break; } @@ -104,21 +104,21 @@ void Mob::Move(std::uint64_t delta, World* world) { void Mob::MoveBack(const TeamCastle& enemyCastle, World* world) { switch (GetDirection()) { case Direction::NegativeX: { - SetCenterX(enemyCastle.GetBottomRight().GetX() + GetWidth() / 2.0f); - break; - } + SetCenterX(enemyCastle.GetBottomRight().GetX() + GetWidth() / 2.0f); + break; + } case Direction::PositiveX: { - SetCenterX(enemyCastle.GetTopLeft().GetX() - GetWidth() / 2.0f); - break; - } + SetCenterX(enemyCastle.GetTopLeft().GetX() - GetWidth() / 2.0f); + break; + } case Direction::NegativeY: { - SetCenterY(enemyCastle.GetBottomRight().GetY() + GetHeight() / 2.0f); - break; - } + SetCenterY(enemyCastle.GetBottomRight().GetY() + GetHeight() / 2.0f); + break; + } case Direction::PositiveY: { - SetCenterY(enemyCastle.GetTopLeft().GetY() - GetHeight() / 2.0f); - break; - } + SetCenterY(enemyCastle.GetTopLeft().GetY() - GetHeight() / 2.0f); + break; + } default: break; } @@ -133,64 +133,64 @@ void Mob::ChangeDirection(const WalkableTile& tile, World* world) { switch (GetDirection()) { case Direction::PositiveY: { - if (tile.direction == Direction::NegativeX) { - if (GetTileY() > GetTileX()) { - SetCenterY(tileY + GetTileX()); - SetDirection(tile.direction); - } - } else { // tile->direction = Direction::PositiveX - if (GetTileY() > 1 - GetTileX()) { - SetCenterY(tileY + (1 - GetTileX())); - SetDirection(tile.direction); - } + if (tile.direction == Direction::NegativeX) { + if (GetTileY() > GetTileX()) { + SetCenterY(tileY + GetTileX()); + SetDirection(tile.direction); + } + } else { // tile->direction = Direction::PositiveX + if (GetTileY() > 1 - GetTileX()) { + SetCenterY(tileY + (1 - GetTileX())); + SetDirection(tile.direction); } - return; } + return; + } case Direction::NegativeY: { - if (tile.direction == Direction::PositiveX) { - if (GetTileY() < GetTileX()) { - SetCenterY(tileY + GetTileX()); - SetDirection(tile.direction); - } - } else { // tile.direction = Direction::NegativeX - if (GetTileY() < 1 - GetTileX()) { - SetCenterY(tileY + (1 - GetTileX())); - SetDirection(tile.direction); - } + if (tile.direction == Direction::PositiveX) { + if (GetTileY() < GetTileX()) { + SetCenterY(tileY + GetTileX()); + SetDirection(tile.direction); + } + } else { // tile.direction = Direction::NegativeX + if (GetTileY() < 1 - GetTileX()) { + SetCenterY(tileY + (1 - GetTileX())); + SetDirection(tile.direction); } - return; } + return; + } case Direction::PositiveX: { - if (tile.direction == Direction::NegativeY) { - if (GetTileX() > GetTileY()) { - SetCenterX(tileX + GetTileY()); - SetDirection(tile.direction); - } - } else { // tile.direction = Direction::PositiveY - if (GetTileX() > 1 - GetTileY()) { - SetCenterX(tileX + (1 - GetTileY())); - SetDirection(tile.direction); - } + if (tile.direction == Direction::NegativeY) { + if (GetTileX() > GetTileY()) { + SetCenterX(tileX + GetTileY()); + SetDirection(tile.direction); + } + } else { // tile.direction = Direction::PositiveY + if (GetTileX() > 1 - GetTileY()) { + SetCenterX(tileX + (1 - GetTileY())); + SetDirection(tile.direction); } - return; } + return; + } case Direction::NegativeX: { - if (tile.direction == Direction::PositiveY) { - if (GetTileX() < GetTileY()) { - SetCenterX(tileX + GetTileY()); - SetDirection(tile.direction); - } - } else { // tile.direction = Direction::NegativeY - if (GetTileX() < 1 - GetTileY()) { - SetCenterX(tileX + (1 - GetTileY())); - SetDirection(tile.direction); - } + if (tile.direction == Direction::PositiveY) { + if (GetTileX() < GetTileY()) { + SetCenterX(tileX + GetTileY()); + SetDirection(tile.direction); + } + } else { // tile.direction = Direction::NegativeY + if (GetTileX() < 1 - GetTileY()) { + SetCenterX(tileX + (1 - GetTileY())); + SetDirection(tile.direction); } - return; } + return; + } default: break; @@ -203,6 +203,7 @@ bool Mob::IsTouchingCastle(const TeamCastle& enemyCastle) const { } void Mob::Tick(std::uint64_t delta, World* world) { + m_HitCooldown = std::max(0.0f, m_HitCooldown - static_cast(delta / 1000.0f)); UpdateEffects(delta, world); Move(delta, world); AttackCastle(delta, world); @@ -217,18 +218,18 @@ void Mob::UpdateEffects(std::uint64_t delta, World* world) { m_Effects.erase(m_Effects.begin() + static_cast(i)); switch (effect.type) { case EffectType::Fire: { - m_EffectFireTimer.Reset(); - break; - } + m_EffectFireTimer.Reset(); + break; + } case EffectType::Poison: { - m_EffectPoisonTimer.Reset(); - break; - } + m_EffectPoisonTimer.Reset(); + break; + } case EffectType::Heal: { - m_EffectHealTimer.Reset(); - } + m_EffectHealTimer.Reset(); + } default: break; diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 87c50a7..4ec1db8 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -70,6 +70,7 @@ void Renderer::RenderVAO(const GL::VertexArray& vao) { void Renderer::RenderModel(const Model& model) { m_EntityShader->Start(); m_EntityShader->SetModelPos(model.positon); + m_EntityShader->SetColorEffect(model.color); model.vao->Bind(); glDrawArrays(GL_TRIANGLES, 0, static_cast(model.vao->GetVertexCount())); model.vao->Unbind(); diff --git a/src/render/WorldRenderer.cpp b/src/render/WorldRenderer.cpp index b822fc5..29f8be9 100644 --- a/src/render/WorldRenderer.cpp +++ b/src/render/WorldRenderer.cpp @@ -87,6 +87,7 @@ void WorldRenderer::RenderMobs() const { Renderer::Model model; model.vao = m_MobVao.get(); model.positon = { mob->GetCenterX(), mob->GetCenterY() }; + model.color = mob->HasTakenDamage() ? Vec3f{ 1, 0.5, 0.5 } : Vec3f{ 1, 1, 1 }; m_Renderer->RenderModel(model); } } diff --git a/src/render/shaders/EntityShader.cpp b/src/render/shaders/EntityShader.cpp index 3ebbcea..e4c5c28 100644 --- a/src/render/shaders/EntityShader.cpp +++ b/src/render/shaders/EntityShader.cpp @@ -39,13 +39,16 @@ flat in int pass_color; out vec4 out_color; +uniform vec3 ColorEffect; + void main(void){ float r = float(pass_color >> 24 & 0xFF) / 255.0; float g = float(pass_color >> 16 & 0xFF) / 255.0; float b = float(pass_color >> 8 & 0xFF) / 255.0; float a = float(pass_color & 0xFF) / 255.0; - out_color = vec4(r, g, b, a); + vec3 intermediate_color = vec3(r, g, b) * ColorEffect; + out_color = vec4(intermediate_color, a); } )"; @@ -81,13 +84,16 @@ flat in int pass_color; out vec4 out_color; +uniform vec3 ColorEffect; + void main(void){ float r = float(pass_color >> 24 & 0xFF) / 255.0; float g = float(pass_color >> 16 & 0xFF) / 255.0; float b = float(pass_color >> 8 & 0xFF) / 255.0; - float a = float(pass_color & 0xFF) / 255.0; - out_color = vec4(r, g, b, a); + float a = float(pass_color & 0xFF) / 255.0; + vec3 intermediate_color = vec3(r, g, b) * ColorEffect; + out_color = vec4(intermediate_color, a); } )"; @@ -105,6 +111,7 @@ void EntityShader::GetAllUniformLocation() { m_LocationCam = static_cast(GetUniformLocation("camPos")); m_LocationTranslation = static_cast(GetUniformLocation("translation")); m_LocationViewtype = static_cast(GetUniformLocation("isometricView")); + m_LocationColorEffect = static_cast(GetUniformLocation("ColorEffect")); } void EntityShader::SetCamPos(const Vec2f& camPos) { @@ -122,7 +129,9 @@ void EntityShader::SetModelPos(const Vec2f& modelPos) { void EntityShader::SetIsometricView(float isometric) { LoadFloat(m_LocationViewtype, isometric); } - +void EntityShader::SetColorEffect(const Vec3f& color) { + LoadVector(m_LocationColorEffect, color); +} } // namespace shader } // namespace td \ No newline at end of file