public Character(Viewport viewport, Tile tile) { position = tile.position; minPosition = Vector2.Zero; maxPosition = new Vector2(viewport.Width, viewport.Height); currentTile = tile; selected = false; }
public Map(SpriteBatch spriteBatch, TextureList newTextureList, Viewport viewport) { textureList = newTextureList; tileList = new List<Tile>(); for (int x = 0; x < (viewport.Width) / 32; x++) { for (int y = 0; y < (viewport.Height - 128) / 32; y++) { if ((x == 3 && y < 10) || (x > 2 && x < 4 && y > 4 && y < 10)) { Tile mountainTile = new Tile(textureList.Get("tile-mountain"), new Vector2(x * 32, y * 32)); mountainTile.restricted = true; tileList.Add(mountainTile); } else { Tile grassTile = new Tile(textureList.Get("tile-grass"), new Vector2(x * 32, y * 32)); tileList.Add(grassTile); } } } }
public void Update(MouseState currentMouseState, MouseState previousMouseState, KeyboardState currentKeyState, KeyboardState previousKeyState, GameTime gameTime, Map map) { // Selects or deselects the character. if (Math.Abs(currentMouseState.X - (position.X + 15)) <= 15 && Math.Abs(currentMouseState.Y - (position.Y + 15)) <= 15 && previousMouseState.LeftButton == ButtonState.Pressed && currentMouseState.LeftButton == ButtonState.Released) { selected = !selected; } // Deselects the character when clicking anywhere on the map. if (selected && (Math.Abs(currentMouseState.X - (position.X + 15)) > 15 || Math.Abs(currentMouseState.Y - (position.Y + 15)) > 15) && previousMouseState.LeftButton == ButtonState.Pressed && currentMouseState.LeftButton == ButtonState.Released) { selected = false; } // Finds the path from the current tile to the selected tile. if (selected && previousMouseState.RightButton == ButtonState.Pressed && currentMouseState.RightButton == ButtonState.Released) { foreach (Tile mapTile in map.tileList) { if (!mapTile.restricted && Math.Abs(currentMouseState.X - (mapTile.position.X + 15)) <= 15 && Math.Abs(currentMouseState.Y - (mapTile.position.Y + 15)) <= 15) { // Clear the old path. if (path != null) { for (int i = 1; i < path.Length; i++) { path[i].isPath = false; } } // Create the new path. pathIndex = 0; path = map.FindPath(currentTile, mapTile).ToArray(); for (int i = 1; i < path.Length; i++) { path[i].isPath = true; } } } } // Moves the character one tile along the path when the space bar is pressed. if (selected && path != null && pathIndex < path.Length-1 && previousKeyState.IsKeyDown(Keys.Space) && currentKeyState.IsKeyUp(Keys.Space)) { Tile nextTile = path[++pathIndex]; currentTile = nextTile; position = nextTile.position; nextTile.isPath = false; } // Clears the path if the character gets deselected. if (!selected) { path = null; foreach (Tile mapTile in map.tileList) { mapTile.isPath = false; } } }
/// <summary> /// /// </summary> /// <param name="e"></param> protected override void OnNavigatedTo(NavigationEventArgs e) { if (e.NavigationMode == NavigationMode.Back) { return; } FrameWidth = canvasPanel.Width / Column; FrameHeight = canvasPanel.Height / Row; mTile = new Tile(Column,Row); mTile.Shuffle(); for (int i = 0; i < Row; i++) { for (int j = 0; j < Column; j++) { Image img = new Image(); img.Stretch = Stretch.Fill; img.Width = FrameWidth - 2; img.Height = FrameHeight - 2; img.RenderTransform = new TranslateTransform(); Canvas.SetTop(img, i * FrameHeight); Canvas.SetLeft(img, j * FrameWidth); Object RowObj = (Object)i; Object ColObj = (Object)j; img.ManipulationStarted += (obj, args) => Image_ManipulationStarted(obj, args, RowObj, ColObj); canvasPanel.Children.Add(img); mImageList.Add(img); } } Image imgBase = new Image(); imgBase.Source = TileBitmap; imgBase.Stretch = Stretch.None; Int32 TileWidth = TileBitmap.PixelWidth / Column; Int32 TileHeight = TileBitmap.PixelHeight / Row; for (int i = 0; i < Row; i++) { for (int j = 0; j < Column; j++) { WriteableBitmap writeableBitmap = new WriteableBitmap(TileWidth,TileHeight); TranslateTransform translate = new TranslateTransform(); translate.X = -TileWidth * j;//在绘制到位图中之前应用到元素的变换 translate.Y = -TileHeight * i; writeableBitmap.Render(imgBase, translate);//在位图中呈现元素 writeableBitmap.Invalidate(); mBitmapSource.Add(writeableBitmap); } } refreshContent(); }
/// <summary> /// Finds the path from start to finish using A* pathfinding algorithm. /// </summary> /// <param name="start">The start location of the selected character.</param> /// <param name="finish">The selected location on the map.</param> /// <returns>The shortest path from start to finish.</returns> public List<Tile> FindPath(Tile start, Tile finish) { List<Tile> openList = new List<Tile>() { start }; List<Tile> closedList = new List<Tile>(); Dictionary<Tile, Tile> cameFrom = new Dictionary<Tile, Tile>(); Dictionary<Tile, int> currentDistance = new Dictionary<Tile, int>(); Dictionary<Tile, float> predictedDistance = new Dictionary<Tile, float>(); currentDistance.Add(start, 0); predictedDistance.Add(start, start.position.X - finish.position.X + start.position.Y - finish.position.Y); while (openList.Count > 0) { // Gets the node with the lowest estimated cost to the finish. Tile current = (from p in openList orderby predictedDistance[p] ascending select p).First(); if (current.position.X == finish.position.X && current.position.Y == finish.position.Y) { return ConstructPath(cameFrom, finish); } openList.Remove(current); closedList.Add(current); foreach (Tile neighbour in GetNeighbourTiles(current)) { int tempCurrentDistance = currentDistance[current] + 1; if (closedList.Contains(neighbour) && tempCurrentDistance >= currentDistance[neighbour]) { continue; } if (!closedList.Contains(neighbour) || tempCurrentDistance < currentDistance[neighbour]) { if (cameFrom.Keys.Contains(neighbour)) { cameFrom[neighbour] = current; } else { cameFrom.Add(neighbour, current); } currentDistance[neighbour] = tempCurrentDistance; predictedDistance[neighbour] = currentDistance[neighbour] + Math.Abs(neighbour.position.X - finish.position.X) + Math.Abs(neighbour.position.Y - finish.position.Y); if (!openList.Contains(neighbour) && !neighbour.restricted) { openList.Add(neighbour); } } } } throw new Exception( string.Format ("Unable to find a path from {0},{1}, to {2},{3}", start.position.X, start.position.Y, finish.position.X, finish.position.Y)); }
private IEnumerable<Tile> GetNeighbourTiles(Tile currentTile) { List<Tile> neighbourTiles = new List<Tile>(); foreach (Tile tile in tileList) { // Up if (Math.Abs(currentTile.position.X - tile.position.X) < 1 && Math.Abs(currentTile.position.Y - 32 - tile.position.Y) < 1) { neighbourTiles.Add(tile); } // Right if (Math.Abs(currentTile.position.X + 32 - tile.position.X) < 1 && Math.Abs(currentTile.position.Y - tile.position.Y) < 1) { neighbourTiles.Add(tile); } // Down if (Math.Abs(currentTile.position.X - tile.position.X) < 1 && Math.Abs(currentTile.position.Y + 32 - tile.position.Y) < 1) { neighbourTiles.Add(tile); } // Left if (Math.Abs(currentTile.position.X - 32 - tile.position.X) < 1 && Math.Abs(currentTile.position.Y - tile.position.Y) < 1) { neighbourTiles.Add(tile); } } return neighbourTiles; }
/// <summary> /// Creates a list of valid paths generated by the FindPath method and returns a path to current. /// </summary> /// <param name="cameFrom">An origin and list of nodes.</param> /// <param name="current">The destination node we are looking for.</param> /// <returns>The shortest path from the start tile to the finish tile.</returns> private List<Tile> ConstructPath(Dictionary<Tile, Tile> cameFrom, Tile current) { if (!cameFrom.Keys.Contains(current)) { return new List<Tile> { current }; } List<Tile> path = ConstructPath(cameFrom, cameFrom[current]); path.Add(current); return path; }