2012-09-03 3 views
3

프로젝트의 경우 게임을 만들 게임 엔진을 제공 받았습니다. 우리는 경계 상자 감지 방법을 통해 가능한 충돌이 발견 된 후에 픽셀 레벨 충돌 감지를 구현해야합니다. 둘 다 구현했지만 픽셀 수준 테스트는 작은 개체 (이 경우 글 머리 기호)에서 실패합니다. 나는 그것이 느린 총알을 위해 작동하는지 점검했지만 너무 실패했다.작은 개체의 경우 픽셀 수준 충돌 검색이 실패합니다. (Java)

내 픽셀 수준 구현에서는 사용 가능한 IntBuffer를 사용하여 각 텍스처의 비트 마스크를 만듭니다 (ByteBuffer도 사용할 수 있습니까?). IntBuffer는 RGBA 형식이고 크기는 width * height입니다.이 값을 2D 배열에 배치하고 1이 아닌 숫자를 모두 마스크로 바꾸십시오. 경계 상자가 충돌 한 후 중복 (.createIntersection을 사용하여)으로 표시된 사각형을 찾은 다음이 교차 내의 두 스프라이트의지도에서 비트 AND를 사용하여 둘 다의 0이 아닌 픽셀을 확인합니다. 나는 일이 고민 봤는데 어떤 도움이 크게 감사합니다

/** 
* Pixel level test 
* 
* @param rect the rectangle representing the intersection of the bounding 
* boxes 
* @param index1 the index at which the first objects texture is stored 
* @param index the index at which the second objects texture is stored 
*/ 
public static boolean isBitCollision(Rectangle2D rect, int index1, int index2) 
{ 
    int height = (int) rect.getHeight(); 
    int width = (int) rect.getWidth(); 

    long mask1 = 0; 
    long mask2 = 0; 

    for (int i = 0; i < width; i++) 
    { 
     for (int j = 0; j < height; j++) 
     { 
      mask1 = mask1 + bitmaskArr[index1].bitmask[i][j];//add up the current column of "pixels" 
      mask2 = mask2 + bitmaskArr[index2].bitmask[i][j]; 

      if (((mask1) & (mask2)) != 0)//bitwise and, if both are nonzero there is a collsion 
      { 
       return true; 
      } 
      mask1 = 0; 
      mask2 = 0; 
     } 

    } 


    return false; 
} 

:

여기에 픽셀 레벨 테스트에 대한 내 코드입니다.

+0

: /// C :/문서 % 20 ° % 20Settings/SER/데스크탑/java3d/신발 끈 % 20formula % 20 % 20Wikipedia % 20the % 20free % 20encyclopedia.htm' 당신이 찾을 수있는 지역 하나의 도형 중 ... 하나의 영역이 서로 다른 모양의 영역의 합보다 작 으면 충돌합니다. 이것은 O (n + m) 방법보다 O (n * n) –

+0

조언 주셔서 감사하지만 나는 이런 종류의 테스트를 구현해야합니다. – Mafro34

답변

2

나는이 문제를 해결할 수 있었지만 이제는 제대로 작동합니다. 관심있는 사람은 두 스프라이트의 두 경계 상자가 겹쳐서 만들어지는 사각형을 찾았습니다. 나는 상대적으로 직사각형과 함께 원점에 각 객체를 떨어 뜨렸다. 각 객체를 "분리 된"원점에 떨어 뜨린 점에 주목해야합니다. 즉, 이후에 실제로 교차하는 두 개의 직사각형이 있습니다. 두 객체의 비트 마스크 2D 배열의 경계에있는 각 직사각형의 좌표는 두 객체의 겹침에 대한 올바른 영역을 확인하는 데 사용되었습니다.

