示例#1
0
    public List <PathNode> GetPath(PathNode start, PathNode end)
    {
        WaypointManager wg      = GameObject.Find("WaypointManager").GetComponent <WaypointManager>();
        var             sources = wg.pathNodes;

        if (start == null || end == null)
        {
            if (sources != null && sources.Count >= 2)
            {
                start = sources[PathNode.startNode] /*.GetComponent<PathNode>()*/;               //.GetInnerObject();
                end   = sources[PathNode.endNode] /*.GetComponent<PathNode>()*/;                 //.GetInnerObject();
            }

            if (start == null || end == null)
            {
                Debug.LogWarning("Need 'start' and or 'end' defined!");
                enabled = false;
                return(null);
            }
        }

        startIndex = Closest(sources, start.position);

        endIndex = Closest(sources, end.position);

        return(AStarHelper.Calculate(sources[startIndex] /*.GetComponent<PathNode>()*/, sources[endIndex] /*.GetComponent<PathNode>()*/));
    }
示例#2
0
        internal override Boolean CalculatePath(GridSlot p_start, GridSlot p_target, List <GridSlot> p_pathBuffer)
        {
            if (!p_target.CheckForSummons())
            {
                AStarHelper <GridSlot> .Calculate(p_start, p_target, GameConfig.MaxSteps, m_owner, false, true, true, p_pathBuffer);

                return(p_pathBuffer.Count > 0);
            }
            List <GridSlot> list;

            if (Position.Distance(p_target.Position, LegacyLogic.Instance.WorldManager.Party.Position) <= 1.1f)
            {
                list = GetMeleeTargets(LegacyLogic.Instance.MapLoader.Grid, LegacyLogic.Instance.WorldManager.Party);
            }
            else
            {
                list = GetRangedTargets(LegacyLogic.Instance.MapLoader.Grid, LegacyLogic.Instance.WorldManager.Party);
            }
            if (list.FindAll(new Predicate <GridSlot>(FindSlotsWithSummons)).Count == list.Count)
            {
                return(base.CalculatePath(p_start, p_target, p_pathBuffer));
            }
            list.RemoveAll(new Predicate <GridSlot>(FindSlotsWithSummons));
            list.Sort(new Comparison <GridSlot>(DistSortAsc));
            AStarHelper <GridSlot> .Calculate(p_start, list[0], GameConfig.MaxSteps, m_owner, false, true, true, p_pathBuffer);

            list.Sort(new Comparison <GridSlot>(DistSortAsc));
            return(p_pathBuffer.Count > 0);
        }
示例#3
0
    public static int Closest(List </*GameObject*/ PathNode> inNodes, Vector3 toPoint)
    {
        int   closestIndex = 0;
        float minDist      = float.MaxValue;

        for (int i = 0; i < inNodes.Count; i++)
        {
            if (AStarHelper.Invalid(inNodes[i] /*.GetComponent<PathNode>()*/))
            {
                continue;
            }
            float thisDist = Vector3.Distance(toPoint, inNodes[i] /*.GetComponent<PathNode>()*/.Position);
            if (thisDist > minDist)
            {
                continue;
            }

            minDist      = thisDist;
            closestIndex = i;
        }

        if (minDist != float.MaxValue)
        {
            return(closestIndex);
        }
        else
        {
            return(-1);
        }
    }
    public void EstablishEnemyPositions()
    {
        positionToNearestCharacter.Clear();
        nearestCharacter.Clear();
        var currentRoster     = EnemyRosterController.instance.GetCurrentRoster();
        var currentCharacters = GameObject.FindGameObjectsWithTag("Player");

        foreach (EnemyController enemy in currentRoster)
        {
            var pos   = new List <GridTile>();
            var start = GridController.instance.GetTileAtPosition(enemy.transform.position);
            foreach (GameObject player in currentCharacters)
            {
                if (!player.activeInHierarchy)
                {
                    continue;
                }
                var end    = GridController.instance.GetTileAtPosition(player.transform.position);
                var toChar = AStarHelper.GetPath(start, end, true);
                Debug.Log("Checking path to " + player.name + " and found path of length " + toChar.Count);
                if (pos.Count == 0 || pos.Count > toChar.Count)
                {
                    pos = toChar;
                    nearestCharacter[enemy] = player.GetComponent <PlayerCharacterController>();
                }
            }
            positionToNearestCharacter[enemy] = pos;
        }
    }
