2013-07-16 4 views
0

이 질문은 많은 질문을받을 수 있으며, 미안하다는 점을 알고 있습니다. 하지만 잠시 동안 내 게임에서 충돌이 생겨서 도움이 필요합니다.XNA 2D Platformer 충돌 및 중력

먼저 게임은 2D 플랫폼입니다. 각 솔리드는 목록에 배치됩니다. 나는 나를 위해 꽤 좋은 작품 충돌 감지에 대한이 코드를 가지고 : 문제는 플레이어가 사각형과 교차하지 않을 경우 I 따라서 그는 계속해서 그와 충돌로 폭포에의 중력을 설정한다는 것입니다 그러나

    if (player.rectangle.Intersects(rect)) 
         { 
          player1Collision = true; 
          colSolid = solid; 
          colRectangle = rect; 
         } 


         if (player1Collision) 
         { 
          Vector2 pos = player.position; 
          Vector2 pLeft = new Vector2(player.BoundingBox.Left, 0); 
          Vector2 pRight = new Vector2(player.BoundingBox.Right, 0); 
          Vector2 pTop = new Vector2(0, player.BoundingBox.Top); 
          Vector2 pBottom = new Vector2(0, player.BoundingBox.Bottom); 

          Vector2 sLeft = new Vector2(colSolid.BoundingBox.Left, 0); 
          Vector2 sRight = new Vector2(colSolid.BoundingBox.Right, 0); 
          Vector2 sTop = new Vector2(0, colSolid.BoundingBox.Top); 
          Vector2 sBottom = new Vector2(0, colSolid.BoundingBox.Bottom); 

          if (player.rectangle.Intersects(colRectangle)) 
          { 
           if (player.velocity.X > 0 && Vector2.Distance(pRight, sLeft) < player.texture.Width/2)//left 
           { 
            player.velocity.X = 0f; 
            pos.X = colSolid.BoundingBox.Left - player.BoundingBox.Width; 

           } 
           else if (player.velocity.X < 0 && Vector2.Distance(pLeft, sRight) < player.texture.Width/2)//right 
           { 
            player.velocity.X = 0f; 
            pos.X = colSolid.BoundingBox.Right; 
           } 

           if (player.velocity.Y > 0 && Vector2.Distance(pBottom, sTop) < player.texture.Height/ 2) //top 
           { 
            player.velocity.Y = 0f; 
            player.gravityOn = false;       
            pos.Y = colSolid.BoundingBox.Top - player.BoundingBox.Height; 

           } 
           else if (player.velocity.Y < 0 && Vector2.Distance(pTop, sBottom) < player.texture.Height/2)//bottom 
           { 
            player.velocity.Y = 0f; 
            pos.Y = colSolid.BoundingBox.Bottom; 

           } 
           player.position = pos; 
          } 
          else 
          { 
           player.gravitySpeed = 0.15f; 
           player.gravityOn = true; 
          } 

         } 

단단한 다음 그것을 충돌하지 않기 위해 위에 올려 놓는다. 내가 알아야 할 것은 : 어떻게 이것을 피할 수 있습니까? 플레이어를 계속해서 솔리드로 떨어 뜨리지 않고 중력을 계속 설정할 수있는 다른 방법이 있습니까? 단단한 솔기 위로 다시 떨어 뜨리면 다시 떨어질까요?

도움을 주시면 감사하겠습니다.

+2

이 질문은 [gamedev 사이트] (http://gamedev.stackexchange.com)에 더 적합 할 수 있습니다. 내가이 플래그를 마이 그 레이션하기를 원한다면 알려주십시오. –

답변

0

이 문제를 해결하는 방법이 최적이 아닐 수도 있습니다. (실제로는 그렇지 않을 것이라고 확신합니다.) 그러나 지금까지 모든 2D 플랫폼 프로젝트에서 저에게 도움이되었습니다.

먼저 스프라이트 클래스에 대해 두 번째 사각형을 정의합니다. 이 사각형은 기본 경계 상자와 동일한 너비와 X 좌표를 갖지만 약간 큰 (내 경우 2 또는 3). 두 사각형의 아래쪽 가장자리가 인라인되도록 당신은 또한 설명하기 위해, 그것을 상쇄해야합니다

Rectangle boundingRect = new Rectangle((int)position.X, (int)position.Y, texture.Width, texture.Height); 
Rectangle gravityRect = new Rectangle((int)boundingRect.X, (int)boundingRect.Y - 3, texture.Width, texture.Height + 3); 

스프라이트 클래스는 플레이어가 떨어지는할지 여부를 추적하기 위해 부울이 필요합니다. 그리고 솔리드인지 여부를 추적하는 하나 (초기화하는 동안 분명히 원하는대로 지정). 내 스프라이트를 초기화 할 때, 나는 보통 목록에 모두 추가

int gravityTotalI = 0; 
int gravityCounterI = 0; 

: 내 GAME1 클래스의 상단에

public bool isGrounded = false; 
bool isSolid; 

, 나는 2의 int를 선언합니다. 나는이 수행 할 수 있도록 : 괜찮은 방향 충돌 엔진을 구축

foreach (Sprite s in spriteList) 
{ 
    if (!s.Equals(player) 
    { 
     if (player.boundingRect.Intersects(s.boundingRect) || player.boundingRect.Intersects(s.gravityRect)) 
     { 
      player.isGrounded = true; 
      gravityCounterI = 0; 
     } 
     else 
     { 
      gravCounterI++; 
      if (gravCounterI >= gravTotalI) 
      { 
       player.isGrounded = false; 
       gravCounterI = 0; 
      } 
     } 

     if (player.boundingRect.Intersects(s.boundingRect)) 
     { 
      player.position.Y -= 2f; //set the resistance of the platform here 
     } 
    } 
} //end of foreach loop. 
if (!player.isGrounded) 
{ 
    player.position.Y += 2f; //set the force of gravity here. 
} 

다른 일이지만이 기술은 것입니다 : 이제

foreach (Sprite s in spriteList) 
{ 
    if (s.isSolid) 
    { 
     gravityTotalI++; 
    } 
} 

을, 나는 GAME1 업데이트 방법에 로직이 비트를 사용 기본을 다뤄야합니다 (그리고 그 지옥의 수신 거부).

희망이 너무 오래 - 바람이 불고/중요한 아무것도 놓치지 마세요, 그리고 정말 도움이되기를 바랍니다 - 나는 당신과 오랫동안 똑같은 문제로 고투했고, 나는 그것이 얼마나 절망적인지를 안다. 있다!

나는 이것을 처리하기위한 다른 사람들의 기술을 기대하고 있습니다!