盒子碰撞检测和弹跳

发布于 2024-10-09 20:01:34 字数 1002 浏览 0 评论 0原文

我正在制作乒乓球,并且发现编写一个将球正确地从四堵墙上弹开的算法真的很困难(稍后我将处理得分问题,因为只有西边和东边的一部分会进球)。所以现在我想让球在盒子周围弹跳。

检测球是否撞到墙壁很容易,但我在计算新角度时遇到困难。

这就是我到目前为止所想到的:

        if(dstY == 0) {
            // North wall
            if(angle < 90) {
                newAngle = angle + 90;
            } else {
                newAngle = angle - 90;
            }
        } else if(dstX == maxWidth) {
            // East wall
            if(angle < 90) {
                newAngle = angle + 270;
            } else {
                newAngle = angle + 90;
            }
        } else if(dstY == maxHeight) {
            // South wall
            newAngle = angle + 90;
        } else if(dstX == 1) {
            // West wall
            if(angle < 270) {
                newAngle = angle - 90;
            } else {
                newAngle = angle - 270;
            }
        }

这只适用于大约一半的碰撞,而且看起来非常难看。我确信这应该非常简单,而且之前已经做过很多次了。

在我的代码中,dstX/dstY 是 X/Y 目标坐标。 X=0 和 y=0 位于左上角。

I'm making pong, and am finding it really difficult to write an algorithm that bounces the ball off the four walls properly (I will deal with scoring later on, because only part of the West+East sides will be goals). So at the moment I want the ball to bounce around the box.

Detecting whether the ball has hit a wall is easy, but I'm having trouble calculating the new angle.

This is what I've come up with so far:

        if(dstY == 0) {
            // North wall
            if(angle < 90) {
                newAngle = angle + 90;
            } else {
                newAngle = angle - 90;
            }
        } else if(dstX == maxWidth) {
            // East wall
            if(angle < 90) {
                newAngle = angle + 270;
            } else {
                newAngle = angle + 90;
            }
        } else if(dstY == maxHeight) {
            // South wall
            newAngle = angle + 90;
        } else if(dstX == 1) {
            // West wall
            if(angle < 270) {
                newAngle = angle - 90;
            } else {
                newAngle = angle - 270;
            }
        }

That only works for about half of the collisions, and looks really ugly. I'm sure this should be really simple and that it's been done many times before.

In my code, dstX/dstY are the X/Y destination coordinates. X=0 and y=0 at the top left.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

擦肩而过的背影 2024-10-16 20:01:34

您可以通过两种方式来看待这个问题:

角度:如果您知道球碰撞的角度,只需执行 180 度角即可找到新角度。

渐变:可能更简单。您必须每 t 毫秒以特定的 dY 和 dX 移动球。所以如果你碰壁了,你可以简单地使用 dY 和 dX 的反转符号。例如,如果你撞到了右边的墙,dX 会变成 -dX,而 dY 会继续前进。

You can look at this in 2 ways:

Angles: If you know the angle the ball is colliding at, just perform 180 - angle to find the new angle.

Gradient: Probably simpler. You must be moving the ball at a certain dY and dX every t milliseconds. so if you hit the wall you can simply play with inverting signs of dY and dX. For example if you hit the right wall, dX becomes -dX while dY continues on its course.

枕花眠 2024-10-16 20:01:34

在此 KineticModel 中,方法collideWalls() 使用二维向量运算来简化模拟颗粒与平坦表面之间的弹性碰撞。

In this KineticModel, the method collideWalls() uses two-dimensional vector arithmetic to simplify the simulation of an elastic collision between a particle and a flat surface.

時窥 2024-10-16 20:01:34

关于使用 jbx 梯度方法的智慧之言。如果球击中盒子的角落附近,则 dx 会反转,dy 可以将球放置在顶部边界上方。

A word of wisdom about using jbx's gradient method. If the ball hits near the corners of the box, while dx will be inverted, dy can place the ball above the top boundary.

黯然#的苍凉 2024-10-16 20:01:34

谢谢@jbx,我知道有一种更简单的方法:)但是,这似乎不适用于东墙和西墙以及桨(如果它们在那些墙上)。不过,这似乎对我的东墙和西墙有用:

(180 - (angle + 90)) - 90.

它简化为(180-angle)
希望有帮助。

Thanks @jbx, I knew there was a simpler way :) However, that doesn't seem to work for the east and west walls and the paddles (if they're on those walls). This seems to work for me on the east and west walls though:

(180 - (angle + 90)) - 90.

which simplifies to just (180-angle).
Hope that helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文