示例#5
0
    //This is always called after the objects have been sorted, use cached position
    public EnemyAction GetAction()
    {
        var positionOfNearestCharacter = FindClosestPlayer().transform.position;

        //Need to recalculate path as may have changed by previous moves
        var pathToNearestCharacter = AStarHelper.GetPath(
            GridController.instance.GetTileAtPosition(transform.position),
            GridController.instance.GetTileAtPosition(positionOfNearestCharacter)
            );

        var list = pathToNearestCharacter.ConvertAll(
            new System.Converter <GridTile, Vector2>(GetWorldPositionOfGridTile)
            );

        //Need to find the nearest character and create an int list of positions to move towards
        if (list.Count > 0)
        {
            return(new MoveToTargetPositionAction(
                       gameObject,
                       this,
                       movementStyle,
                       list.GetRange(0, Mathf.Min(availableMove - 1, list.Count))
                       ));
        }
        else
        {
            return(new MoveToTargetPositionAction(
                       gameObject,
                       this,
                       movementStyle,
                       list
                       ));
        }
    }
示例#6
0
        public override void CheckVisibility(Boolean skipAnimation)
        {
            base.CheckVisibility(skipAnimation);
            Single num = 0f;

            if (MyController != null)
            {
                Monster monster = (Monster)MyController;
                Party   party   = LegacyLogic.Instance.WorldManager.Party;
                if (party != null && party.HasDangerSense())
                {
                    Int32    monsterVisibilityRangeWithDangerSense = ConfigManager.Instance.Game.MonsterVisibilityRangeWithDangerSense;
                    Grid     grid  = LegacyLogic.Instance.MapLoader.Grid;
                    GridSlot slot  = grid.GetSlot(monster.Position);
                    GridSlot slot2 = grid.GetSlot(party.Position);
                    Int32    num2  = AStarHelper <GridSlot> .Calculate(slot, slot2, monsterVisibilityRangeWithDangerSense, null, false, null);

                    if (num2 > 0)
                    {
                        num = 1f;
                    }
                }
                else if (party != null && monster.IsAggro && 1f >= Position.DistanceSquared(monster.Position, party.Position))
                {
                    num = 1f;
                }
            }
            if (num == 0f)
            {
                TooltipManager.Instance.Hide(this);
            }
            collider.enabled = (num > 0f);
            TweenAlpha.Begin(gameObject, (!skipAnimation) ? 1 : 0, num);
        }
示例#7
0
        private static Boolean InMoveRange(Grid grid, Position start, Position target, Int32 range)
        {
            GridSlot slot  = grid.GetSlot(start);
            GridSlot slot2 = grid.GetSlot(target);
            Int32    num   = AStarHelper <GridSlot> .Calculate(slot, slot2, range, null, false, null);

            return(num > 0);
        }
 public AStar(AStarHelper aStarHelper, int start, int goal, MZDungeon dungeon)
 {
     this.aStarHelper = aStarHelper;
     this.start       = start;
     this.goal        = goal;
     this.dungeon     = dungeon;
     this.current     = start;
     openSet          = new Dictionary <int, float>();
     closedSet        = new List <int>();
 }
示例#9
0
        internal virtual Boolean CalculatePath(GridSlot p_start, GridSlot p_target, List <GridSlot> p_pathBuffer)
        {
            // Avoid to stack agro monsters due to cast of spell or long obstacles
            Int32 maxSteps = GameConfig.MaxSteps;

            if (m_owner.IsAggro)
            {
                maxSteps *= 3;
            }

            return(AStarHelper <GridSlot> .Calculate(p_start, p_target, maxSteps, m_owner, false, p_pathBuffer) > 0);
        }
