You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Godot 4.4.1中玩家同时触多尖刺仅扣1条生命值的实现方法

解决Godot 4.4.1中玩家同时触碰多个尖刺重复扣血的问题

问题核心是:玩家同时进入多个尖刺的Area2D时,每个尖刺的_on_body_entered事件会在同一帧内触发,导致多次扣血。你之前尝试的无敌机制没生效,大概率是因为无敌状态的设置存在延迟,没来得及阻止同一帧内的其他触发。以下是几个更优的解决方案:

方案1:让玩家统一处理受伤逻辑(推荐)

把扣血和无敌状态的管理从尖刺转移到玩家身上,确保同一帧内无论触发多少次受伤请求,玩家只会响应一次。

玩家脚本(Player.gd)

extends CharacterBody2D

var is_invulnerable := false
const INVULNERABILITY_DURATION := 1.5 # 无敌持续时间,可根据需求调整

func take_damage() -> void:
    if not is_invulnerable:
        # 扣血
        Global.lifes -= 1
        # 立刻开启无敌
        is_invulnerable = true
        # 启动计时器恢复正常状态
        $InvulnerabilityTimer.start()

# 绑定Timer节点的timeout信号
func _on_invulnerability_timer_timeout() -> void:
    is_invulnerable = false

尖刺脚本修改

extends Area2D

func _on_body_entered(body: Node2D) -> void:
    if body.is_in_group("Player"):
        # 调用玩家的受伤函数,由玩家自己判断是否扣血
        body.take_damage()

注意:需要在玩家节点下添加一个Timer节点(命名为InvulnerabilityTimer),将其Wait Time设为INVULNERABILITY_DURATION,并勾选One Shot。

方案2:优化全局无敌状态的触发时机

如果你坚持使用全局状态管理无敌,需要确保扣血后立刻设置无敌状态,阻止同一帧内的其他尖刺触发。

尖刺脚本修改

extends Area2D

func _on_body_entered(body: Node2D) -> void:
    if body.is_in_group("Player") and not Global.immortality:
        Global.lifes -= 1
        # 立刻开启全局无敌,阻止后续触发
        Global.immortality = true
        # 让玩家启动无敌计时器
        body.start_invulnerability()

玩家脚本补充

extends CharacterBody2D

const INVULNERABILITY_DURATION := 1.5

func start_invulnerability() -> void:
    $InvulnerabilityTimer.start()

func _on_invulnerability_timer_timeout() -> void:
    Global.immortality = false

方案3:合并相邻尖刺的碰撞区域(备选)

如果你的尖刺是连续排列的,可以将多个尖刺的Area2D合并为一个,这样无论玩家碰多少个尖刺,只会触发一次_on_body_entered事件。但如果尖刺分散布局,这个方案操作成本较高,仅推荐用于连续尖刺场景。

内容的提问来源于stack exchange,提问作者Charles Dev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 19:53:10