2013-12-15 2 views
4

학교용 Windows Forms로 게임을 만들어야합니다. 내 게임은 미로를 통과해야하는 사용자로 구성됩니다. 내 사용자가 충돌 감지를 사용하여 벽을 직진하는 것을 막으려 고하고 있지만 벽을 나타내는 데 사용되는 사각형의 모양이 다양하기 때문에 멈추는 경우가 있습니다. Here's an image of the game.이 질문은 this one과 비슷할 수 있습니다. 그러나 제 운동에 대해서는 그리드 시스템이나 그래픽지도가 배치되지 않았으므로 꽤 다른 것이라고 생각합니다.두꺼운 벽이있는 2D 미로에서 충돌 감지

보시다시피, 벽은 상당히 두껍습니다. 각 벽은 C# Rectangle,으로 표시되며 내 플레이어 이미지 (작은 노란색 유령)입니다. C#의 IntersectsWith(Rectangle r) 메서드를 사용하여 플레이어가이 벽을 통과하는지 확인하는 방법을 알고 있지만 충돌을 처리하고 플레이어가 벽을 전혀 통과하지 못하도록하려면이 정보를 사용하는 방법을 정확히 알지 못합니다.

다음은 내가 시도한 내용입니다.

이것은 실제 코드입니다.의

이제
private void HandleCollision() 
    { 
     // First, check to see if the player is hitting any of the boundaries of the game. 
     if (this.x <= 0) 
     { 
      this.x = 0; 
     } 
     if (this.x >= 748) 
     { 
      this.x = 748; 
     } 
     if (this.y <= 0) 
     { 
      this.y = 0; 
     } 
     if (this.y >= 405) 
     { 
      this.y = 405; 
     }   
     // Second, check for wall collision. 

     foreach (Rectangle wall in mazeWalls) 
     { 
      if (playerRectangle.IntersectsWith(wall)) 
      { 
       if (player.X > wall.X) { player.X += wall.Width; } 
       else if (player.X < wall.X) { player.X -= wall.Width; } 
       else if (player.Y > wall.Y) { player.Y += wall.Height; } 
       else if (player.Y < wall.Y) { player.Y -= wall.Height; }      
      } 
     } 
    } 

이 코드 위 종류 : 게임은의 WinForm에 내장되어 있기 때문에, 운동이 내 충돌 방법, HandleCollision()입니다 같은 OnKeyPressed로하고 OnKeyUp

public void Move(Direction dir) 
    { 
     HandleCollision(); // Handle collision while player is trying to move. 
     if (dir == Direction.NORTH) 
     {     
      this.y -= moveSpeed; 
     } 
     if (dir == Direction.SOUTH) 
     {     
      this.y += moveSpeed; 
     } 
     if (dir == Direction.EAST) 
     { 
      this.x += moveSpeed; 
     } 
     if (dir == Direction.WEST) 
     { 
      this.x -= moveSpeed; 
     } 
    } 

키보드 이벤트에 의해 트리거됩니다 공장. 그러나 플레이어의 좌표에 벽의 너비/높이가 추가되어 있기 때문에 플레이어가 바운스하는 곳에서지도를 가로 지르는 이상한 충돌 순간 이동이 이루어집니다. 그렇다면 if (playerRectangle.IntersectsWith(wall)) { 블록 내의 모든 코드를 대체 할 수있는 충돌 감지 시스템을 구현하는 가장 효율적인 방법은 무엇일까요?

답변

3

이동 중에는 현재 위치를 저장하고 이동을 수행 한 다음 충돌을 확인하고 참이면 이전 위치로 복원하십시오.

이렇게하려면 HandleCollision은 부울 값을 반환합니다. 성공한 각 테스트 (성공 = 충돌이 감지 됨)에 대해 true이고, 조건이 충족되지 않으면 끝에는 false입니다. 메서드는 x 또는 y 값을 전혀 수정하지 않습니다. 새 함수를 반영하기 위해이 메서드의 이름을 CheckCollision으로 변경해야합니다.


다른 게시물의 gif에서 경기장이 사각형으로 나뉘어져 있고 벽과 스프라이트가 여러 개의 사각형으로 구성되어있는 것 같습니다. 그런 다음 의도 한 증가분이 충족 될 때까지 한 칸씩 증가시켜야합니다. 각 사각형에 대해 충돌을 검사해야합니다.

이동 당 하나의 수표 만 사용하는 고급 방법의 경우 선형 수학이 필요합니다. 충돌 체크는 현재 포인트 P와 이동의 증가 d를 필요로합니다. P와 P + d 사이에 벽이 교차하는지 확인해야합니다. 이것은 일반적으로 선형 조건의 부호 변화로 표시됩니다. P의 왼쪽에 수직 벽 W가있는 경우 d가 벽을 가리키면 P.x+d.x-(W.x+W.width)은 음수가됩니다. W.x+W.width<=P.x+s*d.x으로 s를 결정하십시오. 수평 벽의 경우 y 좌표에서 같은 체크를해야합니다. 모든 물체에 최소값을 가하고 P+s*d을 새로운 위치로 가져갑니다.