2009-08-30 8 views
2

iPhone 용 기본 플랫폼 게임을 만들고 있는데 충돌 감지에 문제가 있습니다.iPhone SDK : 충돌 감지, 사각형이어야합니까?

if (CGRectIntersectsRect(player.frame, platform.frame)) 
    pos2 = CGPointMake(0.0, +0.0); 
else 
    pos2 = CGPointMake(0.0, +10.0); 

충돌 감지 플레이어가 플랫폼에있을 때 기존에 게임 중력 중지하는 것입니다, 문제는 충돌 감지가 플레이어 주변의 사각형이 있다는 사실이다, 충돌을 할 어쨌든이 이미지의 실제 모양 (투명도 포함) 대신에 사각형 주위의 감지?

답변

3

독자적으로 이것을 프로그래밍해야하며 픽셀 단위로 충돌하는 것이 iPhone에 너무 비쌉니다. 내 권장 사항은 Collidable 프로토콜 (다른 모든 프로그래밍 언어에서 인터페이스라고 함)을 작성하고 collidedWith : (Collidable *) c 함수를 지정한 다음 충돌을 허용하려는 모든 객체에이를 구현하는 것입니다. 그런 다음 케이스 별 충돌 논리를 작성할 수 있습니다. 마찬가지로, 충돌에 필요한 모든 정보 (X, Y, 너비 및 높이 또는 X, Y 및 픽셀 데이터 배열)와 collidesWith 메서드가있는 큰 수퍼 클래스를 만들 수 있습니다 . 어느 쪽이든 여러 가지 충돌 방법을 쓸 수 있습니다. 몇 가지 사항에 대해서만 픽셀 충돌을 수행하면 성능에 큰 타격을주지 않을 것입니다. 일반적으로 인데 바운딩 박스 충돌이나 기하학에 기반한 다른 충돌을 수행하는 것이 더 빠릅니다.이 빠릅니다.

사람들은 metanetsoftware에서 충돌 기술에 대한 훌륭한 자습서를 만들었습니다. 그 중 axis separation collsiongrid based collision 중 하나가 게임에 더 적합 할 것 같다고합니다. 그러나 무작위 적 충돌 탐지를 유지하려면 (모든 객체를 다른 모든 객체와 비교하여 검사하는 경우) 일반적으로 이미지보다 작은 인 경계 상자를 만드는 것이 일반적입니다. 이것은 Super Mario Brothers를 포함하여 많은 성공한 플랫폼 개발자가 수행 한 것입니다. 가중치가있는 경계 상자를 고려할 수도 있습니다. 즉, 한 유형의 객체에 대해 하나의 경계 상자가 있고 다른 대상에 다른 크기 상자가 있습니다. 예를 들어, 마리오의 경우, 적을 공격하는 것보다 동전을 쳐야하는 큰 상자가 있습니다.

이제 내가 경고 했음에도 불구하고, 나는 당신에게 은혜를 베풀고 픽셀 기반 충돌을 수행하는 방법을 제시 할 것입니다. CGImage의 access the pixel data을 원할 것입니다. 그런 다음 모든 픽셀을 반복하여이 이미지가 다른 이미지와 위치를 공유하는지 확인하십시오. 여기에 몇 가지 코드가 있습니다.

for (int i = 0; i < [objects count]; i++) 
{ 
    MyObject *obj1 = [objects objectAtIndex:i]; 

    //Compare every object against every other object. 
    for (int j = i+1; j < [objects count]; j++) 
    { 
     MyObject *obj2 = [objects objectAtIndex:j]; 

     //Store whether or not we've collided. 
     BOOL collided = NO; 

     //First, do bounding box collision. We don't want to bother checking 
     //Pixels unless we are within each others' bounds. 
     if (obj1.x + obj1.imageWidth >= obj2.x && 
      obj2.x + obj2.imageWidth >= obj1.x && 
      obj1.y + obj1.imageHeight >= obj2.y && 
      obj2.y + obj2.imageGeight >= obj1.y) 
     { 
      //We want to iterate only along the object with the smallest image. 
      //This way, the collision checking will take the least time possible. 
      MyObject *check = (obj1.imageWidth * obj1.imageHeight < obj2.imageWidth * obj2.imageHeight) ? obj1 : obj2; 

      //Go through the pixel data of the two objects. 
      for (int x = check.x; x < check.x + check.imageWidth && !collided; x++) 
      { 
       for (int y = check.y; y < check.y + check.imageHeight && !collided; y++) 
       { 
        if ([obj1 pixelIsOpaqueAtX:x andY:y] && [obj2 pixelIsOpaqueAtX:x andY:y]) 
        { 
         collided = YES; 
        } 
       } 
      } 
     } 
    } 
} 

나는 그렇게 pixelIsOpaque 당신이 그 부분을 프로그램 할 때 그래서 당신은 다시 밖으로 x와 y를 빼기주의해야하거나 검사 할 것이다, 글로벌 좌표 로컬이 아닌 좌표 소요했다 너의 심상의 범위에서.