Example #1
0
 private GlobalHelper()
 {
     curLevelTileGrid_ = null;
 }
Example #2
0
 public void setCurrentLevelTileGrid(TileGrid grid)
 {
     curLevelTileGrid_ = grid;
 }
        private static TileIndex getNearest(TileGrid grid, TileIndex start, TileIndex destination, float radius, Height height)
        {
            radius = radius / (TileGrid.TILEHEIGHT + TileGrid.TILEWIDTH) / 2;

            Tile dest = grid.getTile(destination);

            if (!dest.collides(height, radius))
            {
                return destination;
            }

            short manhattan = 1;

            // Expand outward by increasing the manhattan distance
            // Until finding some subset of tiles which we can walk on
            // TODO
            // Don't use heap space here
            List<TileIndex> closest = new List<TileIndex>();
            while (closest.Count == 0)
            {
                Tile cur;
                int newX;
                int newY;

                for (short i = 0; i < manhattan - 1; i++)
                {
                    // Quadrant I
                    newX = destination.x_ + i;
                    newY = destination.y_ + (manhattan - i);
                    cur = grid.getTile(newX, newY);
                    if (!cur.collides(height, radius))
                    {
                        closest.Add(new TileIndex((short)newX, (short)newY));
                    }

                    // Quadrant II
                    newX = destination.x_ - i;
                    newY = destination.y_ + (manhattan - i);
                    cur = grid.getTile(newX, newY);
                    if (!cur.collides(height, radius))
                    {
                        closest.Add(new TileIndex((short)newX, (short)newY));
                    }

                    // Quadrant III
                    newX = destination.x_ - i;
                    newY = destination.y_ - (manhattan - i);
                    cur = grid.getTile(newX, newY);
                    if (!cur.collides(height, radius))
                    {
                        closest.Add(new TileIndex((short)newX, (short)newY));
                    }

                    // Quadrant IV
                    newX = destination.x_ + i;
                    newY = destination.y_ - (manhattan - i);
                    cur = grid.getTile(newX, newY);
                    if (!cur.collides(height, radius))
                    {
                        closest.Add(new TileIndex((short)newX, (short)newY));
                    }
                }

                manhattan++;
                if (manhattan > 10)
                {
                    return new TileIndex(-1, -1);
                }
            }

            // We've found walkable tiles, and they are all the same manhattan
            //  distance from the destination, so pick closest to the start
            // TODO
            // Determine whether it's better to pick closest real distance to
            //  destination first
            TileIndex best = new TileIndex(-1, -1);
            float bestScore = float.MaxValue;
            for (int i = 0; i < closest.Count; i++)
            {
                float score = CommonFunctions.distance(closest[i], start);
                if (score < bestScore)
                {
                    bestScore = score;
                    best = closest[i];
                }
            }

            return best;
        }
        protected static void setupSearch(TileGrid grid, TileIndex start, TileIndex destination, float radius, Height height)
        {
            // Initialize the static structures used by the search
            reset();

            start_ = start;
            goal_ = destination;

            // Project our start and goal nodes into the search space, if possible
            // TODO
            // For now, if they are farther apart than the size of the search space in
            // any dimension, we give up - in the future, they will try to get as close
            // as possible
            short manhattanX = (short)Math.Abs(start_.x_ - goal_.x_);
            short manhattanY = (short)Math.Abs(start_.y_ - goal_.y_);
            short leftOffset = (short)Math.Floor((SEARCH_SPACE_WIDTH - manhattanX) / 2.0f);
            short rightOffset = (short)Math.Ceiling((SEARCH_SPACE_WIDTH - manhattanX) / 2.0f);
            short bottomOffset = (short)Math.Floor((SEARCH_SPACE_HEIGHT - manhattanY) / 2.0f);
            short topOffset = (short)Math.Ceiling((SEARCH_SPACE_HEIGHT - manhattanY) / 2.0f);
            gridXOffset_ = (short)(Math.Min(start_.x_, goal_.x_) - leftOffset);
            gridYOffset_ = (short)(Math.Min(start_.y_, goal_.y_) - topOffset);

            if (gridXOffset_ < 0) gridXOffset_ = 0;
            if (gridYOffset_ < 0) gridYOffset_ = 0;
            start_.x_ -= gridXOffset_;
            start_.y_ -= gridYOffset_;
            goal_.x_ -= gridXOffset_;
            goal_.y_ -= gridYOffset_;

            searchRadius_ =
                (float)(radius / ((TileGrid.TILEWIDTH + TileGrid.TILEHEIGHT) / 2.0f));
            grid_ = grid;
            searchHeight_ = height;
        }
 public static List<TileIndex> calculateNearbyPath(TileGrid grid, Vector2 start, Vector2 destination, float radius, Height height)
 {
     return calculateNearbyPath(grid, grid.getTileIndex(start), grid.getTileIndex(destination), radius, height);
 }
 public static List<TileIndex> calculateNearbyPath(TileGrid grid, TileIndex start, TileIndex destination, float radius, Height height)
 {
     TileIndex newdest = getNearest(grid, start, destination, radius, height);
     if (newdest.x_ == -1 || newdest.y_ == -1)
     {
         //throw new Exception("AStarPathfinder failed to find a nearest tile!");
         return null;
     }
     return calculateExactPath(grid, start, newdest, radius, height);
 }
        /// <summary>
        /// Run the A* algorithm to get a navigation path.
        /// </summary>
        /// <param name="grid">The area being searched</param>
        /// <param name="start">Index of the start tile.</param>
        /// <param name="destination">Index of the destination tile.</param>
        /// <param name="radius">Radius of the character performing the search</param>
        /// <param name="tileHeight">Height of the character performing the search</param>
        /// <returns>Waypoints which should allow the character to reach the goal.</returns>
        public static List<TileIndex> calculateExactPath(TileGrid grid, TileIndex start, TileIndex destination, float radius, Height height)
        {
            #if DEBUG
            clock.Start();
            #endif

            setupSearch(grid, start, destination, radius, height);

            //Console.WriteLine("Pathfind Start: " + start_.x_ + "," + start_.y_);
            //Console.WriteLine("Pathfind Goal: " + goal_.x_ + "," + goal_.y_);

            TileIndex cur = start_;
            searchSpace_[cur.x_, cur.y_].g = 0;
            searchSpace_[cur.x_, cur.y_].f = heuristicDistance(cur.x_, cur.y_);
            searchSpace_[cur.x_, cur.y_].parent = new TileIndex(-1, -1); // stack
            touched_[cur.x_, cur.y_] = true;

            // As long as we aren't at the goal, keep expanding outward and checking
            // the next most promising node
            while (!TileIndex.equals(goal_, cur))
            {
                searchSpace_[cur.x_, cur.y_].open = false;
                expand(ref cur, searchSpace_[cur.x_, cur.y_].g);

                // If we are out of nodes to check, no path exists
                if (openlist_.Count == 0)
                {
            #if DEBUG
                    clock.Stop();
            #endif
                    return null;
                }
                else
                {
                    cur = getNext();
                }
            }
            #if DEBUG
            clock.Stop();
            #endif
            return recreatePath();
        }