Difference between revisions of "Rectangle Bounds Collision"

From TRCCompSci - AQA Computer Science
Jump to: navigation, search
(Checking if they overlap)
 
(5 intermediate revisions by the same user not shown)
Line 1: Line 1:
 +
=Introduction=
 +
The textures & images used within your game have a position, and create a rectangle from that position using the height and width of the image or texture. For walls or platforms this is fine because they tend to fit well with a rectangle, however it will create a poor game if you use this method for characters. For example the image below shows a collision when only the rectangle bounds are used:
 +
 +
[[File:Rectangle collision.gif]]
 +
 +
This is because the character with the sword has a transparent background which extends out beyond the other pixels, the same is true for the character in the suit.
 +
 
==Characters==
 
==Characters==
 
I have declared the following Textures & 2 vectors to control the position of these:
 
I have declared the following Textures & 2 vectors to control the position of these:
Line 58: Line 65:
 
==Create Player Rectangle==
 
==Create Player Rectangle==
 
<syntaxhighlight lang=csharp>
 
<syntaxhighlight lang=csharp>
// Get bounds of enemy
+
// Get bounds of player
 
             Rectangle playerRectangle = new Rectangle((int)ppos.X, (int)ppos.Y, player.Width, player.Height);
 
             Rectangle playerRectangle = new Rectangle((int)ppos.X, (int)ppos.Y, player.Width, player.Height);
 
</syntaxhighlight>
 
</syntaxhighlight>
Line 75: Line 82:
 
Now we have the 2 rectangles you can check if they are touching or overlap. This can be done by checking for intersection.
 
Now we have the 2 rectangles you can check if they are touching or overlap. This can be done by checking for intersection.
 
<syntaxhighlight lang=csharp>
 
<syntaxhighlight lang=csharp>
// Get bounds of enemy
+
 
 
             // Check bounds of enemy with player
 
             // Check bounds of enemy with player
 
             if (playerRectangle.Intersects(enemyRectangle))
 
             if (playerRectangle.Intersects(enemyRectangle))
Line 86: Line 93:
 
My example altered the movement values changed before the collision detection:
 
My example altered the movement values changed before the collision detection:
 
<syntaxhighlight lang=csharp>
 
<syntaxhighlight lang=csharp>
// Get bounds of enemy
+
            //Set the X & Y before the move
             // Check bounds of enemy with player
+
            int x=ppos.X;
             if (playerRectangle.Intersects(enemyRectangle))
+
            int y=ppos.Y;
 +
 
 +
             if (currentKeyboardState.IsKeyDown(Keys.Left))
 +
            {
 +
                ppos.X += playerMoveSpeed;
 +
            }
 +
 
 +
             if (currentKeyboardState.IsKeyDown(Keys.Right))
 
             {
 
             {
                 if (currentKeyboardState.IsKeyDown(Keys.Left))
+
                 ppos.X -= playerMoveSpeed;
                {
+
            }
                    ppos.X += playerMoveSpeed;
 
                }
 
  
                if (currentKeyboardState.IsKeyDown(Keys.Right))
+
            if (currentKeyboardState.IsKeyDown(Keys.Up))
                {
+
            {
                    ppos.X -= playerMoveSpeed;
+
                ppos.Y += playerMoveSpeed;
                }
+
            }
  
                if (currentKeyboardState.IsKeyDown(Keys.Up))
+
            if (currentKeyboardState.IsKeyDown(Keys.Down))
                {
+
            {
                    ppos.Y += playerMoveSpeed;
+
                ppos.Y -= playerMoveSpeed;
                }
+
            }
  
                if (currentKeyboardState.IsKeyDown(Keys.Down))
+
            //Check bounds of enemy with player
                {
+
            if (playerRectangle.Intersects(enemyRectangle))
                    ppos.Y -= playerMoveSpeed;
+
            {
                 }
+
                ppos.X = X;
 +
                 ppos.Y = Y;
 
             }
 
             }
  
 