示例#10
0
    /// <summary>
    /// Generate the level
    /// </summary>
    public void Generate()
    {
        roadSize = SceneParameters.initialSize;
        Transform  firstChunk, veryLastChunk;
        GameObject fline;
        GameObject car = GameObject.Find("Car");

        // Initialization
        rays = new Vector3[6];
        hits = new RaycastHit[6];
        bool done = false;


        while (!done)
        {
            RemoveAll();
            lastRotY = 0.0f;
            lastIdx  = 0;
            putChunks(gameObject.transform, 0.0f, 0, -1);

            firstChunk = transform.Find("part-0");

            AStarHelper astar = new AStarHelper(firstChunk, this);
            done = astar.run();

            if (!done)
            {
                Debug.Log("Trying again");
            }
            //GameObject inicio = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
            //inicio.transform.position= firstChunk.position ;//- new Vector3(0,0,0.25f*firstChunk.GetComponent<BoxCollider>().size.z);
            //Debug.Log(transform.position);
        }

        firstChunk = transform.Find("part-0");

        float carX = (firstChunk.position.x + firstChunk.GetComponent <RoadChunk> ().mountPoint.transform.position.x) / 2;
        float carZ = (firstChunk.position.z + firstChunk.GetComponent <RoadChunk> ().mountPoint.position.z) / 2;

        car.transform.position = new Vector3(carX, firstChunk.position.y + 0.01f, carZ);
        car.transform.rotation = firstChunk.GetComponent <RoadChunk> ().mountPoint.rotation;
        car.transform.Rotate(new Vector3(0, 180, 0));
        //firstChunk.GetComponent<RoadChunk>().mountPoint.rotation.eulerAngles.y /2, 0));
        //fline = UnityEngine.Object.Instantiate (FinishLine) as GameObject;
        //fline.transform.position = new Vector3 (1.5f, 6f, 7f);
        //fline.transform.rotation = new Quaternion (0, 0, 0, 0);
        //fline.transform.Rotate (new Vector3 (0, 90, 0));
    }
示例#11
0
        internal Boolean TryMove(List <GridSlot> p_targets, Grid p_grid, GridSlot p_startSlot, Party p_party)
        {
            if (m_owner.CombatHandler.CanMove)
            {
                List <GridSlot> pathBuffer = m_PathBuffer;
                GridSlot        gridSlot   = null;
                Int32           num        = 999;
                GridSlot        gridSlot2  = null;
                foreach (GridSlot gridSlot3 in p_targets)
                {
                    pathBuffer.Clear();
                    if (CalculatePath(p_startSlot, gridSlot3, pathBuffer) && pathBuffer.Count < num)
                    {
                        gridSlot  = gridSlot3;
                        num       = pathBuffer.Count;
                        gridSlot2 = pathBuffer[1];
                    }
                }
                if (gridSlot != null)
                {
                    EDirection lineOfSightDirection = EDirectionFunctions.GetLineOfSightDirection(p_startSlot.Position, gridSlot2.Position);
                    if (lineOfSightDirection != EDirection.CENTER)
                    {
                        m_owner.Direction = EDirectionFunctions.GetDirection(gridSlot2.Position, p_party.Position);
                        if (p_grid.MoveEntity(m_owner, lineOfSightDirection))
                        {
                            m_targetSlot = gridSlot;
                            GridSlot slot  = p_grid.GetSlot(m_owner.Position);
                            GridSlot slot2 = p_grid.GetSlot(p_party.Position);
                            Int32    num2  = AStarHelper <GridSlot> .Calculate(slot, slot2, GameConfig.MaxSteps, m_owner, true, null);

                            if (num2 > 0)
                            {
                                m_owner.DistanceToParty = num2;
                            }
                            else
                            {
                                m_owner.DistanceToParty = 99f;
                            }
                            m_owner.StartMovement.Trigger();
                            return(true);
                        }
                    }
                }
            }
            return(false);
        }
示例#12
0
    /// <summary>
    /// Generate the level
    /// </summary>
    public void Generate()
    {
        roadSize = SceneParameters.initialSize;
        Transform firstChunk, veryLastChunk;
        GameObject fline;
        GameObject car = GameObject.Find ("Car");

        // Initialization
        rays = new Vector3[6];
        hits = new RaycastHit[6];
        bool done = false;

        while (!done) {
            RemoveAll ();
            lastRotY = 0.0f;
            lastIdx = 0;
            putChunks (gameObject.transform, 0.0f, 0, -1);

            firstChunk = transform.Find ("part-0");

            AStarHelper astar = new AStarHelper (firstChunk, this);
            done = astar.run ();

            if (!done) {
                Debug.Log ("Trying again");
            }
            //GameObject inicio = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
            //inicio.transform.position= firstChunk.position ;//- new Vector3(0,0,0.25f*firstChunk.GetComponent<BoxCollider>().size.z);
            //Debug.Log(transform.position);
        }

        firstChunk = transform.Find ("part-0");

        float carX = (firstChunk.position.x + firstChunk.GetComponent<RoadChunk> ().mountPoint.transform.position.x) / 2;
        float carZ = (firstChunk.position.z + firstChunk.GetComponent<RoadChunk> ().mountPoint.position.z) / 2;

        car.transform.position = new Vector3 (carX, firstChunk.position.y + 0.01f, carZ);
        car.transform.rotation = firstChunk.GetComponent<RoadChunk> ().mountPoint.rotation;
        car.transform.Rotate (new Vector3 (0, 180, 0));
        //firstChunk.GetComponent<RoadChunk>().mountPoint.rotation.eulerAngles.y /2, 0));
        //fline = UnityEngine.Object.Instantiate (FinishLine) as GameObject;
        //fline.transform.position = new Vector3 (1.5f, 6f, 7f);
        //fline.transform.rotation = new Quaternion (0, 0, 0, 0);
        //fline.transform.Rotate (new Vector3 (0, 90, 0));
    }
