public AxisDirection? directionForTile(Tile tile) { if (tile.posX == posX) { if (tile.posY > posY) return AxisDirection.down; else if (tile.posY < posY) return AxisDirection.up; else return null; } else if (tile.posY == posY) { if (tile.posX > posX) return AxisDirection.right; else if (tile.posX < posX) return AxisDirection.left; else return null; } else return null; }
public TilePathNode(Tile _tile) { tile = _tile; waypointIndex = -1; }
public static LinkedList<TilePathNode> findPathBetween(Tile from, Tile to, Vector startDirection) { var roadMap = from.roadMap; var cost = new double[roadMap.width, roadMap.height]; for (int x = 0; x < roadMap.width; ++x) { for (int y = 0; y < roadMap.height; ++y) { cost[x, y] = double.MaxValue; } } var backDir = new AxisDirection[roadMap.width, roadMap.height]; var speedDir = new Vector[roadMap.width, roadMap.height]; var queue = new Queue<Tile>(); queue.Enqueue(from); cost[from.posX, from.posY] = 0; speedDir[from.posX, from.posY] = startDirection; while (queue.Count > 0) { var current = queue.Dequeue(); foreach (AxisDirection dir in Enum.GetValues(typeof(AxisDirection))) { if (current.canGoInDirection(dir)) { var next = current.nextTileInDirection(dir); if (next != null) { double nextCost = cost[current.posX, current.posY] + 1; if (speedDir[current.posX, current.posY] * new Vector(dir) < 0.01) nextCost += 1; if (cost[next.posX, next.posY] > nextCost) { cost[next.posX, next.posY] = nextCost; backDir[next.posX, next.posY] = dir.back(); speedDir[next.posX, next.posY] = new Vector(dir); if (!queue.Contains(next)) queue.Enqueue(next); } } } } } var list = new LinkedList<TilePathNode>(); { var current = to; if (cost[to.posX, to.posY] == -1) return list; // SHEEIT, UNKNOWN TILES while (current != from) { list.AddFirst(new TilePathNode(current)); current = current.nextTileInDirection(backDir[current.posX, current.posY]); if (current == null) return list; } } return list; }
private Vector addPathBetween(Tile from, Tile to, Vector speedDir) { var q = new Queue<Tile>(); var map = from.roadMap; var cost = new double[map.width, map.height]; for (int x = 0; x < map.width; ++x) { for (int y = 0; y < map.height; ++y) { cost[x, y] = double.MaxValue; } } cost[from.posX, from.posY] = 0; var backDir = new AxisDirection[map.width, map.height]; { Vector speed = speedDir; foreach (AxisDirection dir in Enum.GetValues(typeof(AxisDirection))) { if (!from.canGoInDirection(dir)) continue; var next = from.nextTileInDirection(dir); if (next == null) continue; cost[next.posX, next.posY] = (speed * new Vector(dir)) * 0.5 + 1; backDir[next.posX, next.posY] = dir.back(); q.Enqueue(next); } } while (q.Count > 0) { var cur = q.Dequeue(); Vector speed = new Vector(backDir[cur.posX, cur.posY].back()); { var prev = cur.nextTileInDirection(backDir[cur.posX, cur.posY]); if (prev == from) { speed += speedDir; } else { speed += new Vector(backDir[prev.posX, prev.posY].back()); } } speed = speed.normalized; foreach (AxisDirection dir in Enum.GetValues(typeof(AxisDirection))) { if (!cur.canGoInDirection(dir)) continue; var next = cur.nextTileInDirection(dir); if (next == null) continue; var nextCost = cost[cur.posX, cur.posY] + (speed * new Vector(dir)) * -0.7 + 1; if (nextCost < cost[next.posX, next.posY]) { cost[next.posX, next.posY] = nextCost; backDir[next.posX, next.posY] = dir.back(); q.Enqueue(next); } } } { var localPath = new LinkedList<Tile>(); var last = to; while (last != from && last != null) { localPath.AddFirst(last); last = last.nextTileInDirection(backDir[last.posX, last.posY]); } foreach (var tile in localPath) { tilePath.Add(tile); } } Vector retSpeed = new Vector(backDir[to.posX, to.posY].back()); { var prev = to.nextTileInDirection(backDir[to.posX, to.posY]); if (prev == from) { retSpeed += speedDir; } else if (prev != null) { retSpeed += new Vector(backDir[prev.posX, prev.posY].back()); } else { retSpeed += speedDir; } retSpeed = retSpeed.normalized; } return retSpeed; }