2016-07-25 3 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

문제는 코너 충돌을 감지 할 필요가 없다는 것입니다. 문제는 현재 충돌 감지가 충돌이 감지되었을 때 볼을 옆으로 움직이지 않는다는 것입니다. 당신의 setup() 기능에

전화 frameRate(5) 더 무슨 일이 일어나고 있는지 볼 수 있습니다 : 볼이 박스의 상단을 교차

bad collision

공지 사항, 당신은 -1하여 vy 변수를 곱 있도록. 이로 인해 원이 위로 움직이기 시작합니다. 그러나 다음 프레임에서는 원이 충분히 이동하지 않았기 때문에 원이 여전히 사각형과 충돌합니다. 코드가 충돌을 감지하면 vy-1 번 다시 입력하면 공이 다시 아래로 이동합니다. 다음 프레임에서는 똑같은 일이 발생하여 볼이 결국 사각형과의 충돌을 멈출 때까지 계속됩니다.

이 문제를 해결하려면 충돌을 감지 할 때 더 이상 다음 프레임의 사각형과 충돌하지 않도록 공을 이동해야합니다. 여기

상단 측면 동안 그 작업을 수행하는 방법의 예입니다

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

if 각 문에 println() 문을 추가 (위의 if 문장의 예를 참조) 볼이 패들 아래에있을 때 어떻게되는지 알, 또는 패들의 오른쪽으로.

로직을 리팩토링하여 네면 (3면뿐만 아니라)을 모두 확인해야합니다.내가 너라면, 공의 다음 위치이 인 함수를 작성하고 해당 위치가 사각형과 충돌하면 boolean 값이 true으로 반환됩니다. 그런 다음 바운스하는 방법을 알려주는 X 및 Y 축에서 공을 이동하기 전에 확인할 수 있습니다. 이런 식으로 뭔가가 :

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

이는 네 개의 개별 if 문의 발생, 그것은뿐만 아니라 당신의 위의 문제를 해결한다.