using System; using System.Collections.Generic; using Microsoft.Xna.Framework; namespace MonoGame.Extended.Tilemaps { /// /// Represents a layer composed of a grid of tiles. /// public class TilemapTileLayer : TilemapLayer { private readonly TilemapTile?[,] _tiles; /// /// Gets the width of the layer in tiles. /// public int Width { get; } /// /// Gets the height of the layer in tiles. /// public int Height { get; } /// /// Gets the width of each tile in pixels. /// public int TileWidth { get; } /// /// Gets the height of each tile in pixels. /// public int TileHeight { get; } /// public override Rectangle Bounds { get { return new Rectangle(0, 0, Width * TileWidth, Height * TileHeight); } } /// /// Initializes a new instance of the class. /// /// The name of the layer. /// The width of the layer in tiles. /// The height of the layer in tiles. /// The width of each tile in pixels. /// The height of each tile in pixels. public TilemapTileLayer(string name, int width, int height, int tileWidth, int tileHeight) : base(name) { Width = width; Height = height; TileWidth = tileWidth; TileHeight = tileHeight; _tiles = new TilemapTile?[width, height]; } /// /// Gets the tile at the specified tile coordinates. /// /// The X coordinate of the tile. /// The Y coordinate of the tile. /// The tile at the specified coordinates, or if empty. public TilemapTile? GetTile(int x, int y) { if (x < 0 || x >= Width || y < 0 || y >= Height) { return null; } return _tiles[x, y]; } /// /// Sets the tile at the specified tile coordinates. /// /// The X coordinate of the tile. /// The Y coordinate of the tile. /// The tile to set, or to clear. public void SetTile(int x, int y, TilemapTile? tile) { if (x < 0 || x >= Width || y < 0 || y >= Height) { throw new ArgumentOutOfRangeException(); } _tiles[x, y] = tile; } /// /// Gets all non-empty tiles in the layer. /// /// An enumerable of tuples containing tile coordinates and tile data. public IEnumerable<(int x, int y, TilemapTile tile)> GetTiles() { for (int y = 0; y < Height; y++) { for (int x = 0; x < Width; x++) { TilemapTile? tile = _tiles[x, y]; if (tile.HasValue) { yield return (x, y, tile.Value); } } } } /// /// Gets all tiles within the specified rectangular region. /// /// The region in tile coordinates. /// An enumerable of tuples containing tile coordinates and tile data. public IEnumerable<(int x, int y, TilemapTile tile)> GetTilesInRegion(Rectangle region) { // Clamp region to layer bounds int startX = Math.Max(0, region.X); int startY = Math.Max(0, region.Y); int endX = Math.Min(Width, region.X + region.Width); int endY = Math.Min(Height, region.Y + region.Height); for (int y = startY; y < endY; y++) { for (int x = startX; x < endX; x++) { TilemapTile? tile = _tiles[x, y]; if (tile.HasValue) { yield return (x, y, tile.Value); } } } } } }