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

Java 2D射击游戏:计算圆沿Y轴至线段的最大投影碰撞距离

2D射击游戏中子弹沿Y轴移动的碰撞距离计算函数

以下是满足需求的Java实现,核心逻辑是先判断子弹与墙体线段的X轴范围是否重叠(无重叠则不会碰撞),再计算Y轴方向的碰撞距离:

核心函数实现

public class BulletCollisionCalculator {

    /**
     * 计算子弹沿Y轴移动的最大距离
     * @param bulletX 子弹中心X坐标
     * @param bulletY 子弹中心Y坐标
     * @param bulletRadius 子弹半径
     * @param lineX1 墙体线段端点1的X坐标
     * @param lineY1 墙体线段端点1的Y坐标
     * @param lineX2 墙体线段端点2的X坐标
     * @param lineY2 墙体线段端点2的Y坐标
     * @return 可移动的Y轴距离:线段在圆上方返回负值,下方返回正值,无碰撞返回POSITIVE_INFINITY,已碰撞返回0
     */
    public static float calculateMaxYDistance(float bulletX, float bulletY, float bulletRadius,
                                             float lineX1, float lineY1, float lineX2, float lineY2) {
        // 计算子弹和线段的X轴范围
        float xBulletMin = bulletX - bulletRadius;
        float xBulletMax = bulletX + bulletRadius;
        float xLineMin = Math.min(lineX1, lineX2);
        float xLineMax = Math.max(lineX1, lineX2);

        // X轴无交集,不会碰撞
        if (xBulletMax < xLineMin || xBulletMin > xLineMax) {
            return Float.POSITIVE_INFINITY;
        }

        // 计算线段在X重叠区域内的Y值范围
        float yLineMin, yLineMax;
        if (lineX1 == lineX2) {
            // 垂直线段
            yLineMin = Math.min(lineY1, lineY2);
            yLineMax = Math.max(lineY1, lineY2);
        } else {
            // 斜线/水平线段,用参数方程计算重叠区域的Y范围
            float slope = (lineY2 - lineY1) / (lineX2 - lineX1);
            float intercept = lineY1 - slope * lineX1;

            float overlapXMin = Math.max(xBulletMin, xLineMin);
            float overlapXMax = Math.min(xBulletMax, xLineMax);

            float yAtMinX = slope * overlapXMin + intercept;
            float yAtMaxX = slope * overlapXMax + intercept;

            yLineMin = Math.min(yAtMinX, yAtMaxX);
            yLineMax = Math.max(yAtMinX, yAtMaxX);
        }

        return calculateDistanceFromYRange(bulletY, bulletRadius, yLineMin, yLineMax);
    }

    /**
     * 根据线段的Y范围计算子弹可移动的距离
     */
    private static float calculateDistanceFromYRange(float bulletY, float bulletRadius,
                                                   float yLineMin, float yLineMax) {
        float circleYMin = bulletY - bulletRadius;
        float circleYMax = bulletY + bulletRadius;

        // 子弹已与线段碰撞
        if (!(circleYMax < yLineMin || circleYMin > yLineMax)) {
            return 0.0f;
        }

        // 线段在圆上方(所有线段点的Y小于圆的最低Y)
        if (yLineMax < circleYMin) {
            return (yLineMax + bulletRadius) - bulletY;
        }

        // 线段在圆下方(所有线段点的Y大于圆的最高Y)
        if (yLineMin > circleYMax) {
            return (yLineMin - bulletRadius) - bulletY;
        }

        // 理论上不会执行到此处
        return Float.POSITIVE_INFINITY;
    }
}

逻辑说明

  • X轴范围判断:只有子弹的X范围与线段的X范围有重叠时,子弹沿Y轴移动才可能碰撞墙体,否则直接返回Float.POSITIVE_INFINITY。
  • Y范围计算:针对垂直线段、斜线/水平线段分别处理,计算出线段在X重叠区域内的Y值区间。
  • 距离计算:
    • 若子弹已与线段重叠,返回0;
    • 线段在圆上方时,返回负距离(对应子弹向上移动的碰撞位置);
    • 线段在圆下方时,返回正距离(对应子弹向下移动的碰撞位置)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 14:25:59