Android Studio线段交点检测:Pong游戏球与Paddle碰撞问题
Pong游戏球与Paddle的线段交点计算方案
1. 明确两条关键线段的参数
不用纠结Path,直接把碰撞涉及的两条线段参数明确:
- 球的运动线段:起点是上一帧位置
(oldBallX, oldBallY),终点是当前帧位置(ballX, ballY),对应线段参数就是x1=oldBallX, y1=oldBallY, x2=ballX, y2=ballY。 - Paddle的碰撞线段:默认Pong的Paddle是水平矩形,碰撞边取面向球的那条边(比如上方边)。假设Paddle位置由
paddleLeft(左x坐标)、paddleRight(右x坐标)、paddleTopY(上边缘y坐标)确定,这条碰撞线段的参数就是x1=paddleLeft, y1=paddleTopY, x2=paddleRight, y2=paddleTopY。如果是垂直Paddle,就取左右边缘的垂直线段。
2. 线段交点的计算逻辑
用参数方程法计算,以水平Paddle为例:
- 先判断球的运动轨迹是否跨越Paddle的碰撞边:如果
(oldBallY - paddleTopY)和(ballY - paddleTopY)同号,说明球没有穿过这条边,直接跳过碰撞判断。 - 计算参数
t:t = (paddleTopY - oldBallY) / (ballY - oldBallY),这个t表示交点在球运动线段上的位置(范围0-1)。 - 代入球的运动方程得交点x坐标:
intersectX = oldBallX + t*(ballX - oldBallX),y坐标就是paddleTopY。 - 验证有效性:确保
intersectX在[paddleLeft, paddleRight]之间,且t在[0,1]之间,这样才是真正的线段交点。
3. 代码示例(Java)
// 初始化参数 float oldBallX = ...; // 上一帧球的X坐标 float oldBallY = ...; // 上一帧球的Y坐标 float ballX = ...; // 当前帧球的X坐标 float ballY = ...; // 当前帧球的Y坐标 float paddleLeft = ...; // Paddle左边缘X float paddleRight = ...; // Paddle右边缘X float paddleTopY = ...; // Paddle碰撞边Y(如上边缘) float intersectX = 0; float intersectY = paddleTopY; boolean hasCollision = false; // 检查球是否跨越Paddle的碰撞边 if ((oldBallY - paddleTopY) * (ballY - paddleTopY) < 0) { float t = (paddleTopY - oldBallY) / (ballY - oldBallY); intersectX = oldBallX + t * (ballX - oldBallX); // 验证交点是否在两条线段的有效范围内 if (intersectX >= paddleLeft && intersectX <= paddleRight && t >= 0 && t <= 1) { hasCollision = true; } } if (hasCollision) { // 处理反弹逻辑:根据intersectX在Paddle上的位置调整反弹角度 float hitRatio = (intersectX - paddleLeft) / (paddleRight - paddleLeft); // hitRatio为0是左边缘,0.5是中心,1是右边缘,对应不同的反弹方向 }
4. 垂直Paddle适配
如果是垂直Paddle(左右移动),只需调整碰撞线段和判断逻辑:
- 碰撞线段参数为
x1=paddleLeftX, y1=paddleTop, x2=paddleLeftX, y2=paddleBottom - 先判断球的X坐标是否跨越
paddleLeftX,再计算参数t得到交点Y,最后验证Y是否在Paddle的上下范围内。
内容的提问来源于stack exchange,提问作者DoUbT
相关产品推荐
相关产品推荐

