user4329506
user4329506

Reputation:

Rectangles don't collide correctly

Collison

As you can see on the top corner it says COL: False/True. This is if the player bounds and the tiles which are solids. The rectangles for the tiles and players are checked if they intercept each-other. Looks like its working right? Well nope. Look more closely.

NotWorking NotWorking

The BOTTOM RIGHT corner needs to be inside the tiles for it to count.

Now let's get to the code I used now that hopefully you understand the problem.

Player Bounds (Rectangle)

playerBounds.Width = 32;
playerBounds.Height = 64;
playerBounds.X = (int)this.position.X;
playerBounds.Y = (int)this.position.Y;

Tile Bounds (Rectangle)

newTile.bounds = new Rectangle(x * TILE_SIZE, y * TILE_SIZE, TILE_SIZE, TILE_SIZE);

Now onto how it detects it:

for (int x = 0; x < Tilemap.MAP_WIDTH; x++)
        {
            for (int y = 0; y < Tilemap.MAP_HEIGHT; y++)
            {

                if (tm.tile[x, y].bounds.Intersects(playerBounds))
                {
                    if (tm.tile[x, y].getSolid())
                    {
                        Colliding = true;
                    } else
                    {
                        Colliding = false;
                    }
                }
            }

        }

Move

    public void Move(Vector2 pos)
    {
        for (int i = 0; i < speed; i++)
        {

            position += pos;
        }

    }

I have used breakpoints at the collision detection loop. And the rectangle fully covers the character and the tiles.

Upvotes: 0

Views: 105

Answers (1)

Nico Schertler
Nico Schertler

Reputation: 32627

You are overriding previous collisions in your loop. The result will always be the solid-state of the last tile that intersects with the player. Try an adaptation like this:

Colliding = false;
for (int x = 0; x < Tilemap.MAP_WIDTH; x++)
{
    for (int y = 0; y < Tilemap.MAP_HEIGHT; y++)
    {
        if (tm.tile[x, y].bounds.Intersects(playerBounds) && tm.tile[x, y].getSolid())
        {
            Colliding = true;
            break;                    
        }
    }
    if(Colliding)
        break;
}

A more efficient approach would only check the tiles that actually intersect. Since you use simple axis-aligned rectangles, the set of intersecting tiles should not be hard to calculate.

Upvotes: 1

Related Questions