示例#13
0
        // 输出的顶点数和边数相同
        public bool FindCross2CrossPaths(GpsMapCell fromCross, GpsMapCell toCross,
                                         out List <MapPathGraph.NavigateVertexNode> listNavigateVertexNode, out List <MapPathGraph.Edge> listEdge, AStarHelper ash = null)
        {
            if (ash == null)
            {
                ash = new AStarHelper(this.CalcDistanceWeight);
            }
            ash.Clear();

            listNavigateVertexNode = new List <MapPathGraph.NavigateVertexNode>();
            listEdge = new List <MapPathGraph.Edge>();
            float weight = this.pathGraph.FindShortestPaths(ash,
                                                            this.pathGraph.GetVertex(fromCross.Index),
                                                            this.pathGraph.GetVertex(toCross.Index),
                                                            listNavigateVertexNode);

            this.pathGraph.NormalizeVertexAndSpotsOrder(listNavigateVertexNode, listEdge);

            listNavigateVertexNode.RemoveAt(0); // 去掉首结点,因其不指导导航路径,与FindCell2CrossPath一致
            return(weight >= 0);
        }
        public override void DoTurn(Grid p_grid, Party p_party)
        {
            if (m_owner.State == Monster.EState.SPAWNING)
            {
                return;
            }
            if (m_firstAction)
            {
                m_owner.AbilityHandler.ExecuteAttacks(null, null, false, EExecutionPhase.BEGIN_OF_MONSTERS_TURN);
                m_owner.AbilityHandler.FlushActionLog(EExecutionPhase.BEGIN_OF_MONSTERS_TURN);
                m_owner.BuffHandler.ModifyMonsterValues();
                m_owner.CombatHandler.MeleeStrikes          += m_owner.CombatHandler.MeleeStrikesRoundBonus;
                m_owner.CombatHandler.MeleeStrikesRoundBonus = 0;
                GridSlot neighborSlot = p_grid.GetSlot(m_owner.Position).GetNeighborSlot(p_grid, m_owner.Direction);
                if (p_grid.MoveEntity(m_owner, m_owner.Direction))
                {
                    m_targetSlot = neighborSlot;
                    GridSlot slot  = p_grid.GetSlot(m_owner.Position);
                    GridSlot slot2 = p_grid.GetSlot(p_party.Position);
                    Int32    num   = AStarHelper <GridSlot> .Calculate(slot, slot2, GameConfig.MaxSteps, m_owner, true, null);

                    if (num > 0)
                    {
                        m_owner.DistanceToParty = num;
                    }
                    else
                    {
                        m_owner.DistanceToParty = 99f;
                    }
                    m_owner.StartMovement.Trigger();
                    m_firstAction = false;
                    return;
                }
            }
            else
            {
                base.DoTurn(p_grid, p_party);
            }
        }
示例#15
0
        public virtual void UpdateDistanceToParty(Party p_party, Grid p_grid)
        {
            GridSlot slot  = p_grid.GetSlot(m_owner.Position);
            GridSlot slot2 = p_grid.GetSlot(p_party.Position);
            Int32    num;

            if (m_owner.IsAggro)
            {
                num = AStarHelper <GridSlot> .Calculate(slot, slot2, GameConfig.MaxSteps, m_owner, true, false, m_canOpenDoors, null);
            }
            else
            {
                num = AStarHelper <GridSlot> .Calculate(slot, slot2, (Int32)m_owner.AggroRange + 1, m_owner, true, false, m_canOpenDoors, null);
            }
            if (num > 0)
            {
                m_owner.DistanceToParty = num - 1;
            }
            else
            {
                m_owner.DistanceToParty = 99f;
            }
        }
