2014-09-29 3 views
0

좋아, 오늘은 타일 엔진에 대한 충돌 감지 코드를 더욱 최적화하려고했습니다.타일 엔진 충돌 최적화

이것은 내가 무슨 짓을 : 범위 내에서 포인트가

Circle 클래스를 확인합니다. 있다면, 플레이어와 타일 사이의 충돌을 확인하십시오.

코드 : "1"이있는 경우

 int tileWidth = 128; 
     int tileHeight = 128; 

     int[,] Layer3 = { 1, 1, 1, etc... }; 

     int tileMapWidth = Layer3.GetLength(1); 
     int tileMapHeight = Layer3.GetLength(0); 

     Rectangle tile, tile2; 

     for (int x = 0; x < tileMapWidth; x++) 
     { 
      for (int y = 0; y < tileMapHeight; y++) 
      { 
       int wallIndex = Layer3[y, x]; 

       if (wallIndex == 1) //Full-sized Tile Collision (128 x 128) 
       { 
        if (collisionCircle.Contains(new Vector2(x * tileWidth + (tileWidth/2) + (int)Player.camera.Position.X, 
                  y * tileHeight + (tileHeight/2) + (int)Player.camera.Position.Y))) //+ tile/2 is for centering the point 
        { 
         tile = new Rectangle(x * tileWidth + (int)Player.camera.Position.X, y * tileHeight + (int)Player.camera.Position.Y, tileWidth, tileHeight); 
         Collide(tile); 
        } 
       } 
      } 
     } 

이 레이어 3을 통해 확인한다. 있다면, 사각형을 할당하고 포인트가 충돌 반경 내에 있다면 충돌을 확인하십시오.

또한이 코드를 (draw 메서드를 사용하여) 검사했고, 적어도 올바르게 작동하고 있음을 알고 있습니다.

약 120,000 (32 x 3888) 타일을 지연시켜 코드를 작성하기 전에 조금 뒤떨어졌습니다. 그러나 코드에 추가 한 후에는 훨씬 더 뒤떨어졌습니다.

내가 생각하는 방법에 단지 그것도 원격으로 지연 않을 것 반경 내에있는 타일 (점)의 충돌을 확인,하지만 그런 경우가 아니다 이후 ...

어떤 도움/아이디어 이것을 최적화하는 것이 좋을 것입니다.

고마워, Shyy

편집 :

Cirlce.Contains() 코드 : 나는 사각형을 사용하는 것보다 빠르다 들었습니다 때문에

public bool Contains(Vector2 Point) 
    { 
     return ((Point - position).Length() <= radius); 
    } 

내가 원을 사용했다.

+1

원형 테스트가 제곱 된 거리를 비교하는 대신 sqrt를 사용하는 경우 특히 원형이 아닌 사각형으로 사전 테스트를 시도하십시오. – LearnCocos2D

+0

@ 코코스, 답장을 보내 주셔서 감사합니다. 위 Circle.Contains() 코드를 게시했습니다. 내가 사각형을 사용하는 것보다 빠르다고 들었 기 때문에 원을 사용하고 있습니다. –

+0

어디에서 들었습니까?너비가 제곱 된 길이를 비교하면 성능면에서 동치 일 뿐이지 만 Length()를 사용하기 때문에 제곱근을 사용하므로 속도가 느려집니다. @OSborn의 답변을 참조하십시오. – LearnCocos2D

답변

1

또 다른 가능한 최적화 대신 return ((Point - position).Length() <= radius); 사용 return ((Point - position).LengthSquared() <= radius * radius);

Vector2.Length()는 비용이 많이 드는 제곱근 작업을 수행하기 때문에이 빠릅니다이다. Vector2.LengthSquared()은 느린 작업을 수행 할 필요가 없습니다. 벡터의 제곱으로부터 길이를 고려하여 반지름을 곱해야합니다.

플레이어와 충돌 할 때 사용할 타일이 무엇인지 판단하려는 것처럼 들립니다. 당신이 할 수있는 또 다른 최적화는 (X = 5, Y = 5)에있는 타일이 플레이어의 위쪽과 왼쪽에 있다면 (X = 4, Y = 4) 타일을 검사 할 필요가 없다는 것입니다. . 유사하게 (X = 5, Y = 5)가 오른쪽 아래에 있고 (X = 6, Y = 6) 너무 멀다고 보장됩니다. 플레이어를 통과했을 때 더 이상 충돌을 확인할 필요가 없는지 확인하십시오.

+0

답장을 보내 주셔서 감사합니다, Osborn. 나는 그것을 곧 구현할 것이다! 두 번째 부분에서는 원이 범위를 검사하여 범위 내에 타일이 있는지 확인합니다. 내가 다른 충돌 검사를 추가했음을 알았지 만 성능 문제가있는 이유 일 수 있습니다. –

0

이동 오프셋을 사용하여 충돌을 확인하기 위해 화면의 보이는 타일 위로 만 루프하는 것이 좋습니다. 난 내 머리에서 뭔가를 시도 할 것이다 는 ..

for x as integer = 0 + offSetX to tilesInWidth + offSetX 
    for y as integer = 0 + offSetY to tilesInHeight + offSetY 
     if player.insideCircle(player.position, radius) ' 
     object = layer(y,x); 
     if player.collideWith(object) then Collide() 
     end if 
    next 
next 
+0

아아, 알았어. 당신이 말한 것을 이해 합니다만, 저는 Visual Basic에 능통하지 않습니다. 몇 가지 간단한 질문 : offSetX/Y는 무엇을 나타낼 예정입니까? 그리고 tilesInWidth/Height가지도의 타일 크기라고 가정합니다. 도와 주셔서 감사합니다. –

+0

오, 방금 뭔가 깨달았습니다. 타일 ​​맵에 엔티티 (몬스터/생물)가 있습니다. 따라서 화면상의 직사각형 만 검사하면 좋은 생각 일지 모르겠다. 마치 벽을 통과 할 수있는 것처럼 보일 뿐이다. 또는 당신이 말한대로하는 것이 좋은 생각 일 것이지만, 가능한 경우 엔티티에 대한 별도의 점검을 수행합니까? 감사. –