/// <summary> /// Sets the tile at the position by creating a tile /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <param name="index">Index of the tile</param> /// <param name="tileSet">Tile set of the tile</param> public void SetTile(int x, int y, int index, int tileSet) { if (y >= HeightInTiles || x >= WidthInTiles || y < 0 || x < 0) return; map[y, x] = new Tile(index, tileSet); }
public static MapLayer GenerateFromAlgorithm(GenerationAlgorithm algorithm, TileMap level, int selectedTileSet, int groundTile = 0, int wallTile = 0) { Random rand = new Random(); Tile[,] layerTiles = new Tile[level.HeightInTiles, level.WidthInTiles]; // TODO: Algorithm logic switch (algorithm) { case GenerationAlgorithm.Dungeon_DrunkenWalk: { List<Room> rooms = new List<Room>(); for (int x = 0; x < level.WidthInTiles; x++) for (int y = 0; y < level.HeightInTiles; y++) { layerTiles[y, x] = new Tile(wallTile, selectedTileSet); level.SetCollision(x, y, true); } int roomsMin = (int)(level.WidthInTiles * level.HeightInTiles) / 300; int roomsMax = (int)(level.WidthInTiles * level.HeightInTiles) / 150; int roomCount = 30; int widthRoot = (int)Math.Sqrt(level.WidthInPixels * 2); int heightRoot = (int)Math.Sqrt(level.HeightInPixels * 2); int minimumWidth = (int)4 * Engine.TileWidth; int maximumWidth = (int)8 * Engine.TileHeight; int minimumHeight = (int)3 * Engine.TileWidth; int maximumHeight = (int)10 * Engine.TileHeight; do { bool ok = false; Room room = new Room(); room.X = (int)Math.Round(rand.Next(0, level.WidthInPixels) / (double)Engine.TileWidth) * Engine.TileWidth; room.Y = (int)Math.Round(rand.Next(0, level.HeightInPixels) / (double)Engine.TileHeight) * Engine.TileHeight; room.Width = (int)Math.Round(rand.Next(minimumWidth, maximumWidth) / (double)Engine.TileWidth) * Engine.TileWidth; room.Height = (int)Math.Round(rand.Next(minimumHeight, maximumHeight) / (double)Engine.TileHeight) * Engine.TileHeight; if (room.X < 0 || room.X > level.WidthInPixels - room.Width || room.Y < 0 || room.Y > level.HeightInPixels - room.Height) continue; ok = true; if (rooms.Count > 0) { foreach (Room r in rooms) if (r.Bounds.Intersects(room.Bounds)) ok = false; } if (ok) rooms.Add(room); } while (rooms.Count < roomCount); rooms.Add(new Room() { X = 0, Y = 0, Width = 10 * Engine.TileWidth, Height = 10 * Engine.TileHeight }); List<Room> usableRooms = rooms; List<Cell> connectedTiles = new List<Cell>(); int connections = roomCount; int index = 0; for (int i = 0; i < connections - 1; i++) { Room room = rooms[index]; usableRooms.Remove(room); Room connectToRoom = usableRooms[rand.Next(usableRooms.Count)]; double sideStepChance = 0.4; Vector2 pointA = new Vector2(rand.Next(room.Bounds.X, room.Bounds.X + room.WidthInTiles), rand.Next(room.Bounds.Y, room.Bounds.Y + room.HeightInTiles)); Vector2 pointB = new Vector2(rand.Next(connectToRoom.Bounds.X, connectToRoom.Bounds.X + connectToRoom.WidthInTiles), rand.Next(connectToRoom.Bounds.Y, connectToRoom.Bounds.Y + connectToRoom.HeightInTiles)); while (pointB != pointA) { if (rand.NextDouble() < sideStepChance) { if (pointB.X != pointA.X) { if (pointB.X < pointA.X) pointB.X++; else pointB.X--; } } else if (pointB.Y != pointA.Y) { if (pointB.Y < pointA.Y) pointB.Y++; else pointB.Y--; } if (pointB.X < level.WidthInTiles && pointB.Y < level.HeightInTiles) { level.SetCollision((int)pointB.X, (int)pointB.Y, false); layerTiles[(int)(pointB.Y), (int)(pointB.X)] = new Tile(-1, -1); } } } foreach (Room r in rooms) { for (int x = (int)r.Position.X; x < r.Width + r.Position.X; x++) { for (int y = (int)r.Position.Y; y < r.Height + r.Position.Y; y++) { if (x / 32 == r.Position.X / 32 || x / 32 == (int)(r.WidthInTiles + (r.Position.X / 32) - 1) || y / 32 == r.Position.Y / 32 || y / 32 == (int)(r.HeightInTiles + (r.Position.Y / 32) - 1)) { } else { level.SetCollision((int)(x / Engine.TileWidth), (int)(y / Engine.TileHeight), false); layerTiles[(int)(y / Engine.TileHeight), (int)(x / Engine.TileWidth)] = new Tile(-1, -1); } } } } } break; case GenerationAlgorithm.PerlinNoise: break; } return new MapLayer(level, layerTiles); }
/// <summary> /// Sets the tile at the position /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <param name="t">Tile to replace the selected tile</param> public void SetTile(int x, int y, Tile t) { if (y >= HeightInTiles || x >= WidthInTiles || y < 0 || x < 0) return; map[y, x] = t; }
/// <summary> /// Initializes a new map layer /// </summary> /// <param name="width"></param> /// <param name="height"></param> public MapLayer(TileMap parent) { this.parent = parent; map = new Tile[HeightInTiles, WidthInTiles]; for (int y = 0; y < HeightInTiles; y++) { for (int x = 0; x < WidthInTiles; x++) { map[y, x] = new Tile(-1, -1); } } }
/// <summary> /// Initializes a new map layer with an existing map /// </summary> /// <param name="map"></param> public MapLayer(TileMap parent, Tile[,] map) { this.parent = parent; this.map = (Tile[,])map.Clone(); }
private void Floodfill(Point q, Tile target, Tile replacement) { int w = gameRef.level.WidthInTiles; int h = gameRef.level.HeightInTiles; if (q.X < 0 || q.X > w - 1 || q.Y < 0 || q.Y > h - 1) return; Stack<Point> stack = new Stack<Point>(); stack.Push(q); while (stack.Count > 0) { Point p = stack.Pop(); int x = p.X; int y = p.Y; if (y < 0 || y > h - 1 || x < 0 || x > w - 1) continue; var val = gameRef.level.CurrentLayer.GetTile(x, y); if (target != null) { if (val.TileSet == replacement.TileSet && val.TileIndex == replacement.TileIndex) continue; if (val.TileSet == target.TileSet && val.TileIndex == target.TileIndex) { gameRef.level.SetTile(x, y, new Tile(replacement.TileIndex, replacement.TileSet)); stack.Push(new Point(x + 1, y)); stack.Push(new Point(x - 1, y)); stack.Push(new Point(x, y + 1)); stack.Push(new Point(x, y - 1)); } } else { if (val == null) { gameRef.level.CurrentLayer.SetTile(x, y, new Tile(replacement.TileIndex, replacement.TileSet)); stack.Push(new Point(x + 1, y)); stack.Push(new Point(x - 1, y)); stack.Push(new Point(x, y + 1)); stack.Push(new Point(x, y - 1)); } } } }
/// <summary> /// Sets the tile of a layer /// </summary> /// <param name="pos"></param> /// <param name="t">Tile to replace with the selected</param> /// <param name="currentLayer">Layer to edit</param> public void SetTile(Point pos, Tile t, int currentLayer = -1) { if (currentLayer != -1) CurrentLayerIndex = currentLayer; layers[CurrentLayerIndex].SetTile(pos.X, pos.Y, t); }
/// <summary> /// Sets the tile of a layer /// </summary> /// <param name="x">X position of the tile</param> /// <param name="y">Y position of the tile</param> /// <param name="t">Tile to replace with the selected</param> /// <param name="currentLayer">Layer to edit</param> public void SetTile(int x, int y, Tile t, int currentLayer = -1) { SetTile(new Point(x, y), t, currentLayer); }