wand-magic-sparkles特效

效果会暂时控制某个实体,用于冲刺、攻击、吃东西动画、过场动画或死亡/重生流程等复杂行为。

效果可用于玩家、NPC 或任何实体。当你需要以下情况时,它们尤其有用:

  • 你在代码中控制的移动(冲刺/击退/翻滚)

  • 在一小段流程中“锁定”玩家输入(进食、复活、过场动画)

  • 一个带时间限制的状态窗口(无敌、减速、眩晕)

  • 与临时状态绑定的 UI(重生倒计时)

主动 vs 被动

All Out 支持两种效果:

  • 主动效果:每个实体同一时间只能有一个。设置新的主动效果会打断当前的主动效果。

  • 被动效果:可同时附加多个(可叠加的增益/减益/状态效果)。

circle-info

主动效果也会被插入到实体的效果列表中,因此它会出现在 effect_iterator 中,就像被动效果一样。

快速上手(一个简单的定时效果)

创建一个继承自 Effect_Base,然后把它附加到实体上。

Apple_Pop_Effect :: class : Effect_Base {
    sprite: Sprite_Renderer;
    start_scale: v2;
    start_pos: v2;

    effect_start :: method() {
        sprite = entity->get_component(Sprite_Renderer);
        start_scale = entity.local_scale;
        start_pos = entity.local_position;
        set_duration(0.4); // 0.4 秒后自动移除
    }

    effect_update :: method(dt: float) {
        t := get_elapsed_time() / 0.4;

        // 先放大,然后缩小到无
        scale_curve: float;
        if t < 0.3 {
            scale_curve = lerp(1.0, 1.3, Ease.out_back(t / 0.3));
        } else {
            scale_curve = lerp(1.3, 0.0, Ease.in_back((t - 0.3) / 0.7));
        }

        entity->set_local_scale(start_scale * scale_curve);

        // 略微向上浮动
        rise := Ease.out_quad(t) * 0.5;
        entity->set_local_position({start_pos.x, start_pos.y + rise});

        // 在接近结尾时淡出
        if sprite != null {
            alpha := 1.0 - Ease.in_quad(max(0.0, (t - 0.5) / 0.5));
            sprite.color.w = alpha;
        }
    }

    effect_end :: method(interrupt: bool) {
        // 完成后清理(或被打断时)
        entity->destroy();
    }
}

将其作为主动效果附加:

效果生命周期

效果基于回调。只实现你需要的部分:

  • effect_start():在效果被附加时调用一次

  • effect_update(dt):每帧调用

  • effect_late_update(dt):在 effect_update

  • 之后每帧调用effect_end(interrupt)

:在效果被移除时调用

使用 set_active_effect 用于应当互斥的效果(冲刺、攻击前摇、死亡流程)。

如果该实体已经有一个主动效果,则它会以以下方式结束: interrupt = true.

被动效果(可叠加的增益 / 状态)

使用 add_passive_effect 用于可叠加的效果(减速、毒、护盾、无敌窗口)。

API 参考

Effect_Base

应用 / 移除效果

检查 / 遍历效果

circle-exclamation

freeze_playerdisable_movement_inputs

  • player_specific.freeze_player = true:完全锁定玩家位置。

  • player_specific.disable_movement_inputs = true:忽略输入,但你的效果仍然可以移动玩家(冲刺/翻滚)。

这两者都只在以下情况生效: player != null (也就是说,该效果所在实体拥有一个 Player 组件)。

效果示例

冲刺 / 翻滚(主动效果)

无敌窗口(被动效果)

使用被动效果来表示无敌状态,并在所有造成伤害的地方检查它。

持续几秒的 2 倍大小(被动效果)

死亡 / 重生流程(带本地 UI 的主动效果)

过场锁定(主动效果)

最佳实践

  • 使用 set_active_effect 当效果在一小段流程中“拥有”该实体时(冲刺/攻击/死亡/过场动画)。

  • 使用 add_passive_effect 用于可叠加状态(增益/减益/状态)。

  • 使用 set_duration(...) 用于定时效果,而不是手动计时器。

  • 始终在 effect_end 中恢复任何被修改的状态(摩擦、缩放、动画触发器等)。

  • 保持 纯属视觉效果 UI/效果本地化(包在 player->is_local()中),并保持游戏状态由服务器权威。

最后更新于