Exemplo n.º 1
0
        /*
         * Handle a collision between a unit and wall
         */
        public void CheckWallCollision(GameUnit unit, Map map)
        {
            List<Vector2> dirs = new List<Vector2>();
            dirs.Add(new Vector2(0, 1));
            dirs.Add(new Vector2(1, 0));
            dirs.Add(new Vector2(0, -1));
            dirs.Add(new Vector2(-1, 0));
            dirs.Add(new Vector2(1, 1));
            dirs.Add(new Vector2(1, -1));
            dirs.Add(new Vector2(-1, 1));
            dirs.Add(new Vector2(-1, -1));

            foreach (Vector2 dir in dirs)
            {
                if(!map.canMoveToWorldPos(unit.Position + dir * unit.Size/2))
                {
                    int i = 0;
                    while (i++ < unit.Size && !map.canMoveToWorldPos(unit.Position + dir * unit.Size/2))
                    {
                        unit.Position -= dir;
                    }
                }
            }
        }
Exemplo n.º 2
0
        /*
         * Finds the tile based path from start to end, given in world coordinates
         */
        public static List<Vector2> findPath(Map map, Vector2 start, Vector2 end, int limit, bool exploreAll)
        {
            if (!map.canMoveToWorldPos(end))
            {
                return null;
            }

            BinaryHeap<PathNode> node_queue = new BinaryHeap<PathNode>(new NodeCompararer()); // use comparator
            HashSet<PathNode> visited = new HashSet<PathNode>();

            Vector2 mapStart = map.translateWorldToMap(start);
            Vector2 mapEnd = map.translateWorldToMap(end);
            Point startPoint = new Point((int)mapStart.X, (int)mapStart.Y);
            Point endPoint = new Point((int)mapEnd.X, (int)mapEnd.Y);

            PathNode startNode = new PathNode(startPoint);
            startNode.G_score = 0;
            startNode.H_score = calculateHeuristic(startPoint, endPoint);
            node_queue.Insert(startNode);
            while (node_queue.Count > 0)
            {
                PathNode current = node_queue.RemoveRoot(); // O(logn)
                PathNode current2 = getMin(node_queue.GetList());

                if (!exploreAll && current.Pos.Equals(endPoint))
                {
                    return constructPath(current);
                }
                if (current.G_score + 1 > limit)    // Don't explore tiles too far
                {
                    continue;
                }
                visited.Add(current);

                List<Point> adj = getAdjacent(current.Pos);
                foreach (Point position in adj)
                {
                    if (visited.Contains(new PathNode(position)) || !map.canMoveTo(position.X, position.Y))
                    {
                        continue;
                    }
                    PathNode node = nodeAtPosition(node_queue, position);   // O(n)
                    if (node != null && current.G_score + 1 < node.G_score)
                    {
                        node.G_score = current.G_score + 1;
                        node.Parent = current;
                        node_queue.RemoveNode(node);    // O(n)
                        node_queue.Insert(node);        // O(logn)
                    }
                    else if(node == null)
                    {
                        node = new PathNode(position);
                        node.G_score = current.G_score + 1;
                        node.H_score = calculateHeuristic(node.Pos, endPoint);
                        node.Parent = current;
                        node_queue.Insert(node);    // O(logn)
                    }
                }
            }

            if (!exploreAll) return null;

            // Populate the point location map, initialize with (-1, -1)
            pointLocMap = new Vector2[map.HeightTiles, map.WidthTiles];
            for (int i = 0; i < pointLocMap.GetLength(0); i++)
            {
                for (int j = 0; j < pointLocMap.GetLength(1); j++)
                {
                    pointLocMap[i, j] = new Vector2(-1, -1);
                }
            }

            pointLocMap[(int)mapStart.Y, (int)mapStart.X] = mapStart;
            foreach(PathNode node in visited) {
                if (pointLocMap[node.Pos.Y, node.Pos.X] == new Vector2(-1, -1))
                {
                    Vector2 nodePos = new Vector2(node.Pos.X * Map.TILE_SIZE + Map.TILE_SIZE/2,
                        node.Pos.Y * Map.TILE_SIZE + Map.TILE_SIZE/2);
                    if (map.rayCastHasObstacle(nodePos, end, Map.TILE_SIZE/3))
                    {
                        pointLocMap[node.Pos.Y, node.Pos.X] = new Vector2(node.Parent.Pos.X, node.Parent.Pos.Y);
                    }
                    else
                    {
                        pointLocMap[node.Pos.Y, node.Pos.X] = mapEnd;
                    }
                    //collapseBlockedPaths(node, map);
                }
            }

            return null;
        }