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

Java游戏开发中如何避免Beat判定的坐标区间重叠问题?

问题根源

  • 原hit()方法遍历了整个beatArr数组,所有落在判定区间的节拍都会触发计分逻辑,才会出现单次按键多次输出的问题
  • 你之前用counter的写法出错是因为保留了遍历数组的for循环,同一个节拍被判定了51次,才会连续加51次分

可行解决方案

方案1:优先判定离判定线最近的节拍(推荐,容错更高)

第一步先给Beat类新增判定标记,避免重复判定同一个节拍:

public class Beat {
    // 原有属性不变
    private boolean isJudged = false; // 新增:标记是否已经被判定过
    // 新增对应get/set方法
    public boolean isJudged() { return isJudged; }
    public void setJudged(boolean judged) { isJudged = judged; }
}

修改hit()方法如下:

public static void hit(){
    // 先筛选有效区间内、未被判定、离x=200判定线最近的节拍
    Beat targetBeat = null;
    int minDistance = Integer.MAX_VALUE;
    for (Beat beat : Game.beatArr) {
        if (beat.isJudged()) continue; // 跳过已经判定过的节拍
        int x = beat.getX();
        // 只处理在可判定范围内的节拍
        if (x < 0 || x > 250) continue;
        int distance = Math.abs(x - 200);
        if (distance < minDistance) {
            minDistance = distance;
            targetBeat = beat;
        }
    }
    // 没有找到符合条件的节拍直接判定Miss
    if (targetBeat == null) {
        score -=50;
        System.out.println("Miss " + score);
        return;
    }
    // 仅对找到的目标节拍做判定
    int x = targetBeat.getX();
    if (x <= 220 && x >=150){
        score+=100;
        System.out.println("Perfect+ "+score);
    } else if (x <= 250 && x >=100) {
        score += 100;
        System.out.println("Good "+score);
    } else {
        score -=50;
        System.out.println("Miss " + score);
    }
    // 标记该节拍已被判定,后续不会再触发判定
    targetBeat.setJudged(true);
}

方案2:用counter按生成顺序判定(适合固定顺序的谱面)

如果你的节拍是严格按生成顺序先后到达判定线的,可以用counter的写法,不需要遍历数组:
首先全局定义计数器:

public static int counter = 0;

修改hit()方法如下:

public static void hit(){
    // 先跳过已经完全错过判定区间的漏判节拍
    while (counter < beatArr.length && beatArr[counter].getX() < 0) {
        counter++;
    }
    // 所有节拍都已判定完直接返回
    if (counter >= beatArr.length) {
        return;
    }
    Beat currentBeat = beatArr[counter];
    int x = currentBeat.getX();
    if (x <= 220 && x >=150){
        score+=100;
        System.out.println("Perfect+ "+score);
        counter++; // 判定成功后跳到下一个节拍
    } else if (x <= 250 && x >=100) {
        score += 100;
        System.out.println("Good "+score);
        counter++; // 判定成功后跳到下一个节拍
    } else {
        score -=50;
        System.out.println("Miss " + score);
        // 如果当前节拍已经完全离开可判定区间,也跳到下一个
        if (x < 100) {
            counter++;
        }
    }
}

补充优化提示

你原有判定条件里的|是按位或运算符,建议替换成逻辑或||,可以避免不必要的后续判断运算。

内容的提问来源于stack exchange,提问作者SourOddity

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 16:27:04