Saturday, September 01, 2007

Rectangle Collisions

Very Important Note: You will see a red st in one of the if statements below. This stands for a smaller than sign "<". Make sure to put that instead. I had to put st because the web site uses html and it thinks I am trying to create a tag using html.
Note: All words in italics are names of things.
In this tutorial you will learn the basics of collision handling. What we want to accomplish in this tutorial is to make our sprite reverse directions when it hit’s either side of the screen. In order to accomplish this we need to create some kind of collision box around the sprite every time the game updates. Then we can check for a collision with the side of the screen and reverse the sprite’s direction accordingly.


In order to accomplish this there are a few steps we need to do:

Step 1 : Every update(every time the game calls the Update method) create a collision box around the sprite.
Step 2 : Check for collisions with the sprite and the screen.
Step 3 : Reverse the sprites direction if there is a collision.



Once we accomplish these steps we will hopefully have a sprite colliding with the screen borders.
Step 1 : Every update create a collision box around the sprite


First of all, we need to create a collision box around the sprite. Microsoft has provided us with a class that helps with this type of stuff. This class is called Rectangle. In order to create a rectangle that we can use for collision checking, we could do one of two things.

One idea is to create a rectangle around the sprite when we first start the game, and then every time the sprite moves, update the position of this rectangle.

Another idea is to only create a rectangle around the sprite when we are going to start collision checking That way, the rectangle is already at the current position of the sprite. I am going to use this method because that way I don’t have to worry about updating the position of the collision rectangle.


Now that we have decided what we are going to do, we can actually do it. Since we want to create the rectangle at the time we are going to check for collisions(every loop), we are going to put this code inside the Update method. Put this code before the call to move the sprite, but after the call to create speed.


Rectangle spriteCollisionRectangle = new Rectangle((int)spritePosition.X, (int)spritePosition.Y, myTexture.Width, myTexture.Height);


This code creates our rectangle around the sprite. First of all, we create a rectangle variable. Then we initialize the variable. You can see that we are calling the constructor of the rectangle class. This constructor needs two positions to create the rectangle at, and then the width and height the rectangle should be. In order to make a rectangle boxing in our sprite, we pass in the position of the sprite(the X and Y-coordinates), and then we pass in the width and height of the texture we are using. We get this by using the commands myTexture.Width and myTexture.Height. Notice we put (int) in front of the sprite positions. This is because the sprite positions(spritePosition.X and spritePosition.Y) when we try to use them return(give a value of) a float. The rectangle constructor only takes integers as it’s parameters so we have to convert the float into an integer(int). This is a process know as casting.


Now we have created our collision rectangle around our sprite. Every update loop this rectangle is re-created to be at the current position of the sprite.


Figure 1-1 The Creation of the Sprite’s Collision Rectangle

Step 2 : Check for collisions with the sprite and the screen

Now that we have a rectangle for our sprite, we can start to check for collisions. First lets make a variable to hold the rectangle for the screen. Put this code under your code for the sprite’s rectangle:

Rectangle screenRectangle = new Rectangle(0, 0, graphics.GraphicsDevice.Viewport.Width, graphics.GraphicsDevice.Viewport.Height);

This code creates a rectangle for our screen. First we put, 0, 0, which is always the position that the top left corner of the screen is at. Then we pass in the width and height of the screen by using the commands graphics.GraphicsDevice.Viewport.Width or graphics.GraphicsDevice.Viewport.Height.

Now that we have our screen rectangle created, it is time to check for collisions.

All we have to do to check for a collision is add an if statement. In order to check for a collision with the right side of the screen and the right side of the sprite, add this code underneath the rectangle variable declarations:

if(spriteCollisionRectangle.Right > screenRectangle.Right)
{

}

This code is your first if statement. First we place the word if. Then we place two parentheses after the if. Then inside of the two parentheses we write what we are checking for. We want to see if the right side of the sprite rectangle is at a greater position than the right side of the screen rectangle. We do this by accessing the right side position of these rectangles(rectangleName.Right), and checking their positions by using the > operator which checks if one value is greater than another.

Note : Using the command, rectangleName.Right, just gets the position of the right side of the rectangle.

After the if and the two parentheses, we just add two curly brackets. These brackets are where you would put any code that you want to be executed if the spriteCollisionRectangle’s right side is greater than the screenRectangle’s right side. We will fill these brackets in the next step. For now, lets just finish up checking for collisions.
Add this code to check for collisions with the left side of the screen and the left position of the sprite’s rectangle:

if(spriteCollisionRectangle.Left st screenRectangle.Left)
{
}

Notice that we have changed the > to a <. This is because we are checking for a collision with the left side of the screen. And since when you are moving left, your position is getting smaller so you need to put <. Note : If you put >= or <= the project will not work because then we are checking if the sprite rectangle’s side is greater or equal to the side of the screen and since we start out at position 0, 0, there is a collision from the start. In the end the sprite will end up not moving at all. If you really want to know why then post a comment.
Figure 1-2 The Screen Rectangle and If Statements

Step 3 : Reverse the sprites direction if there is a collision

Now that we have all the collision if statements down, all there is left to do is make those if statements change something. All we have to do is reverse the direction that the sprite is moving in. Place this code inside both sets of brackets following the if statements:

speed = -speed;

This code changes the speed that the sprite is moving by, to its opposite. Since the sprite’s X-position is being increased by speed, if speed equals 0.5(the sprite is moving right) then speed will be reversed to -0.5 which means the sprite’s position will be increased by -0.5 or in simpler words subtracted by 0.5(moving left).

Figure 1-3 The Code in the If Statements that Reverses the Sprite’s Direction

Now there is just one thing to fix. We need to stop recreating speed each time the Update method is called. This is because when we recreate speed, we are resetting its value to 0.5 which means that if none of the if statements return(end up as) true(say the sprite is in the middle of the screen so there are no collisions happening), then even if the sprite was moving left, the sprite would move right because when we recreate speed we are setting or more often re-setting it’s value to 0.5 which means moving right.

All we need to do to change this is move the creation of speed to the fields area. This will give speed an initial value of 0.5(moving right) but if we reverse the value of speed in an if statement, speed will keep that new value instead of constantly being reset to 0.5.

Move the, float speed = 0.5, in the Update method, up to where we placed our fields.


Figure 1-4 Moving Speed Up To Our Fields Area

Now if you test the project, the sprite will reverse it’s direction when it collides with the sides of the screen. You have now learned how to do some basic collision checking.

Figure 1-5 Finished Tutorial - The Sprite Just Bounced Off of the Right Side of the Screen

Finally, just change the initial value of speed to 5 so that we can get the sprite moving a bit faster:

Figure 1-6 Changing Speed to the Value of 5

If you have any requests or if parts of this tutorial were confusing post a comment.

Thanks for reading this tutorial.

You don’t need to live a life that has no point. God is offering you a free gift. Take it.

No comments: