Processing velocity vectors during a collision as accurately as possible

I am trying to create a good way to handle all possible collisions between two objects. Usually one will move and hit the other, and then “bounce”.

What I have done so far (I am creating a typical game in which you have a board and bounces the ball in bricks), you need to check if the rectangles intersect, and if they do, invert the Y-speed.

This is really an ugly and temporary solution that will not work in the long run, and since this is a kind of processing very common in games, I would really like to find a great way to do this for future projects. Any links or useful information are appreciated.

Below is my collision handling function.

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.Xb.sprite.Width/2); b.rect.Y = Convert.ToInt32(b.position.Yb.sprite.Height/2); if (bal.rect.Intersects(b.rect)) { b.recieveHit(); bal.velocity.Y *= -1; } } brickArray.removeDead(); } 
+4
source share
1 answer

Here are some suggestions that might help.

First of all, all your objects, such as Player , Bal (not sure what it is), and Brick have a somewhat similar interface - they all have sprite (determining the size of the object), rect (bounding box of the object), position (current position), velocity (current speed). This suggests that you can create a common base class to encapsulate this function.

Also note that you always re-read rect based on current position and sprite . This suggests that rect should actually be a property that hides the recount (which is always the same!)

So, you can start by defining a common base class like this (I will follow the standard .NET coding standard and use CamelCase properties and names):

 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); } } 

If you are now using this type as a base class for all of your game objects, you should be able to write this:

 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(); } 

It's also nice to split a function between two - one that checks Bal and Player , and the other that checks bricks.

+1
source

Source: https://habr.com/ru/post/1305892/


All Articles