我遇到了一个很傻的平台游戏bug,花了我更长的时间来找出它。
游戏背景:https://games.xgallery.online/forest-quest/
玩家可以踩死一个蘑菇敌人,弹起来,并且在弹起来后立即受到伤害。从玩家视角看起来像是:“我落地在上面,为什么我受伤了?”
第一版的代码检查玩家是否刚刚踩踏敌人,通过比较垂直速度来实现。
错误的代码行:
const alreadyStomped = player.velocity.y === PLAYER_CFG.stompImpulse
看起来的逻辑是合理的。当玩家踩踏时,我设置:
player.velocity.y = PLAYER_CFG.stompImpulse
在我的游戏中,这个值是8。
问题出在重力上。
刚刚踩踏后,玩家更新会运行这个代码行:
this.velocity.y -= cfg.gravity * dt
当重力为25和dt约为0.016时,速度从8变为大约7.6。所以相等检查几乎从来都不会生效,保护玩家免受下一个重叠检查的伤害。
修复的方法不是问物理状态一个它不能可靠回答的问题。所以我添加了一个小计时器:
playerStompTimer = 0.15
然后敌人伤害检查会跳过伤害检查直到计时器大于零。它足够长来覆盖2或3个帧的重叠框架,但足够短以防止玩家通过敌人。
蘑菇模型是用Meshy生成的,但视觉资产与bug完全无关。碰撞框、重力顺序和帧时间是整个故事。
这是那些看起来很明显的bug之一,直到你记得游戏循环不是截图。每个系统都有自己的 turno,并且一个 turno就足够改变真相。
评论 (0)