完成土狼时间与无敌闪烁
This commit is contained in:
@@ -81,6 +81,11 @@ void PlayerComponent::setState(std::unique_ptr<state::PlayerState> new_state) {
|
||||
|
||||
}
|
||||
|
||||
bool PlayerComponent::is_on_ground() const
|
||||
{
|
||||
return coyote_timer_ <= coyote_time_ || physics_component_->hasCollidedBelow();
|
||||
}
|
||||
|
||||
void PlayerComponent::handleInput(engine::core::Context& context) {
|
||||
if (!current_state_) return;
|
||||
|
||||
@@ -93,6 +98,31 @@ void PlayerComponent::handleInput(engine::core::Context& context) {
|
||||
void PlayerComponent::update(float delta_time, engine::core::Context& context) {
|
||||
if (!current_state_) return;
|
||||
|
||||
// 一旦离地,开始计时 Coyote Timer
|
||||
if (!physics_component_->hasCollidedBelow()) {
|
||||
coyote_timer_ += delta_time;
|
||||
} else { // 如果碰撞到地面,重置 Coyote Timer
|
||||
coyote_timer_ = 0.0f;
|
||||
}
|
||||
|
||||
// 如果处于无敌状态,则进行闪烁
|
||||
if (health_component_->isInvincible()) {
|
||||
flash_timer_ += delta_time; // 闪烁计时器增加
|
||||
if (flash_timer_ >= 2 * flash_interval_) {
|
||||
flash_timer_ -= 2 * flash_interval_; // 闪烁计时器在 0~2倍闪烁间隔 中循环
|
||||
}
|
||||
// 一半时间可见,一半时间不可见。
|
||||
if (flash_timer_ < flash_interval_) {
|
||||
sprite_component_->setHidden(true);
|
||||
} else {
|
||||
sprite_component_->setHidden(false);
|
||||
}
|
||||
}
|
||||
// 非无敌状态时确保精灵可见
|
||||
else if (sprite_component_->isHidden()) {
|
||||
sprite_component_->setHidden(false);
|
||||
}
|
||||
|
||||
auto next_state = current_state_->update(delta_time, context);
|
||||
if (next_state) {
|
||||
setState(std::move(next_state));
|
||||
|
||||
@@ -46,6 +46,14 @@ private:
|
||||
// --- 属性相关参数 ---
|
||||
float stunned_duration_ = 0.4f; ///< @brief 玩家被击中后的硬直时间(单位:秒)
|
||||
|
||||
// 土狼时间(Coyote Time): 允许玩家在离地后短暂时间内仍然可以跳跃
|
||||
static constexpr float coyote_time_ = 0.1f; ///< @brief Coyote Time (单位:秒)
|
||||
float coyote_timer_ = 0.0f; ///< @brief Coyote Time 计时器
|
||||
|
||||
// 无敌闪烁时间
|
||||
static constexpr float flash_interval_ = 0.1f; ///< @brief 闪烁间隔时间(单位:秒)
|
||||
float flash_timer_ = 0.0f; ///< @brief 闪烁计时器,用于无敌状态下的闪烁效果
|
||||
|
||||
public:
|
||||
PlayerComponent() = default;
|
||||
~PlayerComponent() override = default;
|
||||
@@ -81,6 +89,7 @@ public:
|
||||
float getStunnedDuration() const { return stunned_duration_; } ///< @brief 获取硬直时间
|
||||
|
||||
void setState(std::unique_ptr<state::PlayerState> new_state); ///< @brief 切换玩家状态
|
||||
bool is_on_ground() const; ///< @brief 检查玩家是否在地面上(考虑了Coyote Time)
|
||||
|
||||
private:
|
||||
// 核心循环函数
|
||||
|
||||
@@ -56,8 +56,8 @@ std::unique_ptr<PlayerState> IdleState::update(float, engine::core::Context&)
|
||||
auto friction_factor = player_component_->getFrictionFactor();
|
||||
physics_component->velocity_.x *= friction_factor;
|
||||
|
||||
// 如果下方没有碰撞,则切换到 FallState
|
||||
if (!physics_component->hasCollidedBelow()) {
|
||||
// 如果离地,则切换到 FallState
|
||||
if (!player_component_->is_on_ground()) {
|
||||
return std::make_unique<FallState>(player_component_);
|
||||
}
|
||||
return nullptr;
|
||||
|
||||
@@ -67,8 +67,8 @@ std::unique_ptr<PlayerState> WalkState::update(float, engine::core::Context&)
|
||||
auto max_speed = player_component_->getMaxSpeed();
|
||||
physics_component->velocity_.x = glm::clamp(physics_component->velocity_.x, -max_speed, max_speed);
|
||||
|
||||
// 如果下方没有碰撞,则切换到 FallState
|
||||
if (!physics_component->hasCollidedBelow()) {
|
||||
// 如果离地,则切换到 FallState
|
||||
if (!player_component_->is_on_ground()) {
|
||||
return std::make_unique<FallState>(player_component_);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user