示例#16
0
    // Calculate the A* path
    public static List <T> Calculate <T>(T start, T goal) where T : IPathNode <T>
    {
        List <T> closedset = new List <T>(); // The set of nodes already evaluated.
        List <T> openset   = new List <T>(); // The set of tentative nodes to be evaluated.

        openset.Add(start);
        Dictionary <T, T> came_from = new Dictionary <T, T>();    // The map of navigated nodes.

        Dictionary <T, float> g_score = new Dictionary <T, float>();

        g_score[start] = 0.0f; // Cost from start along best known path.

        Dictionary <T, float> h_score = new Dictionary <T, float>();

        h_score[start] = HeuristicCostEstimate(start, goal);

        Dictionary <T, float> f_score = new Dictionary <T, float>();

        f_score[start] = h_score[start]; // Estimated total cost from start to goal through y.

        System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();

        long elapsed = 0;

        sw.Start();

        while (openset.Count != 0)
        {
            T x = LowestScore(openset, f_score);
            if (x.Equals(goal))
            {
                List <T> result = new List <T>();
                ReconstructPath(came_from, x, ref result);
                return(result);
            }

            sw.Stop();

            elapsed += sw.ElapsedMilliseconds;

            if (elapsed > 5)
            {
                return(null);
            }

            sw.Start();

            openset.Remove(x);
            closedset.Add(x);
            foreach (T y in x.Connections)
            {
                if (AStarHelper.Invalid(y) || closedset.Contains(y))
                {
                    continue;
                }
                float tentative_g_score = g_score[x] + Distance(x, y);

                bool tentative_is_better = false;
                if (!openset.Contains(y))
                {
                    openset.Add(y);
                    tentative_is_better = true;
                }
                else if (tentative_g_score < g_score[y])
                {
                    tentative_is_better = true;
                }

                if (tentative_is_better)
                {
                    came_from[y] = x;
                    g_score[y]   = tentative_g_score;
                    h_score[y]   = HeuristicCostEstimate(y, goal);
                    f_score[y]   = g_score[y] + h_score[y];
                }
            }
        }

        return(null);
    }
示例#17
0
        // 输出的顶点数和边数相同
        public bool FindCell2CrossPath(GpsMapCell from, GpsMapCell cross,
                                       out List <MapPathGraph.NavigateVertexNode> listNavigateVertexNode, out List <MapPathGraph.Edge> listEdge)
        {
            listNavigateVertexNode = null;
            listEdge = null;

            from = FindNearestCellOf(from, GpsMapCell.EType.EN_ROAD);
            if (from == null)
            {
                XxdwDebugger.Log("Road nearby not found. Strange!");
                return(false);
            }

            int crossVertexIndex = this.pathGraph.FindVertex(cross.Index);

            if (crossVertexIndex < 0)
            {
                XxdwDebugger.Log("Target cross not found. Strange!");
                return(false);
            }
            MapPathGraph.VertexNode vnTo = this.pathGraph.VertexList[crossVertexIndex];

            MapPathGraph.VertexNode vn1, vn2;
            MapPathGraph.Edge       e;
            int spotIndex = FindEdgeOfRoadCell(from.Index, out vn1, out vn2, out e);

            if (spotIndex < 0)
            {
                XxdwDebugger.Log("Cross of road not found. Strange!");
                return(false);
            }
            float w1 = CalcDetailWeight(e.Spots, 0, spotIndex + 1);
            float w2 = CalcDetailWeight(e.Spots, spotIndex, e.Spots.Length);

            int[] spots1 = new int[spotIndex + 1];
            Array.Copy(e.Spots, 0, spots1, 0, spotIndex + 1);
            int[] spots2 = new int[e.Spots.Length - spotIndex];
            Array.Copy(e.Spots, spotIndex, spots2, 0, e.Spots.Length - spotIndex);

            MapPathGraph.Edge e1, e2;
            if (e.Spots[0] == vn1.Cell)
            {
                e1 = new MapPathGraph.Edge(vn1.Cell, e.Spots[spotIndex], w1, spots1, "");
                e1.ReverseSpots();
                e2 = new MapPathGraph.Edge(vn2.Cell, e.Spots[spotIndex], w2, spots2, "");
            }
            else
            {
                e1 = new MapPathGraph.Edge(vn1.Cell, e.Spots[spotIndex], w2, spots2, "");
                e2 = new MapPathGraph.Edge(vn2.Cell, e.Spots[spotIndex], w1, spots1, "");
                e2.ReverseSpots();
            }


            List <MapPathGraph.NavigateVertexNode> listNavigateVertexNode1 = new List <MapPathGraph.NavigateVertexNode>();
            List <MapPathGraph.NavigateVertexNode> listNavigateVertexNode2 = new List <MapPathGraph.NavigateVertexNode>();
            AStarHelper ash = new AStarHelper(this.CalcDistanceWeight);

            ash.Clear();
            float weight1 = this.pathGraph.FindShortestPaths(ash, vn1, vnTo, listNavigateVertexNode1);

            weight1 += weight1 >= 0 ? w1 : Parameters.MAX_EDGE_WEIGHT;
            ash.Clear();
            float weight2 = this.pathGraph.FindShortestPaths(ash, vn2, vnTo, listNavigateVertexNode2);

            weight2 += weight2 >= 0 ? w2 : Parameters.MAX_EDGE_WEIGHT;
            if (listNavigateVertexNode1.Count == 0 && listNavigateVertexNode2.Count == 0)
            {
                return(false);
            }

            listEdge = new List <MapPathGraph.Edge>();
            if (weight1 < weight2)
            {
                listNavigateVertexNode1[0].SelectedEdgeIndex = this.pathGraph.GetEdgeNumber(vn1, e);
                listNavigateVertexNode = listNavigateVertexNode1;
                this.pathGraph.NormalizeVertexAndSpotsOrder(listNavigateVertexNode, listEdge);
                listEdge.Insert(0, e1);
            }
            else
            {
                listNavigateVertexNode2[0].SelectedEdgeIndex = this.pathGraph.GetEdgeNumber(vn2, e);
                listNavigateVertexNode = listNavigateVertexNode2;
                this.pathGraph.NormalizeVertexAndSpotsOrder(listNavigateVertexNode, listEdge);
                listEdge.Insert(0, e2);
            }

            return(true);
        }
