/// <summary> /// gets a List of all the TiledTiles that intersect the passed in Rectangle. The returned List can be put back in the pool via ListPool.free. /// </summary> /// <returns>The tiles intersecting bounds.</returns> /// <param name="bounds">Bounds.</param> public new List <TiledTile> GetTilesIntersectingBounds(Rectangle bounds) { // Note that after transforming the bounds to isometric, top left is the left most tile, bottom right is the right most, top right is top most, bottom left is bottom most var topLeft = TiledMap.IsometricWorldToTilePosition(bounds.X, bounds.Y); var bottomLeft = TiledMap.IsometricWorldToTilePosition(bounds.X, bounds.Bottom); var topRight = TiledMap.IsometricWorldToTilePosition(bounds.Right, bounds.Y); var bottomRight = TiledMap.IsometricWorldToTilePosition(bounds.Right, bounds.Bottom); var tilelist = ListPool <TiledTile> .Obtain(); // Iterate in larger isometric rectangle that definitely includes our smaller bounding rectangle for (var x = topLeft.X; x <= bottomRight.X; x++) { for (var y = topRight.Y; y <= bottomLeft.Y; y++) { var tile = GetTile(x, y); // Check if tile collides with our bounds if (tile != null && bounds.Contains(TiledMap.IsometricTileToWorldPosition(x, y))) { tilelist.Add(tile); } } } return(tilelist); }
public override void Draw(Batcher batcher, Vector2 position, float layerDepth, RectangleF cameraClipBounds) { // offset render position by the layer offset, used for isometric layer depth position += Offset; // offset it by the entity position since the tilemap will always expect positions in its own coordinate space cameraClipBounds.Location -= position; if (TiledMap.requiresLargeTileCulling) { // we expand our cameraClipBounds by the excess tile width/height of the largest tiles to ensure we include tiles whose // origin might be outside of the cameraClipBounds cameraClipBounds.Location -= new Vector2(TiledMap.LargestTileWidth, TiledMap.LargestTileHeight - TiledMap.TileHeight); cameraClipBounds.Size += new Vector2(TiledMap.LargestTileWidth, TiledMap.LargestTileHeight - TiledMap.TileHeight); } Point min, max; min = new Point(0, 0); max = new Point(TiledMap.Width - 1, TiledMap.Height - 1); // loop through and draw all the non-culled tiles for (var y = min.Y; y <= max.Y; y++) { for (var x = min.X; x <= max.X; x++) { var tile = GetTile(x, y); if (tile == null) { continue; } var tileworldpos = TiledMap.IsometricTileToWorldPosition(x, y); if (tileworldpos.X < cameraClipBounds.Left || tileworldpos.Y < cameraClipBounds.Top || tileworldpos.X > cameraClipBounds.Right || tileworldpos.Y > cameraClipBounds.Bottom) { continue; } var tileRegion = tile.TextureRegion; // culling for arbitrary size tiles if necessary if (TiledMap.requiresLargeTileCulling) { // TODO: this only checks left and bottom. we should check top and right as well to deal with rotated, odd-sized tiles if (tileworldpos.X + tileRegion.SourceRect.Width < cameraClipBounds.Left || tileworldpos.Y - tileRegion.SourceRect.Height > cameraClipBounds.Bottom) { continue; } } DrawTile(batcher, position, layerDepth, x, y, 1); } } }
public void DrawTile(Batcher batcher, Vector2 position, float layerDepth, int x, int y, float scale) { var tile = GetTile(x, y); if (tile == null) { return; } var t = TiledMap.IsometricTileToWorldPosition(x, y); var tileRegion = tile.TextureRegion; // for the y position, we need to take into account if the tile is larger than the tileHeight and shift. Tiled uses // a bottom-left coordinate system and MonoGame a top-left var rotation = 0f; var spriteEffects = SpriteEffects.None; if (tile.FlippedHorizonally) { spriteEffects |= SpriteEffects.FlipHorizontally; } if (tile.FlippedVertically) { spriteEffects |= SpriteEffects.FlipVertically; } if (tile.FlippedDiagonally) { if (tile.FlippedHorizonally && tile.FlippedVertically) { spriteEffects ^= SpriteEffects.FlipVertically; rotation = MathHelper.PiOver2; t.X += TiledMap.TileHeight + (tileRegion.SourceRect.Height - TiledMap.TileHeight); t.Y -= (tileRegion.SourceRect.Width - TiledMap.TileWidth); } else if (tile.FlippedHorizonally) { spriteEffects ^= SpriteEffects.FlipVertically; rotation = -MathHelper.PiOver2; t.Y += TiledMap.TileHeight; } else if (tile.FlippedVertically) { spriteEffects ^= SpriteEffects.FlipHorizontally; rotation = MathHelper.PiOver2; t.X += TiledMap.TileWidth + (tileRegion.SourceRect.Height - TiledMap.TileHeight); t.Y += (TiledMap.TileWidth - tileRegion.SourceRect.Width); } else { spriteEffects ^= SpriteEffects.FlipHorizontally; rotation = -MathHelper.PiOver2; t.Y += TiledMap.TileHeight; } } // if we had no rotations (diagonal flipping) shift our y-coord to account for any non-tileSized tiles to account for // Tiled being bottom-left origin if (rotation == 0) { t.Y += (TiledMap.TileHeight - tileRegion.SourceRect.Height); } // Scale the tile's relative position, but not the origin t = t * new Vector2(scale) + position; batcher.Draw(tileRegion.Texture2D, t, tileRegion.SourceRect, Color, rotation, Vector2.Zero, scale, spriteEffects, layerDepth); }