Difference between revisions of "Rectangle Bounds Collision"
(→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 | + | // 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> | ||
− | + | ||
// 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> | ||
− | // | + | //Set the X & Y before the move |
− | + | int x=ppos.X; | |
− | if ( | + | 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; | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> |
Latest revision as of 12:10, 24 May 2024
Contents
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:
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;
}