Java版吃豆人克隆游戏移动碰撞检测功能异常求助
吃豆人碰撞检测问题排查与修复

嘿,我来帮你看看这个吃豆人碰撞检测的问题~你的需求逻辑很清晰,但代码里有几个关键小问题导致功能异常,咱们一步步梳理:
你的代码里的核心问题
vector被循环重复覆盖
你在遍历items的过程中,每一次循环都会修改vector的值,最后循环结束后,vector只会保留最后一个MapItem的判断结果,前面所有的碰撞判断都被覆盖了。比如前几个墙体判断出应该设vector=1,最后一个墙体却把它改成了3,结果完全不符合预期。碰撞条件逻辑不符合需求
你现在判断vector=1的条件是左右两个偏移矩形都和墙体碰撞,这意味着吃豆人被墙左右死死夹住,但你的需求是“水平碰撞时仅能上下移动”——应该是只要左右任意一边碰到墙,就限制只能上下移动才对。同理,vector=2的条件也设置成了上下都碰撞,不符合“垂直碰撞时仅能左右移动”的需求。else分支绑定错误
你的else是和第二个if(判断垂直碰撞的if)绑定的,这意味着只要垂直碰撞不成立,就会直接把vector设为3,哪怕前面已经判断出水平碰撞需要设vector=1,这直接破坏了之前的逻辑。
修复后的代码实现
我们调整一下逻辑:先收集所有碰撞情况,最后统一设置vector,避免覆盖问题,同时修正碰撞条件:
修正后的checkMap()方法
public void checkMap() { int xRaw = pac.getX(); int yRaw = pac.getY(); // 定义吃豆人左右上下偏移的碰撞检测矩形(命名更清晰) Rectangle rectanglePacRight = new Rectangle(xRaw + 1, yRaw, Pac.SIZE, Pac.SIZE); Rectangle rectanglePacLeft = new Rectangle(xRaw - 1, yRaw, Pac.SIZE, Pac.SIZE); Rectangle rectanglePacDown = new Rectangle(xRaw, yRaw + 1, Pac.SIZE, Pac.SIZE); Rectangle rectanglePacUp = new Rectangle(xRaw, yRaw - 1, Pac.SIZE, Pac.SIZE); // 先初始化碰撞状态为无碰撞 boolean hasHorizontalCollision = false; boolean hasVerticalCollision = false; // 遍历所有墙体,收集碰撞情况 for (MapItem item : items) { // 水平方向(左右)任意一边碰撞,标记水平碰撞 if (isPacCollisionWallz(item, rectanglePacRight) || isPacCollisionWallz(item, rectanglePacLeft)) { hasHorizontalCollision = true; } // 垂直方向(上下)任意一边碰撞,标记垂直碰撞 if (isPacCollisionWallz(item, rectanglePacDown) || isPacCollisionWallz(item, rectanglePacUp)) { hasVerticalCollision = true; } } // 根据最终碰撞状态设置vector if (hasHorizontalCollision && !hasVerticalCollision) { // 仅水平方向有碰撞,允许上下移动 vector = 1; } else if (hasVerticalCollision && !hasHorizontalCollision) { // 仅垂直方向有碰撞,允许左右移动 vector = 2; } else if (!hasHorizontalCollision && !hasVerticalCollision) { // 无碰撞,十字路口全向移动 vector = 3; } else { // 特殊情况:水平和垂直都有碰撞(比如被墙包围),可根据需求处理 // 比如保持原移动方向或禁止移动,这里暂时留空你自己调整 // vector = 0; // 示例:禁止移动 } }
保留你的isPacCollisionWallz()方法
这个方法逻辑没问题,直接用就行:
private boolean isPacCollisionWallz(MapItem mapItem, Rectangle rectangle) { return rectangle.intersects(mapItem.getRectangle()); }
修复后的逻辑说明
- 先收集所有墙体的碰撞情况,最后统一设置
vector,不会再出现循环覆盖的问题。 - 碰撞条件改成了任意一边碰撞,完全匹配你的需求:水平方向碰墙就只能上下,垂直方向碰墙就只能左右。
- 处理了所有可能的碰撞组合,避免逻辑漏洞。
内容的提问来源于stack exchange,提问作者Karl Einstein
相关产品推荐
相关产品推荐

