2016-07-25 172 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報表的地方,它解決了你的上述問題爲好。