Add simple player STM

This commit is contained in:
tovjemam 2025-09-09 01:00:51 +02:00
parent a20766e335
commit 0b82d1b428
3 changed files with 113 additions and 2 deletions

View File

@ -30,6 +30,7 @@ namespace assets
size_t GetNumFrames() const { return num_frames_; }
float GetTPS() const { return tps_; }
float GetDuration() const { return static_cast<float>(num_frames_) / tps_; }
size_t GetNumChannels() const { return channels_.size(); }
const AnimationChannel& GetChannel(int index) const { return channels_[index]; }

View File

@ -19,8 +19,6 @@ game::Player::Player(World* world, size_t sector_idx, const glm::vec3& position)
world->GetTimePtr()
);
vm_hands_.PlayAnim("knife_idle");
light_trace_offset_ = glm::vec3(0.0f, 0.0f, 0.6f);
}
@ -40,6 +38,8 @@ void game::Player::Update(float dt)
{
time_ += dt;
UpdateState();
vm_node_.UpdateMatrix();
vm_hands_.Update();
@ -195,3 +195,89 @@ glm::vec2 game::Player::GetBobbingOffset(float t, float amplitude)
return offset;
}
//// STATE MACHINE
struct PlayerStateTableEntry
{
void (game::Player::*enter)();
int (game::Player::*update)();
void (game::Player::*exit)();
};
void game::Player::UpdateState()
{
static const PlayerStateTableEntry state_table[] =
{
// enter update exit
{ nullptr, &game::Player::Update_Init, nullptr }, // PS_INIT
{ &game::Player::Enter_Idle, &game::Player::Update_Idle, nullptr }, // PS_IDLE
{ &game::Player::Enter_Attack, &game::Player::Update_Attack, nullptr }, // PS_ATTACK
};
int new_state = -1;
do
{
int new_state = (this->*state_table[state_].update)();
if (new_state >= 0)
{
if (auto exit_fun = state_table[state_].exit)
(this->*exit_fun)();
state_ = static_cast<PlayerState>(new_state);
if (auto enter_fun = state_table[state_].enter)
(this->*enter_fun)();
}
}
while (new_state >= 0);
}
// INIT
int game::Player::Update_Init()
{
return PS_IDLE;
}
// IDLE
void game::Player::Enter_Idle()
{
vm_hands_.PlayAnim("knife_idle", ANIM_LOOP);
}
int game::Player::Update_Idle()
{
if (input_ & PI_ATTACK)
{
return PS_ATTACK;
}
return -1;
}
// ATTACK
void game::Player::Enter_Attack()
{
if (rand() % 2 == 0)
{
vm_hands_.PlayAnim("knife_attack1");
}
else
{
vm_hands_.PlayAnim("knife_attack2");
}
}
int game::Player::Update_Attack()
{
if (vm_hands_.AnimDone())
{
return PS_IDLE;
}
return -1;
}

View File

@ -6,6 +6,13 @@
namespace game
{
enum PlayerState
{
PS_INIT,
PS_IDLE,
PS_ATTACK,
};
class Player : public Entity
{
using Super = Entity;
@ -32,6 +39,8 @@ namespace game
TransformNode vm_node_; // Affected by bobbing
MeshInstance vm_hands_;
std::unique_ptr<MeshInstance> vm_weapon_; // Can be null
PlayerState state_ = PS_INIT;
public:
Player(World* world, size_t sector_idx, const glm::vec3& position);
@ -51,6 +60,21 @@ namespace game
private:
static glm::vec2 GetBobbingOffset(float t, float amplitude);
// STATE MACHINE
void UpdateState();
//void Enter_Init();
int Update_Init();
//void Exit_Init();
void Enter_Idle();
int Update_Idle();
//void Exit_Idle();
void Enter_Attack();
int Update_Attack();
//void Exit_Attack();
};