RecentComments

Comment RSS

XNA 2D Basic Collision Detection with Rotation (Scene2Sprite)

by Ioannis 16. February 2010 07:54

In the previous post we have worked with collision detection between roated sprites. In this post we will deal with the situtation where we want to detect whether a specific sprite that can be rotated is in a specific area in the scene (eg a car is on the road in the scene).

Suppose that you have the following scenario:

 

A car is driven by the user around the scene. When the car hits the boundaries of the road, the car should lose all of its speed. The user uses the UP/DOWN keys to acelerate/break and LEFT/RIGHT for steering.

You want to detect the situation where the car is going out of the road bounds. A way to do this is as follows:

Use a second texture of the road, one that you will use for collision detection which has a specific plain color for the road:

Then get the bounding rectangle of the rotated texture that is parallel to the window's axis:

Within this rectangle check whether there is one point that is on the car's texture but the equivalent point on the road texture is not gray.

This programmatically is achieved as follows:

To get a rotated texture alone from scene, you use an additional back-buffer where you draw the rotated car's texture and then get a snapshot of it. The AdditionalRenderTargetForCollision is initialized once in the main game loop (download the project to see how):

public static RenderTarget2D AdditionalRenderTargetForCollision { get; set; }

private static Color[] _getSingleSpriteAloneFromScene(SpriteBatch spriteBatch,Texture2D textureToDraw,
                             Vector2 Position,Vector2 Origin,float Theta,List<Vector2> RectanglePoints)
{
    spriteBatch.GraphicsDevice.SetRenderTarget(0, AdditionalRenderTargetForCollision);
    spriteBatch.GraphicsDevice.Clear(Color.Black);
    spriteBatch.Begin();
    spriteBatch.Draw(textureToDraw, Position, null, Color.White, 
                                     Theta, Origin, 1.0f, SpriteEffects.None, 0);
    spriteBatch.End();
    spriteBatch.GraphicsDevice.SetRenderTarget(0, null);
    Texture2D SceneTexture = AdditionalRenderTargetForCollision.GetTexture();
    Rectangle BoundingRectangle = _getBoundingRectangleOfRotatedRectangle(RectanglePoints);
    int PixelSize = BoundingRectangle.Width * BoundingRectangle.Height;
    Color[] TextureData = new Color[PixelSize];
    SceneTexture.GetData(0, BoundingRectangle, TextureData, 0, PixelSize);

    return TextureData;
}

The code that checks for bounds is as follows:

public static bool SpriteIsOnValidArea(Texture2D TextureScene, Texture2D TextureSprite, Vector2 PosSprite, Vector2 OrigSprite, List<Vector2> RectSprite,float ThetaSprite,SpriteBatch spriteBatch,Color OKColor)
 {
     Color[] TextureDataSprite = _getSingleSpriteAloneFromScene(spriteBatch, TextureSprite, PosSprite, OrigSprite, ThetaSprite, RectSprite);
     Color[] TextureDataScene =  new Color[TextureScene.Width*TextureScene.Height];
     TextureScene.GetData(TextureDataScene);


     Rectangle RectangleSpriteBounding = _getBoundingRectangleOfRotatedRectangle(RectSprite);
     for (int i = RectangleSpriteBounding.Top; i < RectangleSpriteBounding.Bottom; i++)
         for (int j = RectangleSpriteBounding.Left; j < RectangleSpriteBounding.Right; j++)
             if (TextureDataScene[i * TextureScene.Width + j] != OKColor && TextureDataSprite[(i-RectangleSpriteBounding.Top) *
                 RectangleSpriteBounding.Width + (j-RectangleSpriteBounding.Left)] != new Color(0,0,0,0))
                 return false;
    
     return true;
 }

 

The code initially gets the car's rotated texture and the scene's texture. It then uses a method to calculate the bounding rectangle of the rotated sprite's texture. Then, within this rectangle it tests for the sprite's pixels one by one. If it locates even one texture's point that is not on the selected color (OKColor) it returns false (the car is out of bounds).

The project that performs this kind of collision detection can be downloaded here.

kick it on DotNetKicks.com

Shout it

Tags:

XNA

Comments

2/16/2010 6:46:26 PM #

trackback

XNA 2D Basic Collision Detection with Rotation (Scene2Sprite)

You've been kicked (a good thing) - Trackback from DotNetKicks.com

DotNetKicks.com

2/16/2010 6:49:04 PM #

trackback

C# and .NET Tips and Tricks | XNA 2D Basic Collision Detection with Rotation (Scene2Sprite)

Thank you for submitting this cool story - Trackback from DotNetShoutout

DotNetShoutout

Add comment


(Will show your Gravatar icon)

Enter the word
CAPTCHA word
Add 1 to the number above


  Country flag

biuquote
  • Comment
  • Preview
Loading



Powered by BlogEngine.NET 1.5.0.7

Programming Blogs - BlogCatalog Blog Directory Add to Technorati Favorites

MVP Award

Ioannis Panagopoulos





This blog is using BlogEngine.Net and is hosted in the hoster below. I have not experienced any problems installing BlogEngine.Net in the host and I am satisfied with the host's response times. Therefore I recommend it.


DiscountASP Add