/// <summary> /// Draws the unit. It is assumed spriteBatch.begin() has already been called. /// </summary> /// <param name="spriteBatch"></param> public void Draw(Unit unit, SpriteBatch spriteBatch) { Texture2D texture = null; Color color = Color.White; switch (unit.type) { case UnitType.Melee: texture = Sprites.melee; break; case UnitType.Range: texture = Sprites.range; break; case UnitType.Healer: texture = Sprites.healer; break; } if (unit.selected) color = Color.Yellow; Rectangle srcRect = new Rectangle(0, 0, texture.Width, texture.Height); spriteBatch.Draw(texture, unit.dstRect, srcRect, color); }
/// <summary> /// A* Pathfinding. Returns a path in grid units as a Point Stack /// </summary> /// <param name="unit"></param> /// <param name="destination"></param> /// <returns></returns> public Stack<Point> GetWaypoints(Unit unit, Point destination) { Node[,] map = mapNodes; // Open/Closed List //List<Node> openList = new List<Node>(); //List<Node> closedList = new List<Node>(); HashSet<Node> openHashSet = new HashSet<Node>(); HashSet<Node> closedHashSet = new HashSet<Node>(); // Gets Origin Coords Point origin = FindUnit(unit); // Reset Values & Calc Heuristics foreach (Node n in map) { n.ResetValues(); n.h = n.CalcHeuristic(destination); } Node neighbour = null; Node current = map[origin.X, origin.Y]; bool pathFound = false; double newF, lowestF; while (!pathFound) { closedHashSet.Add(current); openHashSet.Remove(current); for (int x = -1; x <= 1; x++) { for (int y = -1; y <= 1; y++) { if (!(x == 0 && y == 0)) { int nx = current.position.X + x; int ny = current.position.Y + y; try { // Check if it's within the bounds if (nx < 0 || nx >= width || ny < 0 || ny >= height) continue; // Get Neighbour neighbour = map[nx, ny]; // Check if solid if (neighbour.solid) closedHashSet.Add(neighbour); if (!closedHashSet.Contains(neighbour)) { // Is it the destination if (neighbour.position.Equals(destination)) pathFound = true; // Add it to the open list if (!openHashSet.Contains(neighbour)) openHashSet.Add(neighbour); neighbour.g = getMovementValue(neighbour, current, x, y); newF = getFValue(neighbour); setParent(neighbour, current, newF); } } catch (Exception e) { Game1.Trace(this, e.Message); } } } } lowestF = INFINITY; foreach (Node n in openHashSet) { if (n.f < lowestF) { lowestF = n.f; current = n; } } if (openHashSet.Count == 0) break; } if (pathFound) return TraceBack(map[destination.X, destination.Y]); return new Stack<Point>(); }
internal void SetUnit(Unit unit_) { unit = unit_; }
internal void RemoveUnit() { unit = null; }
/// <summary> /// Updates the map with the units. /// </summary> /// <param name="unit"></param> /// <returns>If space is taken up by something other than itself, then return true. /// The purpose is so that it can find a new location to stand.</returns> internal void UpdateUnitOnMap(Unit unit) { int cx = (int)Math.Round((double)unit.dstRect.X / GameController.TILE_SIZE); int cy = (int)Math.Round((double)unit.dstRect.Y / GameController.TILE_SIZE); if (cx < 0 || cy < 0 || cx > GameController.MAP_WIDTH || cy > GameController.MAP_HEIGHT) return; Node node = mapNodes[cx, cy]; // Is space available, then add to location if (IsSpaceEmpty(unit)) { Point unitLocation = FindUnit(unit); // Remove from previous location if (unitLocation.X >= 0) mapNodes[unitLocation.X, unitLocation.Y].RemoveUnit(); // Add to actual location node.SetUnit(unit); } }
/// <summary> /// Checks to see if the space is occupied by another unit. /// Space with a Unit is NOT available. /// </summary> /// <param name="unit"></param> /// <returns></returns> internal bool IsSpaceEmpty(Unit unit) { int cx = (int)Math.Round((double)unit.dstRect.X / GameController.TILE_SIZE); int cy = (int)Math.Round((double)unit.dstRect.Y / GameController.TILE_SIZE); if (cx < 0 || cy < 0) return true; Node node = mapNodes[cx, cy]; if (node.HasUnit()) return false; return true; }
internal bool IsOnAnotherUnit(Unit unit) { int cx = (int)Math.Round((double)unit.dstRect.X / GameController.TILE_SIZE); int cy = (int)Math.Round((double)unit.dstRect.Y / GameController.TILE_SIZE); if (cx < 0 || cy < 0 || cx > GameController.MAP_WIDTH || cy > GameController.MAP_HEIGHT) return false; Unit target = mapNodes[cx, cy].unit; if (target == null) return false; if (target.Equals(unit)) return false; return true; }
/// <summary> /// Finds a unit on the map and returns the coordinates. /// </summary> /// <param name="unit_"></param> /// <returns></returns> internal Point FindUnit(Unit unit_) { for (int x = 0; x < width; x++) for (int y = 0; y < height; y++) if (mapNodes[x, y].unit != null && mapNodes[x, y].unit.Equals(unit_)) return new Point(x, y); return new Point(-1, -1); }
internal Point FindNearestSpace(Unit unit) { int cx = (int)Math.Round((double)unit.position.X / GameController.TILE_SIZE); int cy = (int)Math.Round((double)unit.position.Y / GameController.TILE_SIZE); return FindNearestSpace(cx, cy, unit); }
/// <summary> /// Searches around the chosen coordinates for an empty space. /// </summary> /// <param name="x_"></param> /// <param name="y_"></param> /// <returns></returns> internal Point FindNearestSpace(int x_, int y_, Unit unitSelf = null) { if (x_ < 0 || y_ < 0) { Game1.Trace(this, "Invalid Point"); return new Point(-1, -1); } int range = 1; int rangeMax = GameController.MAP_WIDTH; bool found = false; do { for (int x = -range; x <= range; x++) { for (int y = -range; y <= range; y++) { if (!(x == 0 && y == 0)) { int a = x_ + x; int b = y_ + y; if (a >= 0 && a < width && b >= 0 && b < height) { Unit unit = mapNodes[a, b].unit; if (unitSelf != null && unit != null) if (unit.Equals(unitSelf)) return new Point(a, b); if (unit == null) return new Point(a, b); } } } } range++; if (range > rangeMax) found = true; } while (!found); return new Point(-1, -1); }
/// <summary> /// Finds the unit in the map. If it exists, returns true. /// </summary> /// <param name="unit_"></param> /// <returns></returns> internal bool ContainsUnit(Unit unit_) { for (int x = 0; x < width; x++) for (int y = 0; y < height; y++) if (mapNodes[x, y].unit != null && mapNodes[x, y].unit.Equals(unit_)) return true; return false; }
public void ClearTarget() { targetUnit = null; }
public void Attack(Unit enemyUnit) { state = UnitState.Attacking; targetUnit = enemyUnit; }