JavaScript忍者吃豆人游戏:水平移动无法累计多个寿司分数
问题分析与修复
你的问题出在移动后的寿司判断位置完全错位啦!咱们拆解一下问题根源,再给出修复方案:
错误到底在哪?
拿左移动的逻辑举例子:
- 你先检查
world[ninjaman.y][ninjaman.x - 1] != 1(确认要移动到的位置不是墙),这步没问题 - 然后执行
ninjaman.x--,忍者已经移动到新位置了 - 但你接下来判断的是
world[ninjaman.y][ninjaman.x - 1] == 2—— 这时候ninjaman.x已经减过1了,等于你在检查忍者当前位置左边的第二个格子,根本不是刚刚移动到的那个寿司格子!
上下移动时你也犯了同样的错误,只是可能你的测试场景刚好蒙混过关(比如移动后的下一个格子碰巧也是寿司),但逻辑本身是完全错误的。
正确的逻辑流程
每个方向的操作都应该遵循这个顺序:
- 先算出忍者要移动到的目标位置
- 检查目标位置是不是墙,是墙就不移动
- 如果不是墙,先看目标位置是不是寿司,是就加分
- 把忍者移动到目标位置
- 把目标位置改成空白(表示寿司被吃掉,不会重复计分)
- 重新绘制游戏界面
修复后的代码
把你的document.onkeydown函数替换成下面的版本:
document.onkeydown = function(e) { let targetX = ninjaman.x; let targetY = ninjaman.y; // 先确定目标位置 if (e.keyCode == 40) { // 向下 targetY = ninjaman.y + 1; } else if (e.keyCode == 38) { // 向上 targetY = ninjaman.y - 1; } else if (e.keyCode == 37) { // 向左 targetX = ninjaman.x - 1; } else if (e.keyCode == 39) { // 向右 targetX = ninjaman.x + 1; } // 检查目标位置是否可移动(不是墙) if (world[targetY][targetX] != 1) { // 吃到寿司就加分 if (world[targetY][targetX] == 2) { ninjaScore += 1; console.log(`当前分数:${ninjaScore}`); // 可选:加日志方便看分数变化 } // 移动忍者到目标位置 ninjaman.x = targetX; ninjaman.y = targetY; // 把目标位置设为空白(吃掉寿司或覆盖位置) world[ninjaman.y][ninjaman.x] = 0; // 重新绘制游戏 drawWorld(); drawNinjaMan(); } }
为什么这样改?
- 先统一计算目标位置,避免重复写相同逻辑,代码更清晰
- 直接检查目标位置的寿司状态,这才是忍者真正要吃到的寿司,不会再出现位置错位
- 移动后把目标位置设为0,确保同一个寿司不会被重复计分
这样修改后,不管上下还是左右移动,只要忍者吃到寿司,分数都会正确累计啦!
内容的提问来源于stack exchange,提问作者Amanda Demetrio
相关产品推荐
相关产品推荐

