Пример #1
0
    public Map2dAStar(Func <bool> canJump, MazeLevel maze, VisionMapping vision, Transform transform, GameObject prefab_debug_astar)
    {
        this.maze = maze;
        this.prefab_debug_astar = prefab_debug_astar;
        SetAstarSourceData(vision, () => maze.Map, canJump, ResetCalcSpace,
                           (Coord c, out Coord n) => {
            AStarData a = calcSpace.At(c);
            Coord f     = a.from;                 //e = a._edge;
            n           = f != Coord.NegativeOne ? f : c;
            return(a._edge);
        },
                           (c, f, e) => {
            AStarData a = calcSpace.At(c);
            a._edge     = e; a.from = f;
        },
                           c => calcSpace.At(c).f, (c, f) => { calcSpace.At(c).f = f; },
                           c => calcSpace.At(c).g, (c, f) => { calcSpace.At(c).g = f; });
        ResetCalcSpace(Map.GetSize());
        Vector3 p    = transform.position;
        Coord   here = maze.GetCoord(p);

        Start(here, here);
        if (prefab_debug_astar != null)
        {
            maze.seen.onChange += RefreshVision;
            vision.onChange    += RefreshVision;
        }
    }
Пример #2
0
    void Update()
    {
        if (visionParticle != null)
        {
            if (characterMover.JumpButtonTimed > 0 && !visionParticle.isPlaying)
            {
                visionParticle.Play();
            }
            else if (characterMover.JumpButtonTimed == 0 && visionParticle.isPlaying)
            {
                visionParticle.Stop();
            }
        }
        Coord mapSize = maze.Map.GetSize();

        if (mapAstar == null)
        {
            mapAstar = new Map2dAStar(() => canJump, maze, discovery.vision, _t, prefab_debug_astar);
        }
        mapAstar.UpdateMapSize();
        Vector3 p    = _t.position;
        Coord   here = maze.GetCoord(p);

        if (follower.waypoints.Count > 0)
        {
            Coord there = maze.GetCoord(follower.waypoints[0].positon);
            if (here == there)
            {
                follower.NotifyWayPointReached();
            }
        }
        List <Coord> moves = mapAstar.Moves(here, canJump);

        if (textOutput != null)
        {
            UiText.SetText(textOutput, here.ToString() + ":" + (p - maze.transform.position) + " " + moves.JoinToString(", "));
        }
        if (useVisionParticle && visionParticle)
        {
            timer -= Time.deltaTime;
            if (timer <= 0)
            {
                mapSize.ForEach(co => {
                    if (discovery.vision[co])
                    {
                        Vector3 po = maze.GetPosition(co);
                        po.y       = _t.position.y;
                        visionParticle.transform.position = po;
                        visionParticle.Emit(1);
                    }
                });
                timer = .5f;
            }
        }
        switch (aiBehavior)
        {
        case AiBehavior.RandomLocalEdges:
            if (!characterMover.IsAutoMoving())
            {
                Coord c = moves[Random.Next(moves.Count)];
                characterMover.SetAutoMovePosition(MoveablePosition(c, p));
            }
            break;

        case AiBehavior.RandomInVision:
            if (mapAstar.goal == here)
            {
                if (mapAstar.RandomVisibleNode(out Coord there, here))
                {
                    //Debug.Log("startover #");
                    //Debug.Log("goal " + there+ " "+astar.IsFinished());
                }
                else
                {
                    mapAstar.RandomNeighborNode(out there, here);
                }
                mapAstar.Start(here, there);
            }
            else
            {
                // iterate astar algorithm
                if (!mapAstar.IsFinished())
                {
                    mapAstar.Update();
                }
                else if (mapAstar.BestPath == null)
                {
                    //Debug.Log("f" + astar.IsFinished() + " " + astar.BestPath);
                    mapAstar.Start(here, here);
                    //Debug.Log("startover could not find path");
                }
                if (mapAstar.BestPath != null)
                {
                    if (mapAstar.BestPath != currentBestPath)
                    {
                        currentBestPath = mapAstar.BestPath;
                        List <Coord> nodes = new List <Coord>();
                        Coord        c     = mapAstar.start;
                        nodes.Add(c);
                        for (int i = currentBestPath.Count - 1; i >= 0; --i)
                        {
                            c = mapAstar.NextNode(c, currentBestPath[i]);
                            nodes.Add(c);
                        }
                        //Debug.Log(currentBestPath.JoinToString(", "));
                        indexOnBestPath = nodes.IndexOf(here);
                        if (indexOnBestPath < 0)
                        {
                            mapAstar.Start(here, mapAstar.goal);
                            //Debug.Log("startover new better path");
                        }
                        Vector3 pos = p;
                        follower.ClearWaypoints();
                        for (int i = 0; i < currentBestPath.Count; ++i)
                        {
                            pos = MoveablePosition(nodes[i + 1], pos);
                            //pos.y += follower.CharacterHeight;
                            //Show.Log(i + " " + nodes.Count + " " + currentBestPath.Count + " " + (currentBestPath.Count - i - 1));
                            MazeAStar.EdgeMoveType moveType = MazeAStar.GetEdgeMoveType(currentBestPath[currentBestPath.Count - i - 1]);
                            switch (moveType)
                            {
                            case MazeAStar.EdgeMoveType.Walk: follower.AddWaypoint(pos, false); break;

                            case MazeAStar.EdgeMoveType.Fall: follower.AddWaypoint(pos, false, 0, true); break;

                            case MazeAStar.EdgeMoveType.Jump: follower.AddWaypoint(pos, false, characterMover.jump.fullPressDuration); break;
                            }
                        }
                        follower.SetCurrentTarget(pos);
                        follower.UpdateLine();
                        follower.doPrediction = true;
                    }
                    else
                    {
                        if (!characterMover.IsAutoMoving() && follower.waypoints.Count == 0)
                        {
                            mapAstar.Start(here, here);
                            //Debug.Log("startover new level?");
                        }
                    }
                }
            }
            break;
        }
    }