示例#1
0
        /**
         * 判断能否从当前cell走到下一个cell
         * @param startCell
         * @param nextCell
         * @return
         */
        private bool canWalkToNextCell(Point startCell, Point nextCell)
        {
            // 下一个点在阻挡区域,直接不可达
            if (AStarCell.isObstacle(map.getCell(nextCell.x, nextCell.y)))
            {
                return(false);
            }

            // 下一个cell是前一个cell的上下左右的cell,可达
            if (startCell.x == nextCell.x || startCell.y == nextCell.y)
            {
                return(true);
            }

            // 否则是对角cell,判断法向对角的两个cell是否都在阻挡区域,如果是则不可达
            if (AStarCell.isObstacle(map.getCell(startCell.x, nextCell.y)) &&
                AStarCell.isObstacle(map.getCell(nextCell.x, startCell.y)))
            {
                return(false);
            }
            else
            {
                return(true);
            }
        }
示例#2
0
        /**
         * Bresenham line algorithm
         * @param start
         * @param goal
         * @return
         */
        public Point raycast(Vector2 startPos, Vector2 goalPos, float cellSize)
        {
            Point startCell = posToCell(startPos, cellSize);
            Point goalCell  = posToCell(goalPos, cellSize);

            // exception: start is obstacle. Now just return start
            if (AStarCell.isObstacle(map.getCell(startCell.x, startCell.y)))
            {
                return(startCell);
            }

            if (startCell.Equals(goalCell))
            {
                return(startCell);
            }

            float diffx          = goalPos.x - startPos.x;
            float diffy          = goalPos.y - startPos.y;
            float distanceSquare = diffx * diffx + diffy * diffy;
            float distance       = (float)Math.Sqrt(distanceSquare);

            Vector2 dir = new Vector2(diffx / distance, diffy / distance);

            Vector2 lastPassed = startPos;
            Point   hitPoint   = new Point(startCell.x, startCell.y);

            while (true)
            {
                Vector2 nextPos = getNextPos(lastPassed, dir, cellSize);

                Point newCell = posToCell(nextPos, cellSize);

                float dis = (nextPos.x - startPos.x) * (nextPos.x - startPos.x) + (nextPos.y - startPos.y) * (nextPos.y - startPos.y);
                if (dis >= distanceSquare)
                {
                    break;
                }

                if (!canWalkToNextCell(hitPoint, newCell))
                {
                    break;
                }
                else
                {
                    hitPoint.x = newCell.x;
                    hitPoint.y = newCell.y;

                    if (newCell.Equals(goalCell))
                    {
                        break;
                    }
                }

                lastPassed = nextPos;
            }

            return(hitPoint);
        }
示例#3
0
        public PrintMap(AStarMap map, List <Point> shortestPath)
        {
            StringBuilder sb = new StringBuilder();
            AStarCell     cell;

            for (int y = 0; y < map.getHeightInCells(); y++)
            {
                if (y == 0)
                {
                    for (int i = 0; i <= map.getHeightInCells(); i++)
                    {
                        sb.Append("-");
                    }
                    sb.AppendLine();
                }
                sb.Append("|");

                for (int x = 0; x < map.getWidthInCells(); x++)
                {
                    cell = map.getCell(x, y);

                    if (AStarCell.isObstacle(cell))
                    {
                        sb.Append("X");
                    }
                    else if (isStart(shortestPath, cell.getPoint()))
                    {
                        sb.Append("s");
                    }
                    else if (isGoal(shortestPath, cell.getPoint()))
                    {
                        sb.Append("g");
                    }
                    else if (contains(shortestPath, cell.getPoint()))
                    {
                        sb.Append("?");
                    }
                    else
                    {
                        sb.Append(" ");
                    }
                    if (y == map.getHeightInCells())
                    {
                        sb.Append("_");
                    }
                }

                sb.Append("|");
                sb.AppendLine();
            }
            for (int i = 0; i <= map.getHeightInCells(); i++)
            {
                sb.Append("-");
            }
            //System.Console.SetWindowSize(System.Console.LargestWindowWidth, System.Console.LargestWindowHeight);
            //System.Console.Write(sb.ToString());
        }
示例#4
0
        private bool lineClear(Point a, Point b)
        {
            List <Point> pointsOnLine = Bresenham.getCellsOnLine(a, b);

            foreach (Point p in pointsOnLine)
            {
                AStarCell cell = map.getCell(p.x, p.y);
                if (cell == null || cell.isObstacle())
                {
                    return(false);
                }
            }
            return(true);
        }
示例#5
0
        public Point raycast(Point start, Point goal)
        {
            List <Point> pointsOnLine = Bresenham.getCellsOnLine(start, goal);

            Point hitPoint = (Point)start.Clone();

            foreach (Point p in pointsOnLine)
            {
                AStarCell cell = map.getCell(p.x, p.y);
                if (cell == null || cell.isObstacle())
                {
                    break;
                }
                else
                {
                    hitPoint = p;
                }
            }
            return(hitPoint);
        }
示例#6
0
        public Vector2 Raycast(Vector2 startPos, Vector2 endPos)
        {
            Point startCell = PathFinder.posToCell(startPos, astarMap.getCellSize());
            Point goalCell  = PathFinder.posToCell(endPos, astarMap.getCellSize());

            // exception: start is obstacle. Now just return start
            if (AStarCell.isObstacle(astarMap.getCell(startCell.x, startCell.y)))
            {
                return(startPos);
            }

            if (startCell.Equals(goalCell))
            {
                return(endPos);
            }

            Point   hitCell = pathFinder.raycast(startPos, endPos, astarMap.getCellSize());
            Vector2 hitPos  = PathFinder.cellToPos(hitCell, astarMap.getCellSize());
            Vector2 dir     = (endPos - startPos).normalized;

            hitPos = PathFinder.getNextPosBeforeNextCell(hitPos, dir, astarMap.getCellSize());
            return(hitPos);
        }
示例#7
0
        public Point getCellWithErrorTolerate(float x, float y)
        {
            int       cellX = (int)Math.Floor((x + map.getErrorTolerate()) / map.getCellSize());
            int       cellY = (int)Math.Floor((y + map.getErrorTolerate()) / map.getCellSize());
            AStarCell cell  = map.getCell(cellX, cellY);

            if (!AStarCell.isObstacle(cell))
            {
                return(new Point(cellX, cellY));
            }

            cellX = (int)Math.Floor((x - map.getErrorTolerate()) / map.getCellSize());
            cellY = (int)Math.Floor((y - map.getErrorTolerate()) / map.getCellSize());
            cell  = map.getCell(cellX, cellY);
            if (!AStarCell.isObstacle(cell))
            {
                return(new Point(cellX, cellY));
            }

            cellX = (int)Math.Floor((x + map.getErrorTolerate()) / map.getCellSize());
            cellY = (int)Math.Floor((y - map.getErrorTolerate()) / map.getCellSize());
            cell  = map.getCell(cellX, cellY);
            if (!AStarCell.isObstacle(cell))
            {
                return(new Point(cellX, cellY));
            }

            cellX = (int)Math.Floor((x - map.getErrorTolerate()) / map.getCellSize());
            cellY = (int)Math.Floor((y + map.getErrorTolerate()) / map.getCellSize());
            cell  = map.getCell(cellX, cellY);
            if (!AStarCell.isObstacle(cell))
            {
                return(new Point(cellX, cellY));
            }

            return(null);
        }