2010-04-02 7 views
4

두 개체 간의 가능한 모든 충돌을 처리하기위한 좋은 방법을 만들려고합니다. 일반적으로 사람은 움직이고 다른 사람을 때릴 것이고, 그 다음 "떨어져 나간다".가능한 한 깔끔하게 충돌하는 동안 속도 벡터 처리

내가 지금까지 해왔 던 것은 (보드가 있고 벽돌에서 공을 튀기는 전형적인 게임을 만들고 있습니다.) 직사각형이 교차하는지 확인하는 것입니다. 그렇다면 Y- 속도가 반전됩니다.

이것은 장거리에서 작동하지 않는 매우 추악하고 임시적인 솔루션이며, 게임에서 처리 방법이 매우 일반적이어서 향후 프로젝트에서도 이와 같은 작업을 수행하는 것이 좋습니다. . 모든 링크 또는 유용한 정보는 높이 평가됩니다.

아래는 내 충돌 처리 기능의 모습입니다.

protected void collision() 
    { 
     #region Boundaries 
     if (bal.position.X + bal.velocity.X >= viewportRect.Width || 
      bal.position.X + bal.velocity.X <= 0) 
     { 
      bal.velocity.X *= -1; 
     } 
     if (bal.position.Y + bal.velocity.Y <= 0) 
     { 
      bal.velocity.Y *= -1; 
     } 
     #endregion 
     bal.rect = new Rectangle((int)bal.position.X+(int)bal.velocity.X-bal.sprite.Width/2, (int)bal.position.Y-bal.sprite.Height/2+(int)bal.velocity.Y, bal.sprite.Width, bal.sprite.Height); 
     player.rect = new Rectangle((int)player.position.X-player.sprite.Width/2, (int)player.position.Y-player.sprite.Height/2, player.sprite.Width, player.sprite.Height); 

     if (bal.rect.Intersects(player.rect)) 
     { 
      bal.position.Y = player.position.Y - player.sprite.Height/2 - bal.sprite.Height/2; 
      if (player.position.X != player.prevPos.X) 
      { 
       bal.velocity.X -= (player.prevPos.X - player.position.X)/2; 
      } 

      bal.velocity.Y *= -1; 
     } 
     foreach (Brick b in brickArray.list) 
     { 
      b.rect.X = Convert.ToInt32(b.position.X-b.sprite.Width/2); 
      b.rect.Y = Convert.ToInt32(b.position.Y-b.sprite.Height/2); 
      if (bal.rect.Intersects(b.rect)) 
      { 
       b.recieveHit(); 
       bal.velocity.Y *= -1; 
      } 
     } 
     brickArray.removeDead(); 
    } 
+0

이것에서 무엇이든을 얻으려면, 내가 원하는 행동을 더 정확히 말해야한다고 생각합니다. '이것은 정말로 추악하고 일시적이다'라고 말하면 그것을 잘라 내지 않습니다. –

+1

Bal은 속도가 너무 높을 때 "텔레포트"하지 않고 직각으로 닿는 모든 표면을 정확하게 반사해야하는 볼을 의미합니다. – bjrnt

답변

1

다음은 몇 가지 제안 사항입니다.

모든

첫째, 모든 개체 등 Player, Bal으로 (그게 뭔지 확실하지)와 Brick 다소 비슷한 인터페이스를 가지고 - 그들은 모두 개체의 (경계 상자 sprite (객체의 크기를 정의), rect이), position (현재 위치), velocity (현재 속도). 이것은이 기능을 캡슐화하기위한 공통 기본 클래스를 작성할 수 있음을 암시합니다.

또한 현재 positionsprite을 기준으로 rect을 다시 계산한다는 점에 유의하십시오. 즉, rect은 실제로 재 계산을 숨기는 속성이어야합니다 (항상 동일합니다).

이렇게 공통 기본 클래스를 정의하여 시작할 수 있습니다 (.NET 표준 코딩 스타일을 따르고 사용합니다. 속성과 CamelCase 이름) : 그것은 또한 좋은 같은 소리

protected void Collision() {  
    #region Boundaries   
    if (bal.Position.X + bal.Velocity.X >= viewportRect.Width ||   
     bal.Position.X + bal.Velocity.X <= 0)   
     bal.Velocity.X *= -1;   
    if (bal.Position.Y + bal.Velocity.Y <= 0)   
     bal.Velocity.Y *= -1;   
    #endregion 

    if (bal.Rect.Intersects(player.Rect)) {  
     bal.Position.Y = player.Position.Y - player.Sprite.Height/2 
         - bal.Sprite.Height/2;  
     if (player.Position.X != player.PrevPos.X)  
      bal.Velocity.X -= (player.PrevPos.X - player.Position.X)/2;  
     bal.Velocity.Y *= -1;  
    }  
    foreach (Brick b in brickArray.list) {  
     if (bal.Rect.Intersects(b.Rect)) {  
      b.RecieveHit();  
      bal.Velocity.Y *= -1;  
     }  
    }  
    brickArray.RemoveDead();  
}  

: 당신은 이제 모든 게임 객체의 기본 클래스로이 유형을 사용하는 경우, 당신이 쓸 수 있어야

class GameObject { 
    Point Position { get; set; } 
    Vector Velocity { get; set; } 
    Sprite Sprite { get; set; } 
    Rectangle Rect { 
    get { 
     // Ecnapsulated calculation of the bounding rectangle 
     return new Rectangle 
     ((int)Position.X + (int)Velocity.X - Sprite.Width/2, 
      (int)Position.Y + (int)Velocity.Y - Sprite.Height/2, 
      Sprite.Width, Sprite.Height); 
    } 
}  

기능을 나누기위한 아이디어 그 중 하나는 balplayer을 검사하고 다른 하나는 벽돌을 검사합니다.

관련 문제