示例#18
0
    // Calculate the A* path
    public static List <T> Calculate <T>(T start, T goal) where T : IPathNode <T>
    {
        List <T> closedset = new List <T>();        // The set of nodes already evaluated.
        List <T> openset   = new List <T>();        // The set of tentative nodes to be evaluated.

        openset.Add(start);
        Dictionary <T, T> came_from = new Dictionary <T, T>();          // The map of navigated nodes.

        Dictionary <T, float> g_score = new Dictionary <T, float>();

        g_score[start] = 0.0f;         // Cost from start along best known path.

        Dictionary <T, float> h_score = new Dictionary <T, float>();

        h_score[start] = HeuristicCostEstimate(start, goal);

        Dictionary <T, float> f_score = new Dictionary <T, float>();

        f_score[start] = h_score[start];         // Estimated total cost from start to goal through y.

        while (openset.Count != 0)
        {
            T x = LowestScore(openset, f_score);
            if (x.Equals(goal))
            {
                List <T> result = new List <T>();
                ReconstructPath(came_from, x, ref result);
                return(result);
            }
            openset.Remove(x);
            closedset.Add(x);
            foreach (T y in x.Connections)
            {
                if (AStarHelper.Invalid(y) || closedset.Contains(y))
                {
                    continue;
                }
                float tentative_g_score;

                tentative_g_score = g_score[x] + Distance(x, y);

                bool tentative_is_better = false;
                if (!openset.Contains(y))
                {
                    openset.Add(y);
                    tentative_is_better = true;
                }
                else if (tentative_g_score < g_score[y])
                {
                    tentative_is_better = true;
                }

                if (tentative_is_better)
                {
                    came_from[y] = x;
                    g_score[y]   = tentative_g_score;
                    h_score[y]   = HeuristicCostEstimate(y, goal);
                    f_score[y]   = g_score[y] + h_score[y];
                }
            }
        }
        Debug.Log("(movePath null, tripped in AStarHelper. IF THIS IS TRIPPED THIS IS THE REASON WHY SHIT ISN'T WORKING." + openset.Count + " " + closedset.Count);
        return(null);
    }
