修改伤害传输机制

  • 将之前damaged相关信号传入的伤害值都转为HurtBox
  • 之后触发伤害时按照HurtBox的伤害和方向计算相关数据

玩家受伤功能

  • 引入新的资源文件
  • 为Player添加HitBox
  • 创建stun动画
    • 单独创建一个AnimationPlayer来播放闪烁特效
  • 添加stun节点和脚本
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    class_name StateStun extends State

    @onready var idle: StateIdle = $"../Idle"

    @export var decelerate_speed: float = 10.0
    @export var knockback_speed: float = 200.0
    @export var invulnerable_duration: float = 1.0

    var direction: Vector2
    var hurt_box: HurtBox
    var next_state: State = null

    func _ready() -> void:
    pass

    func init() -> void:
    player.PlayerDamaged.connect(_on_player_damaged)
    pass

    func Enter() -> void:
    player.animation_player.animation_finished.connect(_animation_finished)
    direction = player.global_position.direction_to(hurt_box.global_position)
    player.velocity = direction * -knockback_speed
    player.SetDirection()
    player.UpdateAnimation("stun")
    player.make_invulnerable(invulnerable_duration)
    player.effect_animation_player.play("damaged")
    pass

    func Exit() -> void:
    next_state = null
    player.animation_player.animation_finished.disconnect(_animation_finished)
    pass

    func Process(_delta: float) -> State:
    player.velocity -= player.velocity * decelerate_speed * _delta
    return next_state

    func PhysicsProcess(_delta: float) -> State:
    return null

    func HandleInput(_event: InputEvent) -> State:
    return null

    func _on_player_damaged(_hurt_box: HurtBox) -> void:
    hurt_box = _hurt_box
    stateMachine.ChangeState(self)
    pass

    func _animation_finished(_a: String) -> void:
    next_state = idle
    pass

  • 修改player脚本
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28

    signal PlayerDamaged(hurt_box: HurtBox)

    var hp: int = 6
    var max_hp: int = 6
    var invulnerable: bool = false

    ...

    func _take_damage(hurt_box: HurtBox) -> void:
    if invulnerable:
    return
    update_hp(-hurt_box.damage)
    PlayerDamaged.emit(hurt_box)
    pass

    func update_hp(delta: int) -> void:
    hp = clampi(hp + delta, 0, max_hp)
    pass

    func make_invulnerable(invulnerable_duration: float = 1.0) -> void:
    invulnerable = true
    hit_box.monitoring = false
    await get_tree().create_timer(invulnerable_duration).timeout
    hit_box.monitoring = true
    invulnerable = false
    pass

流程梳理

  • 玩家的HitBox被击中后触发信号,触发HitBox中的damaged方法
  • HitBox的damaged方法触发的damaged信号
  • 玩家监听damaged信号,收到信号后发送PlayerDamaged信号
  • stun脚本监听playerdamaged信号,去进行相应处理
  • hurtbox击中hitbox -> hitbox被击中 -> 玩家被击中 -> 相应状态进行处理