因为最近在做帧同步方面的内容,所以发现了这个问题。
方案1:用Area2d进行碰撞检测,绑定body_entered信号。
缺陷:
Area2d的碰撞检测只会每个物理迭代中只会执行一次,即在physics_process()结束后执行一次。
场景:
玩家经过3次move_and_slide()后,会与怪物发生碰撞,触发Area2d的body_enter信号,并进行后续处理(如无敌时间)。
如果我在physics_process()中执行1行move_and_slide(),那么在3个物理迭代后,检测到碰撞。
如果我在physics_process()中执行2行move_and_slide(),那么在2个物理迭代后,检测到碰撞。
可以发现,后面一种情况,多执行了一次move_and_slide()。如果是单机游戏,这并没有太大影响;但在基于帧同步的多人游戏中,这就造成了不一致现象。
方案2:用raycast2d进行碰撞检测
这是最佳方案,Raycast2d 相比 Ared2d 更加轻量级,且可以手动刷新“碰撞检测”。满足“实时性”。
"""检测碰撞"""
func collision_detect():
$"ShapeCast2D".force_shapecast_update() # 手动刷新碰撞
for item in $"../ShapeCast2D".collision_result:
var inst = instance_from_id(item["collider_id"])
if inst.is_in_group("monster"):
print("碰到了怪物")
# 执行操作
pass
return
"""物理"""
func _physics_process():
chara.velocity.x=100 # 水平速度
chara.move_and_slide()
collision_detect() # 检测碰撞
chara.move_and_slide()
collision_detect() # 检测碰撞
return