Reputation:
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.
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
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