</syntaxhighlight>
 
</syntaxhighlight>

Latest revision as of 13:10, 24 May 2024

Introduction

The textures & images used within your game have a position, and create a rectangle from that position using the height and width of the image or texture. For walls or platforms this is fine because they tend to fit well with a rectangle, however it will create a poor game if you use this method for characters. For example the image below shows a collision when only the rectangle bounds are used:

Rectangle collision.gif

This is because the character with the sword has a transparent background which extends out beyond the other pixels, the same is true for the character in the suit.

Characters

I have declared the following Textures & 2 vectors to control the position of these:

        Texture2D enemy;
        Texture2D player;
        Vector2 ppos, epos;

In reality your project will probably create a class for player and a class for enemy. This will then include the texture, position and so on for your character. For simplicity and for the fear of giving you a complete player class definition, or to give you a complete collision detection method, I will show you how to check for a collision between two object by creating bounding rectangles and checking for an intersection.

In the Initialize method for the game I have set the position vectors for my player and enemy:

            ppos = new Vector2(0, 0);
            epos = new Vector2(300, 300);
            // Set a constant player move speed
            playerMoveSpeed = 8.0f;

Player Movement

I have already created the basic player movement:

            if (GamePad.GetState(PlayerIndex.One).Buttons.Back ==
                ButtonState.Pressed || Keyboard.GetState().IsKeyDown(
                Keys.Escape))
                Exit();

            // Save the previous state of the keyboardso we can determine single key presses
            previousKeyboardState = currentKeyboardState;

            // Read the current state of the keyboard and store it
            currentKeyboardState = Keyboard.GetState();

            if (currentKeyboardState.IsKeyDown(Keys.Left))
            {
                ppos.X -= playerMoveSpeed;
            }

            if (currentKeyboardState.IsKeyDown(Keys.Right))
            {
                ppos.X += playerMoveSpeed;
            }

            if (currentKeyboardState.IsKeyDown(Keys.Up))
            {
                ppos.Y -= playerMoveSpeed;
            }

            if (currentKeyboardState.IsKeyDown(Keys.Down))
            {
                ppos.Y += playerMoveSpeed;
            }

This is from the Update method. It will allow your player to move around, you can't have collisions if you can't move.

Create Player Rectangle

// Get bounds of player
            Rectangle playerRectangle = new Rectangle((int)ppos.X, (int)ppos.Y, player.Width, player.Height);

The (int) is an example of casting, this will convert the value ppos.X to an integer. The rectangle points are its X & Y (ie top right corner), and then the width and height are used to get the bottom left corner.

Create Enemy Rectangle

// Get bounds of enemy
            Rectangle enemyRectangle = new Rectangle((int)epos.X, (int)epos.Y, enemy.Width, enemy.Height);

This is the same as above except using the enemy.

Checking if they overlap

Now we have the 2 rectangles you can check if they are touching or overlap. This can be done by checking for intersection.

            // Check bounds of enemy with player
            if (playerRectangle.Intersects(enemyRectangle))
            {
                  YOUR PROGRAM SHOULD DO SOMETHING HERE A COLLISION HAS HAPPENED
            }

My example altered the movement values changed before the collision detection:

            //Set the X & Y before the move
            int x=ppos.X;
            int y=ppos.Y;

            if (currentKeyboardState.IsKeyDown(Keys.Left))
            {
                ppos.X += playerMoveSpeed;
            }

            if (currentKeyboardState.IsKeyDown(Keys.Right))
            {
                ppos.X -= playerMoveSpeed;
            }

            if (currentKeyboardState.IsKeyDown(Keys.Up))
            {
                ppos.Y += playerMoveSpeed;
            }

            if (currentKeyboardState.IsKeyDown(Keys.Down))
            {
                ppos.Y -= playerMoveSpeed;
            }

            //Check bounds of enemy with player
            if (playerRectangle.Intersects(enemyRectangle))
            {
                ppos.X = X;
                ppos.Y = Y;
            }