private void Collisions() { Rectangle bounds = BoundingRect; int left = (int)Math.Floor((float)bounds.Left / Tiles.TileWidth); int right = (int)Math.Ceiling(((float)bounds.Right / Tiles.TileWidth)) - 1; int top = (int)Math.Floor((float)bounds.Top / Tiles.TileHeight); int bottom = (int)Math.Ceiling(((float)bounds.Bottom / Tiles.TileHeight)) - 1; // Reset flag to search for ground collision. isGround = false; // For each potentially colliding tile, for (int y = top; y <= bottom; ++y) { for (int x = left; x <= right; ++x) { // If this tile is collidable, TilesCollision collision = Level.Collision(x, y); if (collision != TilesCollision.Passable) { // Determine collision depth (with direction) and magnitude. Rectangle tileBounds = Level.Bounds(x, y); Vector2 depth = RectangleExtensions.IntersectionDepth(bounds, tileBounds); if (depth != Vector2.Zero) { float absDepthX = Math.Abs(depth.X); float absDepthY = Math.Abs(depth.Y); // Resolve the collision along the shallow axis. if (absDepthY < absDepthX || collision == TilesCollision.Platform) { // If we crossed the top of a tile, we are on the ground. if (PrevBottom <= tileBounds.Top) { isGround = true; } // Ignore platforms, unless we are on the ground. if (collision == TilesCollision.Impassable || IsGround) { // Resolve the collision along the Y axis. Position = new Vector2(Position.X, Position.Y + depth.Y); // Perform further collisions with the new bounds. bounds = BoundingRect; } } else if (collision == TilesCollision.Impassable) // Ignore platforms. { // Resolve the collision along the X axis. Position = new Vector2(Position.X + depth.X, Position.Y); // Perform further collisions with the new bounds. bounds = BoundingRect; } else if (collision == TilesCollision.Lava) { level.Restart(); health -= 1; if (health <= 0) { Kill(null); } } } } } } PrevBottom = bounds.Bottom; }