示例#19
0
    void FixedUpdate()
    {
        AIPlayerPathCalculationTime++;

        if (AIPlayerPathCalculationTime > 5 && Chase())
        {
            //NEVER CHANGE THE FOLLOWING CODE.
            int layerMask = 1 << 9;             //WALLS ARE LAYER LEVEL 9. THIS NUMBER CANNOT CHANGE. YOU WILL BREAK THE GAME.
            //NEVER CHANGE THE PREVIOUS CODE.

            //Check if player is in sight, no pathfinding is required if player is in sight.
            {
                Vector2 start = transform.position;
                Vector2 end   = player.transform.position;

                RaycastHit2D hit = Physics2D.Linecast(start, end, layerMask);

                if (hit.collider != null)
                {
                    playerSeen = false;
                }
                else
                {
                    playerSeen = true;
                }
            }

            if (!playerSeen)
            {
                //TODO: LOW PRIORITY: Check if path to player already exists from closest node. If so, use said path.

                float  distance     = 999.0f;
                float  distance2    = 999.0f;
                AINode closestNode  = null;
                AINode closestNode2 = null;

                List <AINode> possibleNodes       = new List <AINode> ();
                List <AINode> possiblePlayerNodes = new List <AINode> ();

                //MONSTER CLOSEST NODE
                for (int i = 0; i < World.Instance.AINodeList.Count; i++)
                {
                    Vector2 start = transform.position;
                    Vector2 end   = World.Instance.AINodeList[i].transform.position;

                    RaycastHit2D hit = Physics2D.Linecast(start, end, layerMask);

                    if (hit.collider != null)
                    {
                        //This is not a possible node.
                        continue;
                    }
                    else
                    {
                        //This is a possible node.
                        possibleNodes.Add(World.Instance.AINodeList[i].attachedAINode);
                    }
                }

                for (int i = 0; i < possibleNodes.Count; i++)
                {
                    float tempDistance = Vector2.Distance(transform.position, possibleNodes[i].Position);
                    if (tempDistance < distance)
                    {
                        distance    = tempDistance;
                        closestNode = possibleNodes[i];
                    }
                }
                //END MONSTER CLOSEST NODE

                //PLAYER CLOSEST NODE
                for (int i = 0; i < World.Instance.AINodeList.Count; i++)
                {
                    Vector2 start = player.transform.position;
                    Vector2 end   = World.Instance.AINodeList[i].transform.position;

                    start = Vector2.MoveTowards(start, end, 1f);

                    RaycastHit2D hit = Physics2D.Linecast(start, end, layerMask);

                    if (hit.collider != null)
                    {
                        //This is not a possible node.
                        continue;
                    }
                    else
                    {
                        //This is a possible node.
                        possiblePlayerNodes.Add(World.Instance.AINodeList[i].attachedAINode);
                    }
                }

                for (int i = 0; i < possiblePlayerNodes.Count; i++)
                {
                    float tempDistance = Vector2.Distance(player.transform.position, possiblePlayerNodes[i].Position);
                    if (tempDistance < distance2)
                    {
                        distance2    = tempDistance;
                        closestNode2 = possiblePlayerNodes[i];
                    }
                }

                Debug.DrawLine(player.transform.position, closestNode2.Position, Color.green, 0.1f);
                for (int i = 0; i < possiblePlayerNodes.Count; i++)
                {
                    Debug.DrawLine(player.transform.position, possiblePlayerNodes[i].Position, Color.red, 0.1f);
                }
                //END PLAYER CLOSEST NODE

                //Calculate path.
                movePath = AStarHelper.Calculate(closestNode, closestNode2);

                //If possible node is along path, start there instead.
                int pathStart = 0;

                for (int i = 0; i < possibleNodes.Count; i++)
                {
                    for (int j = 0; j < movePath.Count; j++)
                    {
                        if (possibleNodes[i] == movePath[j] && j > pathStart)
                        {
                            pathStart = j;
                        }
                    }
                }
                currentStep = pathStart;
                AIPlayerPathCalculationTime = 0;
            }
        }
    }
