0
votes

I am having difficulties getting my collision detection algorithm to work properly. I am reading in data from a .txt that contains 0s and 1s (0s are empty spaces 1s cannot be walked through). My algorithm catches sometimes other times it doesn't and ultimately is not working. My current algorithm is posted below where sep is a separation value to keep my spirits from overlapping.

private void collisionDetect()
{
    float diffxleft, diffxright, diffytop, diffybottom;
    float diffx, diffy;

    hit = false;
    foreach (Block b in blocks)
    {
        if (hit)
            break;
        if (inside(charPos, sep, b))
        {
            hit = true;
            diffxleft = Math.Abs(charPos.X + sep - b.pos.X);
            diffxright = Math.Abs(charPos.X - sep - (b.pos.X + b.rect.Width));
            diffytop = Math.Abs(charPos.Y + sep - b.pos.Y);
            diffybottom = Math.Abs(charPos.Y - sep - (b.pos.Y + b.rect.Height));
            diffx = Math.Min(diffxleft, diffxright);
            diffy = Math.Min(diffytop, diffybottom);
            if (diffx < diffy)
            {
                charVel.X = 0;
                if (diffxleft < diffxright)
                    charPos.X = b.pos.X - sep;
                else
                    charPos.X = b.pos.X + b.rect.Width + sep;
            }
            else
            {
                charVel.Y = 0;
                if (diffytop < diffybottom)
                    charPos.Y = b.pos.Y - sep;
                else
                    charPos.Y = b.pos.Y + b.rect.Height + sep;
            }
        }
    }

    foreach (Block b in blocks)
    {
        b.disp.X = b.pos.X + 10 - bkgdisplay.X;
        b.disp.Y = 470 - b.pos.Y;
    }
    charPosDisp.X = charPos.X - bkgdisplay.X;
    charPosDisp.Y = 480 - charPos.Y;
}

Help!

1
Could you be a little clearer about what exactly isn't working? Does it just not detect X collisions sometimes, or does it not detect Y collisions, or both? Or does it detect the collisions but not keep the player from moving through the "spaces"?davidsbro
From best I can tell it's sometimes not detecting either at times and others its creating walls where there are not any. My player is able to walk through some of the walls that they're not supposed to be able to and others he's blocked by walls that aren't actually drawn..user2966964

1 Answers

1
votes

I would change how you handle the collisions slightly to make it easier to read and implement.

Say for each block(or tile) the 0 or 1 value represents whether the block is collidable or not. You can then use an intersect method between the block position and sprite position to see if they are currently intersecting. If they do intersect and the boolean for the tile is set to 1 then we have a collision and you can then handle the collision i.e. stop sprite moving, bounce it back etc. If the value is 0 then the sprite can be moved over the current block position.

This is easy to implement using the following pseudo-code.

Step 1: Read in the value for the block and set a boolean member variable in the class to say if it is collidable or not i.e Parse Value from string, if value is 0 then bool = false else bool = true.

Step 2: Created a method in the block class to return the collidable member variable and which would do something like bool is_collidable() const { return collide; }

Step 3: Use the Rectangle.Intersect method between the sprite rect and the block rect.

Step 4: After seeing if we have an intersection between block and sprite then test the block member variable to see if it is true or false.

Step 5: If value is true then we cannot pass over the tile, otherwise we can.