2009-10-13 3 views
0

나는 "브레이크 아웃"게임을 만들었습니다. 작은 재미있는 측면 프로젝트.공과 벽돌 충돌 처리

이제는 보통 게임을 만들지 않으므로 충돌 처리는 내가 보통 생각하는 것이 아닙니다.

나는 외륜, 공 및 벽돌을 가지고 있습니다.

지금은 충돌이있을 때 (언급 한 각 객체 주위에 사각형을 그립니다) 공의 Y 값을 단순히 -Y로 변경합니다.

공이 측면 (동쪽 또는 서쪽)에서 벽돌을 치는 경우를 제외하고는 잘 작동합니다. 부작용은 꽤 아니며 게임 플레이를 파괴합니다.

저는 위의 기술 대신에 X 값을 -X로 변경해야한다고 생각합니다.

지금까지 내가 가진 : 각 개체 주위 if (ballRect.IntersectsWith(brickRect))

ballRectbrickRect되는 사각형을.

이제 벽돌의 동쪽 경계선, 서쪽 경계선 등을 사각형으로 만들면 어떻게 될까요? 나는 너비가 픽셀 정도라고 생각한다.

서부 또는 동부 직사각형에서 충돌이 발생하면 공 X 값은 -X 여야합니다. 그 반대의 경우도 마찬가지입니다.

그래도 코너는 어떻습니까? x 구석을 제어 할 직사각형을 무작위로 선택해야합니까?

또는 각 모서리 주위에 사각형을 만들어야합니까? 한면에 1 * 1 인 직사각형. 충돌 => -x AND -y 값이있는 경우?

의견을 말하십시오. 여기

지금까지 과정 :

foreach (var brick in Bricks) 
    { 
     if (brick.IsAlive) 
     { 
      var brickRect = new Rectangle(brick.X, brick.Y, BrickWidth, BrickHeight); 
      if (ballRect.IntersectsWith(brickRect)) //Ball has hit brick. lets find out which side of the brick 
      { 
       var brickRectNorth = new Rectangle(brick.X, brick.Y + BrickHeight, BrickWidth, 1); 
       var brickRectSouth = new Rectangle(brick.X, brick.Y, BrickWidth, 1); 

       var brickRectEast = new Rectangle(brick.X, brick.Y, 1, BrickHeight); 
       var brickRectWest = new Rectangle(brick.X + BrickWidth, brick.Y, 1, BrickHeight); 

       if (ballRect.IntersectsWith(brickRectNorth) || ballRect.IntersectsWith(brickRectSouth)) 
       { 
        //STUFF that makes ball.y = -ball.y 
       } 
       if (ballRect.IntersectsWith(brickRectWest) || ballRect.IntersectsWith(brickRectEast)) 
       { 
        //STUFF that makes ball.x = -ball.x 
       } 
      } 
     } 
    } 

답변

2

오히려 사각형의 교차점을 찾는 것보다, 내가 실제 모서리를 교차하는 것입니다. 모서리에서 볼이 두 모서리를 동시에 만지고 있으므로 모션 벡터는 두 가지 모서리의 영향을 받아야합니다.

외곽 루프에서 테스트해야하는 사각형 수를 줄이기는했지만 충돌이 감지되면 내부 루프로 이동하여 충돌 탐지를 위해 하나의 사각형을 유지합니다. 가장자리 그것은 맞았다. 각 모서리를 테스트하고 각 모서리에 따라 벡터를 조정하면 모서리가 자유롭게 나타납니다 (첫 번째 교차 모서리를 찾을 때 루프에서 빠져 나오지 않는 한).

편집 : 업데이트 된 질문에 대한 응답에서 :

사실, 이것이 내가 어떻게 할 것입니다 (즉, 내가 아래에 가정 한 것입니다 귀하의 코드를 부여,이, C# 3.0로 표시) :

foreach(var brick in Bricks) { 
    if(brick.IsAlive) { 
     var brickRect = new Rectangle(brick.X, brick.Y, BrickWidth, BrickHeight); 
     if(ballRect.IntersectsWith(brickRect)) { 
      // Ball has hit brick. Now let's adjust the ball's vector accordingly 

      // Convenience variables. Compiler will probably inline. 
      var brickLeft = brick.X; 
      var brickRight = brick.X + BrickWidth; 
      var brickTop = brick.Y; 
      var brickBottom = brick.Y + BrickHeight; 

      var ballLeft = ball.X - ball.Radius; 
      var ballRight = ball.X + ball.Radius; 
      var ballTop = ball.Y - ball.Radius; 
      var ballBottom = ball.Y + ball.Radius; 

      // Test which vector(s) we need to flip 
      bool flipX = (ballRight >= brickLeft || ballLeft <= brickRight); 
      bool flipY = (ballTop >= brickBottom || ballBottom <= brickTop); 

      // Flip the vectors (there are probably ways to optimize this, 
      // too, but without seeing your code I can't tell). 
      if(flipY) { 
       // Stuff that makes ball.y = -ball.y 
      } 

      if(flipX) { 
       // Stuff that makes ball.x = -ball.x 
      } 
     } 
    } 
} 

기본적으로, 요점은 이미 공은 실제로 벽돌을 교차 알고 있기 때문에, 당신은 훨씬 빠릅니다 간단한 박스 테스트로 간단하게 할 수 있다는 것입니다. 또한 가장자리에 추가 사각형을 만들 필요가 없습니다. 이미 가지고있는 사각형의 가장자리를 사용하십시오.

+0

의견에 감사드립니다. 나는 그것의 생각하지 않았다 – CasperT

+0

나는 나의 포스트를 새롭게했다. 이게 당신이 의미 한거야? – CasperT

+0

안녕하세요. 볼은 직사각형입니다 (일식으로 그려져 있지만). 반지름은 입니다. int ballRadius = BallSize/2; // 물건에 대해서 ... 나는 기본적으로 플레이어에게 솜씨 포인트를주고, 벽돌을 죽이는 등의 많은 일을 기본적으로 수행합니다. 결국, 문자 그대로 글을 씁니다. BallDirection = new Point (-BallDirection.X, BallDirection.Y); // x = -x 코드에서 나에게 아주 이상한 결과를 제공하지만 좀 더 살펴볼 것입니다. – CasperT

관련 문제