示例#20
0
        // 返回被删除的边的引用

        /*private Edge RemoveEdgeNode(int vertexIndex, int adjacentIndex)
         * {
         *  EdgeNode p = this.vertexList[vertexIndex].FirstEdge, q = null;
         *  while (p != null && p.AdjacentVertex != adjacentIndex)
         *  {
         *      q = p;
         *      p = p.Next;
         *  }
         *
         *  if (p != null) // 找到
         *  {
         *      if (q == null)  // 首条边
         *      {
         *          this.vertexList[vertexIndex].FirstEdge = p.Next;
         *      }
         *      else
         *      {
         *          q.Next = p.Next;
         *      }
         *
         *      return p.EdgeLink;
         *  }
         *
         *  return null;
         * }*/

        /// <summary>
        /// 采用A*算法寻最短路
        /// A*算法 (F=G+H)
        ///   1,把起始格添加到开启列表。
        ///   2,重复如下的工作:
        ///      a) 寻找开启列表中F值最低的格子。我们称它为当前格。
        ///      b) 把它切换到关闭列表。
        ///      c) 对相邻的格中的每一个
        ///          * 如果它不可通过或者已经在关闭列表中,略过它。反之如下。
        ///          * 如果它不在开启列表中,把它添加进去。把当前格作为这一格的父节点。记录这一格的F,G,和H值。
        ///          * 如果它已经在开启列表中,用G值为参考检查新的路径是否更好。更低的G值意味着更好的路径。
        ///          *     如果是这样,就把这一格的父节点改成当前格,并且重新计算这一格的G和F值。
        ///          *     如果要保持的开启列表按F值排序,改变之后可能需要重新对开启列表排序。
        ///      d) 停止,当
        ///          * 把目标格添加进了关闭列表,这时候路径被找到,或者
        ///          * 没有找到目标格,开启列表已经空了。这时候,路径不存在。
        ///   3.保存路径。从目标格开始,沿着每一格的父节点移动直到回到起始格。这就是找到的路径。
        /// </summary>
        /// <param name="vnFrom">起点</param>
        /// <param name="vnTo">终点</param>
        /// <param name="listNavigateVertexNode">顶点表示的路径,每个元素记录的是边对应结点的入边, "并未"设置出边的序号</param>
        /// <returns>路径的总权值, 负数表示没找到</returns>
        public float FindShortestPaths(AStarHelper ash, VertexNode vnFrom, VertexNode vnTo, List <NavigateVertexNode> listNavigateVertexNode)
        {
            listNavigateVertexNode.Clear();

            AStarHelper.SeekingNode me = new AStarHelper.SeekingNode(-1, 0.0f, 0.0f, null, vnFrom, null);
            ash.InsertIntoOpening(me);

            while (ash.OpeningLength > 0)
            {
                me = ash.PopLowestWeightInOpening();
                VertexNode vn = me.Data as VertexNode;
                if (vn.Cell == vnTo.Cell)
                {
                    break; // 找到
                }
                // 遍历邻接点
                EdgeNode p             = vn.FirstEdge;
                int      whichAdjacent = 0;
                while (p != null)
                {
                    if (ash.IsInClosed(p.EdgeLink.ID))
                    {
                        p = p.Next;
                        whichAdjacent++;
                        continue;
                    }

                    NavigateVertexNode nvn = new NavigateVertexNode(this.vertexList[p.AdjacentVertex] as VertexNode);
                    nvn.SelectedEdgeIndex = whichAdjacent;
                    nvn.SelectedEdge      = p;
                    float h = ash.hFunc(this.vertexList[p.AdjacentVertex].Cell, vnTo.Cell);
                    //string info = string.Format("edge={0:d}<->{1:d}, g={2:f}, h={3:f}",
                    //    vn.Cell, this.vertexList[p.AdjacentVertex].Cell, me.G + p.EdgeLink.Weight, h);
                    //XxdwDebugger.Log(info);
                    AStarHelper.SeekingNode next = new AStarHelper.SeekingNode(
                        p.EdgeLink.ID,
                        me.G + p.EdgeLink.Weight,
                        h,
                        me,
                        this.vertexList[p.AdjacentVertex],
                        nvn);
                    AStarHelper.SeekingNode pre = ash.FindInOpening(p.EdgeLink.ID);
                    if (pre == null)
                    {
                        ash.InsertIntoOpening(next);
                    }
                    else if (next.F < pre.F)
                    {
                        ash.RemoveFromOpening(pre);
                        ash.InsertIntoOpening(next);
                    }

                    p = p.Next;
                    whichAdjacent++;
                }
            } // while

            float weight = 0.0f;

            if ((me.Data as VertexNode).Cell == vnTo.Cell) // 找到
            {
                NavigateVertexNode nvn;

                AStarHelper.SeekingNode sn = me;
                while (sn != null && sn.ExtraData != null)
                {
                    nvn = sn.ExtraData as NavigateVertexNode;
                    listNavigateVertexNode.Insert(0, nvn);
                    weight += nvn.SelectedEdge.EdgeLink.Weight;
                    sn      = sn.Parent;
                }
                listNavigateVertexNode.Insert(0, new NavigateVertexNode(vnFrom)); //加入开始节点

                return(weight);
            }
            else
            {
                return(-1.0f);
            }
        }