Exemplo n.º 1
0
 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;
 }
Exemplo n.º 2
0
 public TilePathNode(Tile _tile)
 {
     tile = _tile;
     waypointIndex = -1;
 }
Exemplo n.º 3
0
        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;
        }
Exemplo n.º 4
0
        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;
        }