2012-04-23 2 views
3

나는 수업을위한 프로그래밍 프로젝트를하고있다. 우리는 공, 패들, 네 개의 가장자리 및 벽돌로 구성된 게임 브레이크 아웃을 프로그래밍하고 있습니다. 공은 서로 다른 물체로부터 튀어 오르고 충돌이 감지되면 각 물체는 서로 다른 작업을 수행합니다. 아래 코드는 현재 작동하지 않습니다. 상자가 맞았는지를 계산하기 위해 객체의 위치 (중심점)를 사용하여 경계 상자와 각 가장자리 값 (상단, 하단, 왼쪽, 오른쪽)을 구성하려고합니다. 나는 내 머리 속에 두 가지 유형의 충돌이있을 수 있다고 생각했는데, 하나는 모서리가 맞고 다른 하나는 다른 물체의 중간에 충돌하는 것입니다. 가능한 경우 내 코드를 살펴보고 도움을 받으십시오. 나는 내가하고 싶은 일을 할 수있는 더 좋은 방법이 있는지 모르지만, 현재 내가하지 못하고 사실대로 가치를 반환합니다.경계 박스를 이용한 충돌 감지

이것은 충돌 할 수있는 모든 다른 개체와 충돌 할 수있는 모든 개체를 검사하는 코드의 일부입니다. 또한 각 객체를 이동하고 게임의 시계를 틱합니다.

이 코드는 개체가 다른 개체와 충돌했는지 확인하는 데 사용되며 적절한 경우 수행 할 조치도 취합니다. 이 코드 섹션은 볼 오브젝트에서 가져온 것이므로 벽돌을 칠 때 수행되는 동작은 ySpeed가 반대로됩니다.

public boolean collidesWith(ICollider otherObj) { 
     GameObject gObj = (GameObject) otherObj; 
     //this collider 
     int r1 = (int) (getX() + getWidth()/2); 
     int l1 = (int) (getX() - getWidth()/2); 
     int t1 = (int) (getY() + getHeight()/2); 
     int b1 = (int) (getY() - getHeight()/2); 

     //the other collider 
     int r2 = (int) (gObj.getX() + gObj.getWidth()/2); 
     int l2 = (int) (gObj.getX() - gObj.getWidth()/2); 
     int t2 = (int) (gObj.getY() + gObj.getHeight()/2); 
     int b2 = (int) (gObj.getY() - gObj.getHeight()/2); 

     //corner collision check 
     if(r1>l2 && t2>b1 && t1>t2 && b1>b2){ 
      System.out.println("Corner Collision check 1"); 
      return true; 
     } 
     if(r2>l1 && t2>b1 && t1>t2 && b1>b2){ 
      System.out.println("Corner Collision check 2"); 
      return true; 
     } 
     if(r2>l1 && t1>b2 && t2>t1 && b2>b1){ 
      System.out.println("Corner Collision check 3"); 
      return true; 
     } 
     if(r1>l2 && t1>b2 && t2>t1 && b2>b1){ 
      System.out.println("Corner Collision check 4"); 
      return true; 
     } 

     //middle collision check 
     if(l1>l2 && r1<r2 && t1<t2 && b1<b2){ 
      System.out.println("middle collision check 1"); 
      return true; 
     } 
     if(l1>l2 && r1<r2 && t1>t2 && b1>b2){ 
      System.out.println("middle Collision check 2"); 
      return true; 
     } 
     if(l1<l2 && r1<r2 && t1<t2 && b1>b2){ 
      System.out.println("middle Collision check 3"); 
      return true; 
     } 
     if(l1>l2 && r1>r2 && t1<t2 && b1>b2){ 
      return true; 
     } 

     return false; 
    } 

    public void handleCollision(ICollider otherObject) { 
     if(otherObject instanceof Brick){ 
      System.out.println("Brick Hit"); 
      ySpeed = -(ySpeed); 
     } 
    } 
+0

