From 18e9491dbc8d874577efea482377afcd59341591 Mon Sep 17 00:00:00 2001 From: Bilal Kahraman Date: Wed, 27 Nov 2024 21:16:33 +0300 Subject: [PATCH] Update enemy states and use shooting logic --- src/State/CMakeLists.txt | 3 + src/State/include/State/enemy_state.h | 42 +++---- src/State/src/enemy_state.cpp | 172 +++++++++++++++----------- src/State/src/weapon_state.cpp | 2 + src/Strike/include/Strike/weapon.h | 9 ++ 5 files changed, 134 insertions(+), 94 deletions(-) diff --git a/src/State/CMakeLists.txt b/src/State/CMakeLists.txt index 57f6095..f949441 100644 --- a/src/State/CMakeLists.txt +++ b/src/State/CMakeLists.txt @@ -12,6 +12,8 @@ target_link_libraries( enemy_state PUBLIC character + animation + navigation_manager texture_manager ) @@ -30,4 +32,5 @@ target_link_libraries( PUBLIC weapon texture_manager + shooting_manager ) \ No newline at end of file diff --git a/src/State/include/State/enemy_state.h b/src/State/include/State/enemy_state.h index e0c5677..7e5f1f1 100644 --- a/src/State/include/State/enemy_state.h +++ b/src/State/include/State/enemy_state.h @@ -12,15 +12,13 @@ #ifndef STATE_INCLUDE_STATE_ENEMY_STATE_H_ #define STATE_INCLUDE_STATE_ENEMY_STATE_H_ +#include "Animation/time_based_single_animation.h" #include "State/state.h" +#include #include namespace wolfenstein { -namespace { -constexpr double kIdlePatrolDistance = 0.5; -} // namespace - class Enemy; template <> @@ -52,12 +50,9 @@ class IdleState : public EnemyState EnemyStateType GetType() const override; private: - int current_frame; - double counter; - double interval; double animation_speed_; - double patrol_distance{0.25}; - std::vector textures; + double range_; + std::unique_ptr animation_; }; // ########################################### WalkState ########################################### @@ -74,11 +69,14 @@ class WalkState : public EnemyState EnemyStateType GetType() const override; private: - int current_frame; - double counter; - double interval; double animation_speed_; - std::vector textures; + double range_max_; + double range_min_; + double attack_range_; + double attack_rate_; + double attack_counter_; + bool is_attacked_; + std::unique_ptr animation_; }; // ########################################### AttackState ########################################### @@ -95,11 +93,9 @@ class AttackState : public EnemyState EnemyStateType GetType() const override; private: - int current_frame; - double counter; - double interval; double animation_speed_; - std::vector textures; + double attack_counter_; + std::unique_ptr animation_; }; // ########################################### PainState ########################################### @@ -116,11 +112,9 @@ class PainState : public EnemyState EnemyStateType GetType() const override; private: - int current_frame; - double counter; - double interval; double animation_speed_; - std::vector textures; + double counter; + std::unique_ptr animation_; }; // ########################################### DeathState ########################################### @@ -137,11 +131,9 @@ class DeathState : public EnemyState EnemyStateType GetType() const override; private: - int current_frame; - double counter; - double interval; double animation_speed_; - std::vector textures; + double counter; + std::unique_ptr animation_; }; } // namespace wolfenstein diff --git a/src/State/src/enemy_state.cpp b/src/State/src/enemy_state.cpp index 2392ec6..835fdaa 100644 --- a/src/State/src/enemy_state.cpp +++ b/src/State/src/enemy_state.cpp @@ -1,39 +1,43 @@ #include "State/enemy_state.h" #include "Characters/enemy.h" +#include "NavigationManager/navigation_manager.h" +#include "ShootingManager/shooting_manager.h" #include "TextureManager/texture_manager.h" namespace wolfenstein { // ########################################### IdleState ########################################### -IdleState::IdleState() : current_frame(0), counter(0), interval(0) {} +IdleState::IdleState() {} IdleState::~IdleState() {} void IdleState::Update(const double& delta_time) { - counter += delta_time; - if (counter > animation_speed_) { - current_frame = (current_frame + 1) % textures.size(); - counter = 0; + animation_->Update(delta_time); + + if (context_->IsPlayerInShootingRange()) { + context_->TransitionTo(std::make_shared()); + } + if (context_->IsAttacked()) { + context_->TransitionTo(std::make_shared()); } - interval += delta_time; - // if (interval > 5) { - // context_->TransitionTo(std::make_shared()); - // } } void IdleState::Reset() { - current_frame = 0; - counter = 0; + animation_->Reset(); } void IdleState::OnContextSet() { - animation_speed_ = 0.3; - textures = TextureManager::GetInstance().GetTextureCollection( - context_->GetBotName() + "_idle"); + const auto config = context_->GetStateConfig(); + animation_speed_ = config.animation_time.idle_animation_speed; + range_ = config.follow_range_max; + animation_ = std::make_unique( + TextureManager::GetInstance().GetTextureCollection( + context_->GetBotName() + "_idle"), + animation_speed_); } int IdleState::GetCurrentFrame() const { - return textures[current_frame]; + return animation_->GetCurrentFrame(); } EnemyStateType IdleState::GetType() const { @@ -41,35 +45,68 @@ EnemyStateType IdleState::GetType() const { } // ########################################### WalkState ########################################### -WalkState::WalkState() : current_frame(0), counter(0), interval(0) {} +WalkState::WalkState() + : animation_speed_(1.2), + range_max_(5.0), + range_min_(1.5), + attack_range_(5.0), + attack_rate_(1.0), + attack_counter_(0.0), + is_attacked_(false) {} WalkState::~WalkState() {} void WalkState::Update(const double& delta_time) { - counter += delta_time; - if (counter > animation_speed_) { - current_frame = (current_frame + 1) % textures.size(); - counter = 0; + const auto bot_position = context_->GetPosition(); + const auto distance = + NavigationManager::GetInstance().EuclideanDistanceToPlayer( + bot_position); + if (context_->IsAttacked()) { + NavigationManager::GetInstance().ResetPath(context_->GetId()); + context_->SetNextPose(bot_position.pose); + context_->TransitionTo(std::make_shared()); + return; + } + if (!context_->IsPlayerInShootingRange()) { + if (distance > range_max_) { + NavigationManager::GetInstance().ResetPath(context_->GetId()); + context_->TransitionTo(std::make_shared()); + return; + } } - interval += delta_time; - if (interval > 5) { - context_->TransitionTo(std::make_shared()); + if (distance <= attack_range_ && context_->IsPlayerInShootingRange()) { + attack_counter_ += delta_time; + if (attack_counter_ > attack_rate_) { + context_->SetNextPose(bot_position.pose); + context_->TransitionTo(std::make_shared()); + return; + } } + if ((!context_->IsPlayerInShootingRange()) || + ((distance > range_min_) && context_->IsPlayerInShootingRange())) { + auto next_position = NavigationManager::GetInstance().FindPathToPlayer( + bot_position, context_->GetId()); + context_->SetNextPose(next_position); + } + else { + NavigationManager::GetInstance().ResetPath(context_->GetId()); + context_->SetNextPose(bot_position.pose); + } + + animation_->Update(delta_time); } void WalkState::Reset() { - current_frame = 0; - counter = 0; + animation_->Reset(); } void WalkState::OnContextSet() { - animation_speed_ = 0.3; - textures = TextureManager::GetInstance().GetTextureCollection( - context_->GetBotName() + "_walk"); + animation_ = std::make_unique( + context_->GetBotName() + "_walk", animation_speed_); } int WalkState::GetCurrentFrame() const { - return textures[current_frame]; + return animation_->GetCurrentFrame(); } EnemyStateType WalkState::GetType() const { @@ -77,35 +114,37 @@ EnemyStateType WalkState::GetType() const { } // ########################################### AttackState ########################################### -AttackState::AttackState() : current_frame(0), counter(0), interval(0) {} +AttackState::AttackState() : animation_speed_(0.5), attack_counter_(0.0) {} AttackState::~AttackState() {} void AttackState::Update(const double& delta_time) { - counter += delta_time; - if (counter > animation_speed_) { - current_frame = (current_frame + 1) % textures.size(); - counter = 0; + animation_->Update(delta_time); + if (attack_counter_ == 0.0) { + ShootingManager::GetInstance().EnemyShoot(); } - interval += delta_time; - if (interval > 5) { + if (context_->IsAttacked()) { context_->TransitionTo(std::make_shared()); + return; } + if (attack_counter_ > animation_speed_) { + context_->TransitionTo(std::make_shared()); + return; + } + attack_counter_ += delta_time; } void AttackState::Reset() { - current_frame = 0; - counter = 0; + animation_->Reset(); } void AttackState::OnContextSet() { - animation_speed_ = 0.3; - textures = TextureManager::GetInstance().GetTextureCollection( - context_->GetBotName() + "_attack"); + animation_ = std::make_unique( + context_->GetBotName() + "_attack", animation_speed_); } int AttackState::GetCurrentFrame() const { - return textures[current_frame]; + return animation_->GetCurrentFrame(); } EnemyStateType AttackState::GetType() const { @@ -113,35 +152,34 @@ EnemyStateType AttackState::GetType() const { } // ########################################### PainState ########################################### -PainState::PainState() : current_frame(0), counter(0), interval(0) {} +PainState::PainState() : animation_speed_(0.25), counter(0.0) {} PainState::~PainState() {} void PainState::Update(const double& delta_time) { + animation_->Update(delta_time); counter += delta_time; if (counter > animation_speed_) { - current_frame = (current_frame + 1) % textures.size(); - counter = 0; - } - interval += delta_time; - if (interval > 5) { - context_->TransitionTo(std::make_shared()); + if (context_->GetHealth() <= 0) { + context_->TransitionTo(std::make_shared()); + return; + } + context_->SetAttacked(false); + context_->TransitionTo(std::make_shared()); } } void PainState::Reset() { - current_frame = 0; - counter = 0; + animation_->Reset(); } void PainState::OnContextSet() { - animation_speed_ = 0.3; - textures = TextureManager::GetInstance().GetTextureCollection( - context_->GetBotName() + "_pain"); + animation_ = std::make_unique( + context_->GetBotName() + "_pain", animation_speed_); } int PainState::GetCurrentFrame() const { - return textures[current_frame]; + return animation_->GetCurrentFrame(); } EnemyStateType PainState::GetType() const { @@ -149,35 +187,31 @@ EnemyStateType PainState::GetType() const { } // ########################################### DeathState ########################################### -DeathState::DeathState() : current_frame(0), counter(0), interval(0) {} +DeathState::DeathState() : animation_speed_(1.0) {} DeathState::~DeathState() {} void DeathState::Update(const double& delta_time) { - counter += delta_time; - if (counter > animation_speed_) { - current_frame = (current_frame + 1) % textures.size(); - counter = 0; + if (!animation_->IsAnimationFinishedOnce()) { + animation_->Update(delta_time); + counter += delta_time; } - interval += delta_time; - if (interval > 5) { - context_->TransitionTo(std::make_shared()); + else { + context_->SetDeath(); } } void DeathState::Reset() { - current_frame = 0; - counter = 0; + animation_->Reset(); } void DeathState::OnContextSet() { - animation_speed_ = 0.3; - textures = TextureManager::GetInstance().GetTextureCollection( - context_->GetBotName() + "_death"); + animation_ = std::make_unique( + context_->GetBotName() + "_death", animation_speed_); } int DeathState::GetCurrentFrame() const { - return textures[current_frame]; + return animation_->GetCurrentFrame(); } EnemyStateType DeathState::GetType() const { diff --git a/src/State/src/weapon_state.cpp b/src/State/src/weapon_state.cpp index a974af5..cfa015e 100644 --- a/src/State/src/weapon_state.cpp +++ b/src/State/src/weapon_state.cpp @@ -3,6 +3,7 @@ #include "State/state.h" #include "Strike/weapon.h" #include +#include "ShootingManager/shooting_manager.h" namespace wolfenstein { @@ -53,6 +54,7 @@ void LoadedState::PullTrigger() { trigger_pulled_ = true; trigger_pull_time_ = 0; context_->DecreaseAmmo(); + ShootingManager::GetInstance().PlayerShoot(); } // ########################################### OutOfAmmoState ########################################### diff --git a/src/Strike/include/Strike/weapon.h b/src/Strike/include/Strike/weapon.h index 4721903..6698ab5 100644 --- a/src/Strike/include/Strike/weapon.h +++ b/src/Strike/include/Strike/weapon.h @@ -20,6 +20,15 @@ namespace wolfenstein { struct WeaponConfig { + WeaponConfig(std::string weapon_name, size_t ammo_capacity, + double attack_damage, double attack_range, double attack_speed, + double reload_speed) + : weapon_name(weapon_name), + ammo_capacity(ammo_capacity), + attack_damage(attack_damage), + attack_range(attack_range), + attack_speed(attack_speed), + reload_speed(reload_speed) {} std::string weapon_name; size_t ammo_capacity; double attack_damage;