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

Java版吃豆人克隆游戏移动碰撞检测功能异常求助

吃豆人碰撞检测问题排查与修复

PacMan

嘿,我来帮你看看这个吃豆人碰撞检测的问题~你的需求逻辑很清晰,但代码里有几个关键小问题导致功能异常,咱们一步步梳理:

你的代码里的核心问题

  1. vector被循环重复覆盖
    你在遍历items的过程中,每一次循环都会修改vector的值,最后循环结束后,vector只会保留最后一个MapItem的判断结果,前面所有的碰撞判断都被覆盖了。比如前几个墙体判断出应该设vector=1,最后一个墙体却把它改成了3,结果完全不符合预期。

  2. 碰撞条件逻辑不符合需求
    你现在判断vector=1的条件是左右两个偏移矩形都和墙体碰撞,这意味着吃豆人被墙左右死死夹住,但你的需求是“水平碰撞时仅能上下移动”——应该是只要左右任意一边碰到墙,就限制只能上下移动才对。同理,vector=2的条件也设置成了上下都碰撞,不符合“垂直碰撞时仅能左右移动”的需求。

  3. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 06:43:19