, 당신은 단계에서 collsions을 확인할 수 있습니다 기억, 일부 개체가 다음 충돌 할 수있는 '느슨한 가능성'을 확인하는 것이 더 효율적입니다 그들이 할 수 있는지 확인한 다음 결정적으로 확인하십시오. 이것은 대부분의 시간 동안, 당신의 사물이 충돌 근처에 있지 않기 때문입니다. 볼에 충돌이있을 수없는 영역 (화면의 아래쪽 절반, 패들 영역 및 측면 빼기)과 그 부분의 단락 회로가 있는지 확인하는 코드를 답에 추가 할 수 있습니다. –

+1

Java 2D API를 사용해 보셨습니까? 기성품 인 [Rectangle] 클래스가있는 기성품 [Rectangle 클래스] (http://docs.oracle.com/javase/1.5.0/docs/api/java/awt/Rectangle.html) 방법. :) – ZeroOne

+1

참고 사항 스택 오버플로 : [두 사각형이 서로 겹치는 지 확인] (http://stackoverflow.com/questions/306316/determine-if-two-rectangles-overlap-each-other)? – ZeroOne

답변

8

당신은 단지 가장자리 경계 상자의을 확인해야합니다. 일부 의사 코드는 다음과 같이 보일 수 있습니다. 이 말하고자하는 것은 무엇

if Rect1[RIGHT] < Rect2[LEFT] or 
    Rect1[LEFT] > Rect2[RIGHT] or 
    Rect1[TOP] < Rect2[BOTTOM] or 
    Rect1[BOTTOM] > Rect2[TOP] 
then return false 
else return true 

가있을 경우 X 또는 Y를 따라 가능한 간격이 충돌 할 수없는 다음 상자를 분리 좌표계이다. 매우SAT (Separating Axis Theorem)

단순한 버전이 모양은 시각적으로 보입니다. 동일한 아이디어가 여기에도 적용됩니다.

Visualisation of SAT

은 다음과 유사한 일을해야한다는 것을 의미한다. 테스트하지는 않았지만 올바른 방향으로 인도 할 수 있습니다.

public boolean collidesWith(ICollider otherObj) { 
    GameObject gObj = (GameObject) otherObj; 
    //this collider 
    int r1 = (int) (getX() + getWidth()/2); 
    int l1 = (int) (getX() - getWidth()/2); 
    int t1 = (int) (getY() + getHeight()/2); 
    int b1 = (int) (getY() - getHeight()/2); 

    //the other collider 
    int r2 = (int) (gObj.getX() + gObj.getWidth()/2); 
    int l2 = (int) (gObj.getX() - gObj.getWidth()/2); 
    int t2 = (int) (gObj.getY() + gObj.getHeight()/2); 
    int b2 = (int) (gObj.getY() - gObj.getHeight()/2); 

    if (r1 < l2 || l1 > r2 || t1 < b2 || b1 > t2) 
     return false; 
    else 
     return true; 

    /* Or could be shortened down to 
    return !(r1 < l2 || l1 > r2 || t1 < b2 || b1 > t2) */ 

} 

당신이 말하는 습관 코드 상당히 감소) 또한

+0

나는 실제로 이것을 전에 시도했다. 문제는이 작업이 항상 일부 개체에 대해 true를 반환한다는 것입니다. 개체 (공)가 화면 중앙에있는 경우에도 gameWorld의 모든 개체와 비교할 때 아무것도 표시하지 않습니다.만약 당신이 두 개의 사각형을 서로 직접적으로 만져서 만지면, r1은 12보다 작을 것입니다. 그래서 원래의 예제에서 나는 모든 대응하는면을 비교해 보았습니다.하지만 그것은 작동하지 않았습니다. –

+0

죄송합니다. 내가 입력하지 못했다고 생각했습니다. 반품은 반대가되어야합니다 : /. 나는 대답을 편집했다. – rflood89

+0

아직 작동하지 않습니까? – rflood89