비트 마스크를 통해 아래에서 위로 왼쪽에서 오른쪽으로 루프합니다. 위쪽에 제공된 이미지 데이터로 - 분명히 이것은 이미지 데이터의 표준입니다.파일`에서

/** 
* My Pixel level test - 2D 
* 
* @param rect the rectangle representing the intersection of the bounding 
* boxes 
* @param index1 the index at which the first objects texture is stored 
* @param index2 the index at which the second objects texture is stored 
* @param p1 the position of object 1 
* @param p2 the position of object 2 
* @return true if there is a collision at a pixel level false if not 
*/ 
//public static boolean isPixelCollision(Rectangle2D rect, Point2D.Float p1, Bitmask bm1, Point2D.Float p2, Bitmask bm2) 
public static boolean isPixelCollision(Rectangle2D rect, Point2D.Float p1, int index1, Point2D.Float p2, int index2) 
{ 
    int height = (int) rect.getHeight(); 
    int width = (int) rect.getWidth(); 

    byte mask1 = 0; 
    byte mask2 = 0; 

    //drop both objects to the origin and drop a rectangle of intersection for each along with them 
    //this allows for us to have the co-ords of the rect on intersection within them at number that are inbounds. 
    Point2D.Float origP1 = new Point2D.Float((float) Math.abs(rect.getX() - p1.x), (float) Math.abs(rect.getY() - p1.y));//rect for object one 
    Point2D.Float origP2 = new Point2D.Float((float) Math.abs(rect.getX() - p2.x), (float) Math.abs(rect.getY() - p2.y));//rect for object two 

    //to avoid casting with every iteration 
    int start1y = (int) origP1.y; 
    int start1x = (int) origP1.x; 
    int start2y = (int) origP2.y; 
    int start2x = (int) origP2.x; 

    //we need to loop within the rect of intersection 
    //goind bottom up and left to right 
    for (int i = height - 1; i > 0; i--) 
    { 
     for (int j = 0; j < width; j++) 
     { 
      mask1 = bitmaskArr[index1].bitmask[start1y + i][start1x + j]; 
      mask2 = bitmaskArr[index2].bitmask[start2y + i][start2x + j]; 
      if ((mask1 & mask2) > 0) 
      { 
       return true; 
      } 
     } 

    } 
    //no collsion was found 
    return false; 
} 
0

문제는이 코드 부분이 될 수 :

if (((mask1) & (mask2)) != 0)//bitwise and, if both are nonzero there is a collsion 
{ 
    return true; 
} 

당신이 비트를 사용하는 것 모두 값이 제로가 아닌 여부를 확인하기 위해 -하지만이 같은 방식으로 작동하지 않을 수 있습니다.

예를 들어 다음과 같은 식의 값 :

3 & 4 == 0 

이 참

당신은 비트 연산을 할 때 자신의 비트 표현 등의 숫자를 생각하고 작업을 할 필요가 있기 때문이다 조금씩.

그래서 :

3 = 0000 0011 
& 4 = 0000 0100 
--------------- 
    0 = 0000 0000 

이 때문에 1 비트 값이 서로에 정렬하는 방법이다. 약간의 비트 단위에서 1 개의 값을 가지려면 - 다른 수의 동일한 위치에 두 개의 비트를 또 다른 예는 것 1.

을 할 필요가 : 귀하의 경우 A의 그래서

3 = 0000 0011 
& 2 = 0000 0010 
--------------- 
    2 = 0000 0010 

더 나은 수표는 다음과 같습니다 :

if (mask1>0 && mask2>0)//logical and if both are nonzero there is a collsion 
{ 
    return true; 
} 
+0

안타깝게도 문제를 해결하지 못한다고 자문하면서 코드를 변경하는 어리 석음에 놀랐습니다. 다음 'INT 변화 = (int)를 (을 P1.x -p2.x)' : '경우 은 또한이 당신이 그렇게함으로써 양육 문제를 분류 할 수처럼 솔기로의 변화를 구현하는 시도 (시프트 <0) { ' ''' MASK1 = MASK1 << (-Shift)'' } {else' ''' mask2 = mask2 << (시프트)'' }' 'if ((mask1 & mask2)! = 0)' '{' 'return true; ' '}' – Mafro34

+0

@ Mafro34 비트 마스크는 어떻게 구현 되나요? 우리가 2x2 픽셀 인 두 개의 총알을 가지고 있다고 가정 해 봅시다. 이 예제에서는 비트 마스크가 3x3 사각형이어야한다고 생각합니다. 이게 네가 가진거야? – norbitheeviljester

+0

글 머리 기호가 높이 2이고 너비가 2 인 경우이 경우 마스크는 2x2가됩니다. – Mafro34

관련 문제