我正在用 Java 制作乒乓球,并希望通过为桨的每个部分分配不同的反射逻辑来使游戏更有趣,如下所示:
(球击中球拍的外缘与击中球拍的中间会产生不同的效果)
桨扩展了 Rectangle2D,所以我可以使用 Rectangle2D 的intersects()
方法来确定球是否接触到它的任何部分......
是否有可能确定球在球拍上的确切位置?
我打算做的是,
- 基于此计算入射角和反射角...
- 如果球击中球拍上的 x 点……我将相应地改变反射角
谢谢
是否有可能确定球在球拍上的确切位置?
如果是我,我会抓住球和桨的当前坐标。对于球拍,您可以获得两组 y 坐标,用于描述面向球的线。IE:
int paddleY1 = paddle.y;
int paddleY2 = paddle.y + paddle.width;
// assuming the paddle can only go up and down, y is the only co-ordinate that matters.
然后,您可以将桨的中点计算为:
int paddleYMid = (paddleY1 + paddleY2) / 2;
您可以通过比较 y 坐标来确定球是否击中了球拍的左侧或右侧。IE:
if(ball.y > paddleYMid)
{
// Right side of the paddle.
}
else
{
// Left side of the paddle.
}
然后由您来开发进一步的细化。
由于桨总是垂直的(平行于 Y 轴),球和桨的碰撞点将发生在与球中心相同的 y 坐标上。那是:
if (ball.centerX - ball.radius <= paddle.rightX && ball.velocityX < 0)
{
// collision point, if any, is at (ball.centerX - ball.radius, ball.centerY)
if (ball.centerY >= paddle.bottomY && ball.centerY <= paddle.topY)
{
// handle collision
}
}
至于碰撞本身的处理,您可能不必处理反射角等,而只需处理 x 和 y 速度的原始值。例如,要模拟完美的弹性碰撞,只需执行以下操作:
ball.velocityX = -ball.velocityX;
并且考虑到球以更高或更低的角度反射,您可以根据桨中心的碰撞位置缩放 y 速度,例如。
ball.velocityY += SCALE_CONSTANT * (ball.centerY - ((paddle.topY + paddle.bottomY) / 2));
要找到球击中球拍的确切位置,您可以将问题表述为线相交问题。桨叶可以表示为桨叶 x 坐标处的垂直线(如果需要,+ 厚度,并根据球的直径进行校正)。然后可以将球表示为沿着其运动矢量的一条线(这条线可以简单地由它的当前位置和它的下一个位置定义,如果它要不受阻碍地移动)。
现在可以使用线交点算法解决该问题。
由于桨是一条垂直线,方程可以简化为只回答 Y 将通过桨的 X 的问题。这也是线剪遇到和解决的常见问题:http ://en.wikipedia.org /wiki/Line_clipping(交叉点也可以直接计算,但我找不到公式atm)。