public PathFinding(TileMap map) { this.map = map; openList = new List<Tile>(); closedList = new List<Tile>(); start = map.Map[5, 5]; end = map.Map[10, 10]; AStar(); }
/// <summary> /// Basic constructor creating a new TileLayer of width * height tiles. /// The tiles are set to having no texture. /// </summary> /// <param name="width">The width of the layer.</param> /// <param name="height">The height of the layer.</param> public TileLayer( int width, int height ) { map = new Tile[height, width]; for ( int row = 0; row < height; row++ ) { for ( int col = 0; col < width; col++ ) { map[row, col] = new Tile(); map[row, col].TextureId = -1; } } }
public TileMap(Input input, int width, int height) { this.width = width; this.height = height; this.input = input; map = new Tile[width, height]; InitializeMap(); tileUnderMouse = Map[0, 0]; pathFinding = new PathFinding(this); DrawPath(pathFinding.CalculatePath()); }
//return a path = list of tiles between 2 tiles public List<Tile> CalculatePath(Tile start, Tile end) { this.start = start; this.end = end; foreach (Tile tile in map.Map) { noPath = false; tile.Open = false; tile.Closed = false; tile.ParentTile = null; tile.F = 0; tile.G = 0; tile.H = 0; tile.Color = Color.White; } openList = new List<Tile>(); closedList = new List<Tile>(); return AStar(); }
public void Draw(SpriteBatch spriteBatch) { Rectangle destination = new Rectangle(0, 0, 32, 32); Tile tile = new Tile(); foreach (MapLayer layer in mapLayers) { for (int y = 0; y < layer.Height; y++) { destination.Y = y * 32; for (int x = 0; x < layer.Width; x++) { tile.Type.Id = layer.GetTile_id(x, y); destination.X = x * 32; spriteBatch.Draw(tilesets[tile.Type.tileSet].Texture, destination, tilesets[tile.Type.tileSet].SourceRectangles[tile.Type.tileSetIndex], Color.White); } } } }
//A* Algo private List<Tile> AStar() { current = start; openList.Add(start); start.Open = true; #region loop while (current != end) { //look for lowest F cost tile on the open list current = ChooseLowestFTile(openList); //switch it to the closed list openList.Remove(current); current.Open = false; closedList.Add(current); current.Closed = true; //for all neighbors foreach (Tile tile in GetNeighbors(current)) { //if its not walkable or on the closes list, ignore it if (!tile.IsWalkable || tile.Closed) { // } //if its not on the open list, add it, make current tile its parent //and recalculate scores else if (!tile.Open) { openList.Add(tile); tile.Open = true; tile.ParentTile = current; CalculateInfo(tile); } //if its on the open list already, check if that path to the tile is better //if it is, change its parent to current and recalculate scores else if (tile.Open) { if (getTileG(tile, current) < tile.G) { tile.ParentTile = current; CalculateInfo(tile); } } } //if no path if (openList.Count == 0) { noPath = true; break; } } #endregion return ReturnPath(); }
//Change end tile and recalculate path public List<Tile> ChangeStart(Tile start) { this.start = start; return CalculatePath(); }
//Change start tile and recalculate path public List<Tile> ChangeEnd(Tile end) { this.end = end; return CalculatePath(); }
private void InitializeMap() { for (int x = 0; x < Static.MapSize.X; x++) for (int y = 0; y < Static.MapSize.Y; y++) Map[x, y] = new Tile(new Vector2(x, y), Art.WhiteTileBorder); }
public void AddNewTileToLayer(Vector2 size, Vector2 screenPosition, Color color, Texture2D texture, TileAnimation animation) { var tile = new Tile(size, screenPosition, color, texture, animation); AddTileToLayer(tile); }
public void FindNeighbors(IMap map) { Tile nullTile = new Tile(); Point[] coordinates = new Point[8]; Directions[] directionArray = new Directions[8]; int adjustedSize = this.rectangle.Width; // size is distance from center to edge, // double to ensure we end up outside of this box directionArray[(int)Directions.East] = Directions.East; directionArray[(int)Directions.North] = Directions.North; directionArray[(int)Directions.NorthEast] = Directions.NorthEast; directionArray[(int)Directions.NorthWest] = Directions.NorthWest; directionArray[(int)Directions.South] = Directions.South; directionArray[(int)Directions.SouthEast] = Directions.SouthEast; directionArray[(int)Directions.SouthWest] = Directions.SouthWest; directionArray[(int)Directions.West] = Directions.West; coordinates[(int)Directions.East] = new Point(this.rectangle.Center.X + adjustedSize, this.rectangle.Center.Y); coordinates[(int)Directions.North] = new Point(this.rectangle.Center.X, this.rectangle.Center.Y - adjustedSize); coordinates[(int)Directions.NorthEast] = new Point(this.rectangle.Center.X + adjustedSize, this.rectangle.Center.Y - adjustedSize); coordinates[(int)Directions.NorthWest] = new Point(this.rectangle.Center.X - adjustedSize, this.rectangle.Center.Y - adjustedSize); coordinates[(int)Directions.South] = new Point(this.rectangle.Center.X, this.rectangle.Center.Y + adjustedSize); coordinates[(int)Directions.SouthEast] = new Point(this.rectangle.Center.X + adjustedSize, this.rectangle.Center.Y + adjustedSize); coordinates[(int)Directions.SouthWest] = new Point(this.rectangle.Center.X - adjustedSize, this.rectangle.Center.Y + adjustedSize); coordinates[(int)Directions.West] = new Point(this.rectangle.Center.X - adjustedSize, this.rectangle.Center.Y); foreach (Directions d in directionArray) { this.adjacentTiles[(int)d] = map.GetTile(coordinates[(int)d]); } }
private void CalculateInfo(Tile tile) { if (tile.ParentTile == null) tile.G = 0; else { if (tile.Position.X == tile.ParentTile.Position.X || tile.Position.Y == tile.ParentTile.Position.Y) tile.G = tile.ParentTile.G + 10 + tile.Cost; else tile.G = tile.ParentTile.G + 14 + tile.Cost; } tile.H = ManhattanDistance(tile, End); tile.F = tile.G + tile.H; }
private float getTileG(Tile tile, Tile parent) { // G is calculates from parent's G + (1 or sqrt2) depending on parent relative position if (tile.Position != Start.Position) { //tile's parent is vertical or horizontal if (tile.Position.X == parent.Position.X || tile.Position.Y == parent.Position.Y) { return parent.G + 10 + tile.Cost; } //tile's parent is diagonal else return parent.G + 14+tile.Cost ; } return 0; }
private Tile ChooseLowestFTile(List<Tile> tiles) { int fmax = int.MaxValue; Tile current = new Tile(); foreach (Tile tile in tiles) if (tile.F < fmax) { fmax = (int)tile.F; current = tile; } return current; }
private static Tile GenerateTile(Point position) { Tile tile = new Tile(position, map.TileSize); int rNumber = rand.Next(100); int chance = 30; if (rNumber < chance) { TerrainEntity rockEntity = new TerrainEntity(tile); Texture2D texture = rock; Rectangle destinationRectangle = tile.Rect; Rectangle sourceRectangle = Rectangle.Empty; if (texture == null) { sourceRectangle = Rectangle.Empty; } rockEntity.SetDrawData(texture, destinationRectangle, sourceRectangle, 0.5f); rockEntity.IsBlocked = true; tile.AddEntity(rockEntity); } TerrainEntity terrainEntity = new TerrainEntity(tile); rNumber = rand.Next(100); chance = 80; if (rNumber < chance) { Texture2D texture2 = tile_green; Rectangle destinationRectangle2 = tile.Rect; Rectangle sourceRectangle2 = Rectangle.Empty; if (texture2 == null) { sourceRectangle2 = Rectangle.Empty; } terrainEntity.SetDrawData(texture2, destinationRectangle2, sourceRectangle2, 0.2f); } else { Texture2D texture3 = tile_brown; Rectangle destinationRectangle3 = tile.Rect; Rectangle sourceRectangle3 = Rectangle.Empty; if (texture3 == null) { sourceRectangle3 = Rectangle.Empty; } terrainEntity.SetDrawData(texture3, destinationRectangle3, sourceRectangle3, 0.2f); } tile.AddEntity(terrainEntity); //tile.MapIndex = map.AddTile(tile); return tile; }
public void Update() { #region culling float tilesOnScreenX = Static.ScreenSize.X / Static.tileSize / Camera.Instance.Zoom; float tilesOnScreenY = Static.ScreenSize.Y / Static.tileSize / Camera.Instance.Zoom; x0 = (int)(Camera.Instance.Position.X / Static.tileSize - tilesOnScreenX / 2); x1 = (int)(Camera.Instance.Position.X / Static.tileSize + tilesOnScreenX / 2 + 1); y0 = (int)(Camera.Instance.Position.Y / Static.tileSize - tilesOnScreenY / 2); y1 = (int)(Camera.Instance.Position.Y / Static.tileSize + tilesOnScreenY / 2) + 1; if (x0 < 0) x0 = 0; if (x1 > width) x1 = width; if (y0 < 0) y0 = 0; if (y1 > height) y1 = height; #endregion #region Input //for all tiles on screen for (int x = x0; x < x1; x++) for (int y = y0; y < y1; y++) { //check "selected" tile (tile under mouse) if (input.MouseToGrid == new Vector2(x, y)) { tileUnderMouse = Map[x, y]; //left clic to change start tile if (input.WasLeftButtonDown && !input.IsKeyDown(Keys.LeftShift) && Map[x, y].IsWalkable) DrawPath(pathFinding.ChangeStart(Map[x, y])); //shift left clic to change end tile else if (input.WasLeftButtonDown && input.IsKeyDown(Keys.LeftShift) && Map[x, y].IsWalkable) DrawPath(pathFinding.ChangeEnd(Map[x, y])); //if shift right click, erase tile else if (input.IsRightButtonDown && input.IsKeyDown(Keys.LeftShift)) { Map[x, y] = new Tile(new Vector2(x, y), Art.WhiteTileBorder, 0, true); if (Map[x, y] == pathFinding.End || Map[x, y] == pathFinding.Start) return; DrawPath(pathFinding.CalculatePath()); } //if right click, add tile else if (input.IsRightButtonDown) { //ctrl-right click = new water tile if (input.IsRightButtonDown && input.IsKeyDown(Keys.LeftControl) && Map[x, y] != pathFinding.End) { Map[x, y] = new Tile(new Vector2(x, y), Art.BlueTileBorder, 50, true); if (pathFinding.NoPath) return; } //right click = new wall tile else if (input.IsRightButtonDown && Map[x, y] != pathFinding.End) { Map[x, y] = new Tile(new Vector2(x, y), Art.BlackTileBorder, 0, false); if (pathFinding.NoPath) return; } DrawPath(pathFinding.CalculatePath()); } } } #endregion }
/* Constructor allowing user to create a TileLayer from an existing map. */ public TileLayer( Tile[,] existingMap ) { map = (Tile[,])existingMap.Clone(); }
private int ManhattanDistance(Tile start, Tile end) { int x = (int)Math.Abs(start.Position.X - end.Position.X); int y = (int)Math.Abs(start.Position.Y - end.Position.Y); return 10 * (x + y); }
public void AddNewTileToLayer(Vector2 size, Vector2 screenPosition, Color color) { var tile = new Tile(size, screenPosition, color, _defaultTexture); AddTileToLayer(tile); }
private List<Tile> GetNeighbors(Tile tile) { List<Tile> neighbors = new List<Tile>(); if (tile.Position.X > 0) neighbors.Add(map.Map[(int)tile.Position.X - 1, (int)tile.Position.Y]); if (tile.Position.X < map.Map.GetLength(0) - 1) neighbors.Add(map.Map[(int)tile.Position.X + 1, (int)tile.Position.Y]); if (tile.Position.Y > 0) neighbors.Add(map.Map[(int)tile.Position.X, (int)tile.Position.Y - 1]); if (tile.Position.Y < map.Map.GetLength(1) - 1) neighbors.Add(map.Map[(int)tile.Position.X, (int)tile.Position.Y + 1]); if (tile.Position.X > 0 && tile.Position.Y > 0) neighbors.Add(map.Map[(int)tile.Position.X - 1, (int)tile.Position.Y - 1]); if (tile.Position.X < map.Map.GetLength(0) - 1 && tile.Position.Y > 0) neighbors.Add(map.Map[(int)tile.Position.X + 1, (int)tile.Position.Y - 1]); if (tile.Position.X > 0 && tile.Position.Y < map.Map.GetLength(1) - 1) neighbors.Add(map.Map[(int)tile.Position.X - 1, (int)tile.Position.Y + 1]); if (tile.Position.X < map.Map.GetLength(0) - 1 && tile.Position.Y < map.Map.GetLength(1) - 1) neighbors.Add(map.Map[(int)tile.Position.X + 1, (int)tile.Position.Y + 1]); //foreach (Tile t in neighbors) // CalculateInfo(t); return neighbors; }
public void AddTileToLayer(Tile tile) { _layerTiles.Add(tile); }
private Map BuildEmptyMap(int width, int height) { Map result = new Map(new Point(50, 50), 256, width, height); Point size = result.TileSize; int xMax = size.X * width; int yMax = size.Y * height; var noise = new PerlinNoise(100, 100); for (int x = 0; x < xMax; x = x + size.X) { for (int y = 0; y < yMax; y = y + size.Y) { int tileSelection = random.Next(0, 3); Vector2 position = new Vector2((float)x, (float)y); Tile newTile = new Tile(position, size); var perlin = noise.GetRandomHeight((position.X / xMax) * 100, (position.Y / yMax) * 100, 1.0f, 1.0f, 0.0000000001f, 1.0f, 4); if (perlin < 0.5f && perlin >= 0.0f) newTile.AddEntity(new DirtEntity(newTile, this.dirtTexture[tileSelection], Color.White, false)); if (perlin < 0.9f && perlin >= 0.5f) newTile.AddEntity(new MudEntity(newTile, this.muckTexture[tileSelection], Color.White, false)); if (perlin <= 1.0f && perlin >= 0.9f) newTile.AddEntity(new SludgeEntity(newTile, this.sludgeTexture[tileSelection], Color.White, false)); result.Add(newTile); } } result.CalculateAdjacentTiles(); result.CalculateTileIntensity(); return result; }