2016-07-25 141 views
0

我有一个程序处理一个弹跳球和矩形。我可以得到矩形两侧的碰撞,但我不知道如何找到角落。这是我到目前为止有:圆和矩形碰撞

int radius = 20; 
float circleX, circleY; //positions 
float vx = 3, vy = 3; //velocities float boxW, boxH; //bat dimensions 

void setup(){ 
    size(400,400); 
    ellipseMode(RADIUS); 
    rectMode(RADIUS); 
    circleX = width/4; 
    circleY = height/4; 
    boxW = 50; 
    boxH = 20; 
} 

void draw(){ 
    background(0); 

    circleX += vx; 
    circleY += vy; 

    //bouncing off sides 
    if (circleX + radius > width || circleX < radius){ vx *= -1; } //left and right 
    if (circleY + radius > height || circleY < radius){ vy *= -1; } //top and bottom 
    if (circleY + radius > height){ 
    circleY = (height-radius)-(circleY-(height-radius)); } //bottom correction 

    //bouncing off bat 
    if (circleY + radius > mouseY - boxH && circleX > mouseX - boxW && circleX < mouseX + boxW){ 
     vy *= -1; //top 
    } 
    if (circleX - radius < mouseX + boxW && circleY > mouseY - boxH && circleY < mouseY + boxH){ 
     vx *= -1; //right 
    } 
    if (circleY - radius > mouseY + boxH && circleX > mouseX - boxW && circleX < mouseX + boxW){ 
     vy *= -1; //bottom 
    } 
    if (circleX + radius < mouseX - boxW && circleY > mouseY - boxH && circleY < mouseY + boxH){ 
     vx *= -1; //left 
    } 

    if ([CORNER DETECTION???]){ 
    vx *= -1; 
    vy *= -1; 
    } 

    ellipse(circleX,circleY,radius,radius); 

    rect(mouseX,mouseY,boxW,boxH); 
} 

我不知道要放什么东西在if语句来检测碰撞角落。

+0

您需要重新考虑对几何体的“印象”。首先:一个圈子在一个角落实际上是不可能的。第二:你没有碰到一个角落,你同时击中双方。你需要改变你的逻辑思想,你可能会同时触及多个方面。粗略浏览一下你的前两个陈述似乎已经涵盖了这些内容。 –

+0

你有没有得到这个清理? –

回答

2

问题不在于您需要检测角落碰撞。问题在于,当检测到碰撞时,您当前的碰撞检测不会将球移动到一侧。

呼叫frameRate(5)setup()功能更清楚地看到发生了什么事情:

bad collision

注意球相交的盒的顶部,因此您可以通过-1乘以vy变量。这会导致圈子开始向上移动。但是下一帧,圆仍然与矩形碰撞,因为它还没有完全移动。因此,您的代码会检测到该碰撞,再次通过-1倍增vy,并且球向下移动。下一帧发生同样的事情,直到球最终停止与矩形碰撞。

要解决此问题,当您检测到碰撞时,您需要移动球,使其不再与下一帧中的矩形相碰撞。

这里是如何做到这一点的顶侧的例子:

if (circleY + radius > mouseY - boxH && circleX > mouseX - boxW && circleX < mouseX + boxW) { 
    vy *= -1; //top 
    circleY = mouseY-boxH-radius; 
} 

good collision

你必须添加类似的逻辑的另一边,但总的想法是一样的:确保球在下一帧不会碰撞,否则它会像这样在边缘上弹跳。

编辑:以你的碰撞逻辑定睛一看,东西是尚客:你永远只能检查面,当你真的应该检查所有四个两侧。

让我们这一个例子:

if (circleY + radius > mouseY - boxH && circleX > mouseX - boxW && circleX < mouseX + boxW){ 
    println("top"); 
    vy *= -1; //top 
} 

你检查球下方的长方形顶部,到矩形的左边的右边,和右左的矩形。这将是true这种情况:

no collision

添加println()语句每个if报表(见上面的if声明的例子),并注意当球桨下面会发生什么,或者在桨的右侧。

您需要重构您的逻辑,以便检查所有四面而不仅仅是三面。如果我是你,我会写一个函数,其中下一个位置的球,并返回booleantrue如果该位置与矩形冲突。然后,您可以在X和Y轴上移动球之前进行检查,这会告诉您如何弹跳。事情是这样的:

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

这需要你的四个独立if报表的地方,它解决了你的上述问题为好。