2009-10-13 121 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