简体   繁体   English

如何使矩形角的圆反弹 - 处理

[英]How to make a circle bounce of a corner of a rectangle - Processing

I will keep this quick.我会保持这个快速。

Just making a processing program where the ball bounces off the rectangle.只是制作一个处理程序,让球从矩形上弹开。

At the moment I can only figure out how to do the top,left,right and bottom sides but when the ball goes into the corners of the rectangle, it doesn't bounce off but instead goes into the rectangle and after 1 or 2 bounces gets realeased.目前我只能弄清楚如何做顶部,左侧,右侧和底部,但是当球进入矩形的角落时,它不会反弹而是进入矩形并在1或2次反弹后得到释放。

I just really want to know how I should go about making the ball deflect off the corners of the rectangle so it doens't glitch我真的很想知道我应该如何让球从矩形的角上偏转,这样它就不会出现故障

Here is my code :这是我的代码:

    float x = 100, y = 100, radius = 50;
    float vx = 3, vy = 3;
    float MX = 0;
    float MY = 0;


    void setup() {
        size(500, 700);
    }

    void draw() {
        background(0);
        fill(255);

        x += vx;
        y += vy;
        if (x + radius > width) {
            vx = vx * -1;
        }
        //makes the ball bounce off the right
        if (x - radius < 0) {
            vx = vx * -1;
        }
        //makes the ball bounce off the left
        if (y + radius > height) {
            vy = vy * -1;
            y = height - radius;
        }
        //make the ball bounce off the top
        if (y - radius < 0) {
            vy = vy * -1;
            y = radius;
        }
        //makes the ball bounce    off the top
        if (y + radius > MY && x + radius > MX + 50 && x + radius < MX + 150 &&
            y + radius < MY + 20) {
            vy *= -1;
            y = MY - 3 - radius;
        } //Top Side
        if (x - radius < MX + 100 && y > MY - 10 && y < MY + 10 && x - radius > MX) {
            vx *= -1;
        } // Right Side

        if (y - radius < MY + 20 && x + radius > MX + 50 && x + radius < MX + 150 &&
            y - radius > MY) {
            vy *= -1;
            y = MY + 20 + radius;
        } //Bottom Side

        if (x + radius > MX && y > MY - 10 && y < MY + 10 && x + radius < MX + 100) {
            vx *= -1;
        } // Left Side

        ellipse(x, y, radius * 2, radius * 2);
        rect(MX, MY, 100, 20);

    }

void mouseMoved() {

        MX = mouseX - 50;
        MY = mouseY - 10;
        if (MX < 0) {
            MX = 0;
        }
        if (MX > 400) {
            MX = 400;
        }
        if (MY < 0) {
            MY = 0;
        }
        if (MY > 680) {
            MY = 680;
    }

Sorry I do know know how to insert the code very well, I am new to this site, please have mercy haha :)对不起,我知道如何很好地插入代码,我是这个网站的新手,请怜悯哈哈:)

Cheers干杯

The problem is not that you need to detect corner collision.问题不在于您需要检测角碰撞。 You've got two other problems:你还有另外两个问题:

Problem 1: When you detect a collision, you need to move the ball so it's not colliding with the rectangle anymore.问题 1:当您检测到碰撞时,您需要移动球,使其不再与矩形碰撞。

If you don't, then when the ball intersects the top of the box, you multiply the vy variable by -1 .如果不这样做,那么当球与盒子顶部相交时,将vy变量乘以-1 That causes the circle to start moving up.这导致圆圈开始向上移动。 But the next frame, the circle is still colliding with the rectangle, because it hasn't moved up enough yet.但是下一帧,圆仍然与矩形碰撞,因为它还没有向上移动。 So your code detects that collision, multiples vy by -1 again, and the ball moves back down.所以,你的代码检测到碰撞,倍数vy-1一遍,球移动退缩。 Next frame the same thing happens, until the ball eventually stop colliding with the rectangle.下一帧发生同样的事情,直到球最终停止与矩形碰撞。

Slow the framerate down to see what I'm talking about:减慢帧率,看看我在说什么:

坏碰撞

To fix this, you need to "pop" the ball back to a location that's no longer intersecting with the rectangle.要解决此问题,您需要将球“弹回”到不再与矩形相交的位置。 That way you know it won't still be colliding in the next frame.这样你就知道它不会在下一帧仍然发生碰撞。

Problem 2: You shouldn't do collision on each side separately.问题 2:您不应该在每一侧分别进行碰撞。 Instead, do collisions between the entire circle and the entire rectangle, and then check one axis of movement at a time.相反,在整个圆和整个矩形之间进行碰撞,然后一次检查一个运动轴。

Checking against one side at a time will lead to plenty of headaches, including the problem where multiple sides are hit at one time.一次检查一侧会导致很多头痛,包括一次击中多侧的问题。 I would also bet that your code isn't doing what you think it is: try adding println() statements to all of your if statements to make sure they're executing when you think they are.我还敢打赌,你的代码并没有像你想象的那样做:尝试将println()语句添加到你所有的if语句中,以确保它们在你认为的时候执行。

To fix this problem, I would create a collides() function that takes parameters for the next position of the ball, and returns whether the ball will be colliding with any side of the rectangle.为了解决这个问题,我将创建一个collides()函数,它接受球的下一个位置的参数,并返回球是否会与矩形的任何边发生碰撞。 Then pass in the next X and Y positions and flip their speeds.然后传入下一个 X 和 Y 位置并翻转它们的速度。 It'll look something like this:它看起来像这样:

 if (collides(circleX + vx, circleY)) {
    vx*=-1;
  } 
  else {
    circleX += vx;
  }
  if (collides(circleX, circleY + vy)) {
    vy*=-1;
  } 
  else {
    circleY += vy;
  }

You'd also want to add the logic for "popping" the ball so it's no longer colliding.您还想添加“弹出”球的逻辑,使其不再发生碰撞。

好碰撞

PS: Did you try searching for your problem on google or the Stack Overflow search? PS:您是否尝试在 google 或 Stack Overflow 搜索上搜索您的问题? This question is almost an exact duplicate of your question, to the point where I'm pretty sure you're in the same class! 这个问题几乎与您的问题完全相同,以至于我很确定您在同一个班级!

A quick dirty way i have previously achieved this is by first adding bounding boxes to each side and positioning them in a way that if the ball collides with for example on the top right corner i would then have a condition:我以前实现的一种快速肮脏的方法是首先在每一侧添加边界框并以这样的方式定位它们,如果球碰撞,例如在右上角,我就会有一个条件:

If ball intercepts bounds top and bounds right: do this;如果球拦截到边界顶部和边界右侧:这样做;

I hope this helps!我希望这会有所帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM