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

Java游戏开发:球与Paddle碰撞时无法切换Y方向问题求助

问题:球与Paddle碰撞检测失效,球直接穿过Paddle

我正在尝试实现球与Paddle碰撞时切换Y方向的功能,但球会直接穿过Paddle,仿佛碰撞检测不存在。我已标记出问题区域的代码,尝试调整过多种限制条件和Y方向设置,但均未解决问题,恳请提供帮助。

我的GamePanel代码:

public class GamePanel extends JPanel implements MouseMotionListener {
    int Playerx;

    int width;
    int height;

    // 球的尺寸
    float radius = 20;
    float diameter = radius * 2;

    // 球的中心坐标
    float X = radius + 25;
    float Y = radius + 10;

    // 移动方向
    float dx = 12;
    float dy = 12;

    GamePanel(){
        setPreferredSize(new Dimension(1440, 900));
        setFocusable(true);
        setBackground(Color.BLACK);
        addMouseMotionListener(this);

        Thread thread = new Thread() {
            public void run() {
                while (true) {

                    width = getWidth();
                    height = getHeight();

                    X = X + dx ;
                    Y = Y + dy;

                    // 左右边界碰撞检测
                    if (X - radius < 0) {
                        dx = -dx;
                        X = radius;
                    } else if (X + radius > width) {
                        dx = -dx;
                        X = width - radius;
                    }

                    // 上下边界碰撞检测
                    if (Y - radius < 0) {
                        dy = -dy;
                        Y = radius;
                    }else if (Y + radius > height) {
                        dy = -dy;
                        Y = height - radius;
                    }

                    // 问题区域:与Paddle的碰撞检测
                    if(X-radius>=Playerx && X-radius <- Playerx + 100 && Y+radius>=800 && Y+radius<=810){
                        dy = -dy;
                        Y = height - radius;
                    }

                    repaint();

                    try {
                        Thread.sleep(25);
                    } catch (InterruptedException ex) {
                    }

                }
            }
        };
        thread.start();
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        g.setColor(Color.WHITE);
        // 绘制Paddle,限制左右移动范围
        if(Playerx<=50 && Playerx>= 0){g.fillOval(10,800,100,10);}
        if(Playerx>50 && Playerx<1390){g.fillOval(Playerx-50,800,100,10);}
        if(Playerx>=1390 && Playerx<1440){g.fillOval(1340,800,100,10);}
        
        // 绘制球
        g.setColor(Color.BLUE);
        g.fillOval((int)(X-radius), (int)(Y-radius), (int)diameter, (int)diameter);
    }

    @Override
    public void mouseDragged(MouseEvent e) {

    }

    @Override
    public void mouseMoved(MouseEvent e) {
        Playerx = e.getX();
        repaint();
    }
}

问题分析与修复方案

1. 碰撞检测条件符号错误

问题区域代码里的X-radius <- Playerx + 100是笔误,这里的-应该是<=,这个错误直接导致X范围的碰撞判断完全失效,球永远满足不了检测条件。

2. 碰撞后位置修正逻辑错误

当前碰撞后把Y设为height - radius,但Paddle的Y坐标是800,正确的碰撞后位置应该是球的底部刚好贴合Paddle顶部,即Y = 800 - radius,否则球会被直接拉到屏幕底部,可能再次触发无效碰撞或穿过Paddle。

3. 碰撞检测顺序错误

你先处理了屏幕上下边界的碰撞(包括屏幕底部),再处理Paddle碰撞。如果球已经碰到屏幕底部,会先触发底部边界逻辑,此时再判断Paddle碰撞就毫无意义。应该先判断Paddle碰撞,再处理屏幕上下边界。

修复后的碰撞检测代码

// 先判断与Paddle的碰撞
// 匹配Paddle实际的X范围(Playerx-50到Playerx+50)
if(X + radius >= Playerx - 50 && X - radius <= Playerx + 50 && Y + radius >= 800 && Y + radius <= 810 && dy > 0){
    dy = -dy;
    Y = 800 - radius; // 将球修正到Paddle顶部,避免重复触发碰撞
}

// 再处理上下边界碰撞
if (Y - radius < 0) {
    dy = -dy;
    Y = radius;
}else if (Y + radius > height) {
    dy = -dy;
    Y = height - radius;
}

额外优化

新增dy > 0的判断,确保只有球向下移动时才触发Paddle碰撞,避免球向上移动时误判碰撞。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 17:20:28