2009-10-13 155 views
0

我已經做了遊戲「突圍」。一個有趣的小項目。球和磚碰撞處理

現在,我通常不製作遊戲,因此碰撞處理不是我通常想到的。

我有一個槳,一個球和一些磚。現在,當發生碰撞時(我在提到的每個對象周圍繪製矩形),我只需將球的Y值更改爲-Y即可。

這工作正常,除非球從側面(無論是東或西)擊中一塊磚。副作用並不美麗,並破壞遊戲玩法。

我想我可以放心地假設,而不是上述技術,當發生這種情況時,我需要將X值更改爲-X。

到目前爲止,我有:if (ballRect.IntersectsWith(brickRect))

ballRectbrickRect周圍的每個對象爲矩形。

現在,如果我在磚塊,西部邊界等的東部邊界周圍創建了一個矩形,該怎麼辦?我猜這個寬度大約是一個像素。

如果碰撞發生在西方或東方的矩形中,那麼球的X值應該是-X。 反之亦然。

雖然角落呢?我應該隨機選擇哪個矩形來控制x角?

或者我應該在每個角上做一個矩形?該矩形在邊上是1 * 1。 如果碰撞=> -x和-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 2009-10-13 19:05:30

+0

我已經更新了我的帖子。這是你的意思嗎? – CasperT 2009-10-13 22:21:49

+0

嗨。球是一個矩形(雖然畫爲日食)。所以半徑是: int ballRadius = BallSize/2; 關於//東西......我基本上只是做了很多事情,比如給玩家一些分數,殺死磚塊等等。最後,它直接寫道: BallDirection = new Point(-BallDirection.X,BallDirection.Y); // x = -x 你的代碼給了我一些非常奇怪的結果,但我會再看看它 – CasperT 2009-10-14 10:18:20