有时球反弹有时不会 [英] Ball sometimes bounces sometimes doesn't

查看:323
本文介绍了有时球反弹有时不会的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这code,使周围的画布球反弹:

This code makes the ball bounce around the canvas:

//advance the ball
ball.advance();
//check if ball should bounce off canvas sides
if (ball.getCenterX() + ball.getRadius() > canvas.getWidth())
    ball.setDirectionX(LEFT);
if (ball.getCenterX() - ball.getRadius() < 0)
    ball.setDirectionX(RIGHT);

if (ball.getCenterY() + ball.getRadius() > canvas.getHeight())
    ball.setDirectionY(UPWARDS);
if (ball.getCenterY() - ball.getRadius() < 0)
    ball.setDirectionY(DOWNWARDS);

看起来像这样: https://gyazo.com/7b51794a6e5e474b508cf442ddebc8dc

我试着做,当它击中它反弹的桨,我用这个code:

Im trying to make it bounce off the paddle when it hits it and I used this code:

boolean bounceInY = ball.getCenterY()+ ball.getRadius() > paddle.getTopLeftY();
boolean bounceInX = (ball.getCenterX()+ ball.getRadius() > paddle.getTopLeftX()) && (ball.getCenterX()+ ball.getRadius() < paddle.getTopLeftX() + paddle.getWidth());

if (bounceInY && bounceInX)
    ball.setDirectionY(UPWARDS);

遇到的问题即时消息是,它是不一致的,有时它会正常反弹,有时它会经过桨反弹之前,有时它会经过桨,而不是反弹的它。看起来是这样的: https://gyazo.com/d1b5c848290fc23183c9b7296f757a51 我不知道我在做什么错,$ C $℃,球弹离桨好像它应该工作给我。任何帮助AP preciated:)

The issue im having is that it is inconsistent and sometimes it will bounce properly, sometimes it will go through the paddle before bouncing, and sometimes it will go through the paddle and not bounce off of it at all. Looks like this: https://gyazo.com/d1b5c848290fc23183c9b7296f757a51 I am not sure what I am doing wrong, the code for the ball to bounce off the paddle seems like it should work to me. Any help is appreciated :)

推荐答案

在code支票跳票是关闭的一点。首先, ball.getCenterX()+ ball.getRadius()实际上是球的右侧,这就是,您比较桨的唯一的部分位置。这意味着,在有效的桨位置是关闭的量等于该球的半径。你可以看到它在你的形象 - 球唯一的反弹一旦球的最右侧与桨对齐。

The code that checks bouncing is off by a bit. First of all, ball.getCenterX()+ball.getRadius() is effectively the right side of the ball, and that's the only part that you're comparing to the paddle's location. That means that the effective paddle location is off by an amount equal to the radius of the ball. You can see it in your image - the ball only "bounces" once the far right side of the ball is aligned with the paddle.

其次,即使改变这部分后,您的code仍然会失败在一定的条件下。想象一下,例如,那个球是直属桨,但没有击中人墙呢。 presumably你想要的球继续,直到撞到墙向下移动,然后反弹向上。然而,随着code你现在所拥有的,球会立即启动,一旦再次向上移动的桨是球以上 - 根据您的布尔条件下,球桨下方的x坐标之间桨的边缘,所以应该反弹。

Secondly, even after changing that part, your code will still fail in certain conditions. Imagine, for example, that the ball is directly under paddle but has not hit the wall yet. Presumably you want the ball to continue moving downward until it hits the wall, then bounce back upwards. However, with the code you have right now, the ball will immediately start moving upwards again as soon as the paddle is above the ball - according to your boolean conditions, the ball is below the paddle and the x-coordinate is between the paddle's edges, so it should "bounce".

我假设你是一个初学者,可能不希望进入一个大量的数学,所以解决这个问题最简单的方法是使用使用的AABB(轴对齐包围盒),并测试碰撞该逻辑。这里有一个例子:

I'm assuming you're a beginner and probably don't want to get into a lot of math, so the simplest way to resolve this problem is to use AABBs (axis-aligned bounding boxes) and test for collision using that logic. Here's an example:

// I'm creating a bunch of variables here because I don't know
// what properties your objects have available.
int ballLeftSide     = ball.getCenterX() - ball.getRadius();
int ballRightSide    = ball.getCenterX() + ball.getRadius();
int ballTopSide      = ball.getCenterY() - ball.getRadius();
int ballBottomSide   = ball.getCenterY() + ball.getRadius();
int paddleLeftSide   = paddle.getTopLeftX();
int paddleRightSide  = paddle.getTopLeftX() + paddle.getWidth();
int paddleTopSide    = paddle.getTopLeftY();
int paddleBottomSide = paddle.getTopLeftY() + paddle.getHeight();

bool ballOverlapsPaddle = ((ballLeftSide < paddleRightSide) &&
                           (ballRightSide > paddleLeftSide) &&
                           (ballTopSide < paddleBottomSide) &&
                           (ballBottomSide > paddleTopSide))

// Only change ball direction if the ball hasn't already passed
// the paddle. In this case, "passed" means the ball's center is
// further down than the bottom of the paddle.
if ((ballOverlapsPaddle) && (ball.getCenter() < paddleBottomSide))
    ball.setDirectionY(UPWARDS);

这是检查重叠布尔条件采用采用轴对齐包围盒(的AABB)的分离轴定理(SAT)的一个非常简单的形式。基本上,它检查两个矩形是否发生碰撞。由于您的形状之一是一个球,这个方法把它当作如果它有它周围的矩形边框,当它这样做检查。

That boolean condition that checks for overlaps uses a very simple form of the Separating Axis Theorem (SAT) using axis-aligned bounding boxes (AABBs). Basically, it checks whether two rectangular shapes are colliding. Since one of your shapes is a ball, this method treats it as if it had a rectangular bounding box around it when it does this check.

现在,虽然这种解决方案很简单,但它确实带来了一些并发症的发生。由于你的球显然不是一个矩形,它的有效边界框将会延长有点超出球的实际形状。这意味着,你将有冲突,即使有也不在视觉上出现任何,如下面的例子。

Now, although this solution is very simple, it does bring up some complications. Since your ball is obviously NOT a rectangle, its effective bounding box is going to extend a bit beyond the actual shape of the ball. That means that you'll have "collisions" even when there don't visually appear to be any, as shown in the example below.

假阳性QUOT;碰撞&QUOT;

有当然的方法来解决这个问题,但就有点过于详细,易怒的Q +的格式。如果您想寻找到自己动手,这是我使用教程,当我第一次了解形状之间的碰撞检测。

There are of course methods to get around that issue, but that gets a little too detailed and techy for a Q+A format. If you'd like to look into it yourself, this is the tutorial I used when I first learned about collision detection between shapes.

这篇关于有时球反弹有时不会的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