2D Per pixel collision detection not working

Jonathan Dunn

I would like to say sorry in advance for the amount of code I will post, but I can't seem to get my collision detection to work, the player and the objects pass through each other with no effect when I play test.

I receive 0 warnings or errors, but the Player playerBot object does not seem to interact with any of the level items I have imported from GLEED2D.

One thing I did was to store the values of my item's rectangles and color arrays in lists so they could be all easily iterated through, maybe this is the source of the problem.

If you can spot why my code is not working I will be hugely grateful. I have removed any code that is definitely not relevant, and I am running VS 2010 with GLEED2D 1.3 if that helps.

Thanks again.

// Item Class ImageItem Downcast
public class ImageItem : Item
{
    public Texture2D Texture;
}

// Level
Level level;

// Ints
int iNumOfItems = 0;
int iTextureDataListNum = 0;
int iRectangleListNum = 0;

// Lists
List<Color []> itemTextureDataList = new List<Color[]>();
List<Rectangle> itemRectangleList = new List<Rectangle>();

protected override void Initialize()
{
    if (filename.Length > 0) level = Level.FromFile(filename, Content);
    else level = Level.FromFile("level1.xml", Content);

    foreach (Layer layer in level.Layers)
    {
        foreach (Item item in layer.Items)
        {
            iNumOfItems =+ 1;
        }
    }

    // Creates Player Ship
    playerBot = new Player(new Vector2(400f, 240f), new Vector2(0f, 0f));

    base.Initialize();
}

protected override void LoadContent()
{
    Texture2D pixel = new Texture2D(GraphicsDevice, 1, 1, false, SurfaceFormat.Color);
    pixel.SetData(new[] { Color.White });
    spriteBatch = new SpriteBatch(GraphicsDevice);

    // Player Bot
    playerBot.LoadContent(Content, "Images/Player Bot Sprite Sheet", 40, 40, 4);

    // Assigns level textures color data to array
    foreach (Layer layer in level.Layers)
    {
        foreach (Item item in layer.Items)
        {
            ImageItem imageItem = item as ImageItem;
            if (imageItem != null)
            {
                Texture2D texture = imageItem.Texture;

                itemTextureDataList[iTextureDataListNum] = new Color[imageItem.Texture.Width * imageItem.Texture.Height];
                imageItem.Texture.GetData(itemTextureDataList[iTextureDataListNum]);
                iTextureDataListNum++;
            }
        }
    }

    // Creates a rectangle for every level texture
    foreach (Layer layer in level.Layers)
    {
        foreach (Item item in layer.Items)
        {   
            ImageItem imageItem = item as ImageItem;
            if (imageItem != null)
            {
                itemRectangleList[iRectangleListNum] = new Rectangle((int)imageItem.Position.X, (int)imageItem.Position.Y, imageItem.Texture.Width, imageItem.Texture.Height);
                iRectangleListNum++;
            }
        }
    }

    spriteBatch = new SpriteBatch(GraphicsDevice);
}

protected override void Update(GameTime gameTime)
{
    // Player Update
    playerBot.Update(gameTime);
    ((Sprite)playerBot).Update(gameTime);

    // Check for player collisons with level
    for (int i = 0; i < iNumOfItems - 1; i++)
    {
        if (IntersectPixels(playerBot.colRectangle, playerBot.textureDataArray, itemRectangleList[i], itemTextureDataList[i]) == true)
        {
            playerBot.StopMovement();
        }
    }

    base.Update(gameTime);
}

// Level Collision Detection Method

static bool IntersectPixels(Rectangle rectangleA, Color[] dataA, Rectangle rectangleB, Color[] dataB)
{
    // Find the bounds of the rectangle intersection
    int top = Math.Max(rectangleA.Top, rectangleB.Top);
    int bottom = Math.Min(rectangleA.Bottom, rectangleB.Bottom);
    int left = Math.Max(rectangleA.Left, rectangleB.Left);
    int right = Math.Min(rectangleA.Right, rectangleB.Right);

    // Check every point within the intersection bounds
    for (int y = top; y < bottom; y++)
    {
        for (int x = left; x < right; x++)
        {
            // Get the color of both pixels at this point
            Color colorA = dataA[(x - rectangleA.Left) + (y - rectangleA.Top) * rectangleA.Width];
            Color colorB = dataB[(x - rectangleB.Left) + (y - rectangleB.Top) * rectangleB.Width];

            // If both pixels are not completely transparent
            if (colorA.A != 0 && colorB.A != 0)
            {
                // Then an intersection has been found
                return true;
            }
        }
    }

    // No intersection fond
    return false;
}

// Sprite Class

public void Update(GameTime gameTime)
{
    textureDataArray = new Color[texture.Width * texture.Height];
    texture.GetData(textureDataArray);

// Player Class

public void StopMovement()
{
    velocity.X *= -1;
    velocity.Y *= -1;
}
Steve Lillis

The first thing I'll say here is, you should aim to be more Object Oriented in your approach. Storing a list of textures and a list of rectangles alongside your list of Items is "bad" technique and going to eventually cause you some massive headaches when it comes to debugging.

So first of all, instead of having a list of Color[] and a list of Rectangle, add one Color[] and one Rectangle to your ImageItem class and work with those instead, or at least create a little class called "CollisionData" that has a Rectangle and a Color[] and store those in a single list.

Secondly, note that there is a Rectangle.Intersect(Rectangle A, Rectangle B) that gets your the rectangle of intersection. So you can tidy up your code a bit by using that.

Your color checking can be simplified to (ColorA.A * ColorB.A != 0) as either being zero will cause the result to be zero.

Regarding not getting any errors, put a breakpoint at the start of the collision checking loop. Does the application break? If yes, what is the value of iNumItems? (you can hover over it to see the current value at point of breaking). If no, then that section of code isn't being reached. Put another breakpoint a bit further back and a bit further back until it gets hit, then figure out why the code isn't executing.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

C# - Per Pixel Collision Detection

From Dev

2D Collision detection not working

From Dev

Collision detection not working in Unity 2D

From Dev

Collision Detection in Java 2D Not Working Properly

From Dev

Rotating Images & Pixel Collision Detection

From Java

Collision detection in pygame not working

From Dev

Collision detection not working?

From Dev

Collision detection in java 2d game

From Dev

Unity 2d collision detection not registering

From Dev

Trouble with java 2D collision detection

From Dev

Unity 2D Collision Detection

From Dev

PyGame border collision detection not working

From Dev

Pygame Jumper collision detection not working

From Dev

Collision Detection on 2 objects

From Dev

Collision Detection Javascript Not Working(rather Im not working)

From Dev

HTML Canvas game: 2D collision detection

From Dev

What is the logic behind collision detection in 2d games?

From Dev

Collision detection in a 2D maze with thick walls

From Dev

Collision detection in 2D game without tiles XNA

From Dev

2D Monogame: Rectangle collision detection, side specific

From Dev

Issue with Collision Detection in Pygame for simple 2D Platformer

From Dev

Collision Detection with Ceramic Tile Engine & Box 2D

From Dev

Collision detection in 2D game without tiles XNA

From Dev

How to react on collision detection in 2d platformers

From Dev

2D Monogame: Rectangle collision detection, side specific

From Dev

Is there pixel perfect collision detection for Sprite Kit (iOS7)?

From Dev

Pixel Perfect Collision detection between a custom view and an ImageView

From Dev

Collision Detection hitTestObject not working.. ish

From Dev

JavaScript Collision Detection doesn't seem to be working?

Related Related

HotTag

Archive