add hit "animation"
This commit is contained in:
@@ -89,6 +89,7 @@ private:
|
||||
Direction m_Direction;
|
||||
std::vector<EffectDuration> 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<float>(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<float>(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<float>(static_cast<std::int32_t>(GetCenterX())); } // returns a float between 0 and 1 excluded
|
||||
float GetTileY() { return GetCenterY() - static_cast<float>(static_cast<std::int32_t>(GetCenterY())); } // returns a float between 0 and 1 excluded
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ public:
|
||||
struct Model {
|
||||
GL::VertexArray* vao;
|
||||
Vec2f positon;
|
||||
Vec3f color = { 1, 1, 1 };
|
||||
};
|
||||
private:
|
||||
std::unique_ptr<shader::WorldShader> m_WorldShader;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<float>(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<int>(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;
|
||||
|
||||
@@ -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<GLsizei>(model.vao->GetVertexCount()));
|
||||
model.vao->Unbind();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<unsigned int>(GetUniformLocation("camPos"));
|
||||
m_LocationTranslation = static_cast<unsigned int>(GetUniformLocation("translation"));
|
||||
m_LocationViewtype = static_cast<unsigned int>(GetUniformLocation("isometricView"));
|
||||
m_LocationColorEffect = static_cast<unsigned int>(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
|
||||
Reference in New Issue
Block a user