예제 #1
0
        public static void InitPaths()
        {
            savedPaths = new Dictionary<int, Dictionary<int, PathNode>>();

            allNodes = new Dictionary<int, PathNode>();

            foreach (WayPoint w in Main.MainObject.GameManager.GameState.Karte.WayPoints.Values)
            {
                PathNode n = new PathNode(float.MaxValue, w);
                allNodes.Add(w.ID, n);
            }
        }
예제 #2
0
파일: PathNode.cs 프로젝트: StWol/Last-Man
        // PathNode kopieren
        public PathNode Clone()
        {
            PathNode n = new PathNode(Distance, ID);

            if (NextNode != null)
                n.NextNode = NextNode.Clone();

            if (PreviousNode != null)
                n.PreviousNode = PreviousNode.Clone();

            n.WayPoint = WayPoint;

            n.Distance = Distance;

            return n;
        }
예제 #3
0
        private static void buildPath(ref PathNode start, int targetId)
        {
            PathNode _build = allNodesTemp[targetId];

            PathNode current = _build;

            while (current.ID != start.ID)
            {
                PathNode prev = allNodesTemp[current.PreviousNode.ID];

                prev.NextNode = current;
                int c = current.PreviousNode.ID;
                current = prev;
            }

            start = allNodesTemp[start.ID]; ;
        }
예제 #4
0
        private void searchNextVisibleNode(Enemy e)
        {
            // wenn es kein pfad gibt abbrechen
            if (_currentPath == null)
                return;

            PathNode temp = _currentPath.NextNode;

            // nodes durchgenen
            while (temp != null)
            {
                if (GameManager.PointSeePoint(e.LocationBehavior.Position, temp.WayPoint.Location.Position, e.LocationBehavior.Size))
                {
                    _currentPath = temp;
                    temp = _currentPath.NextNode;
                }
                else
                {
                    // aufhören zu suchen
                    break;
                }
            }
        }
예제 #5
0
        // Tue die Action
        public override void CalculateAction(Enemy e)
        {
            // ist player in sichweite
            if (e.DistanceLessThan(_player, e.SightiningDistance))
            {
                // Kann er den playe sehen oder ist dieser von einem objekt bedeckt / 20x20 ist ca. ein schuss
                if (GameManager.PointSeePoint(e.LocationBehavior.Position, _player.LocationBehavior.Position, new Vector2(20, 20)))
                {
                    // kann spieler sehen
                    _sawPlayer = true;
                    _sawPlayerAt = _player.LocationBehavior.Position;

                    // wenn er in angriffreichweite ist angreifen
                    if (e.DistanceLessThan(_player, e.SightiningDistance))
                    {
                        _lookAtPlayer = true;
                        _attack = true;
                        _lookAtNextNode = false;
                        _walk = false;

                        return;
                    }
                    else
                    {
                        // Kann er zum spieler laufen ohne an eine wand zu stoßen?
                        if (GameManager.PointSeePoint(e.LocationBehavior.Position, _player.LocationBehavior.Position, e.LocationBehavior.Size))
                        {
                            _lookAtPlayer = true;
                            _attack = false;
                            _lookAtNextNode = false;
                            _walk = true;

                            return;
                        }
                    }
                }
            }
            else
            {
                _lookAtPlayer = false;
                _attack = false;
            }

            // ## Sieht er den player und kann schießen wird abgebrochen

            // wenn er den spiele sehen konnte aber jetzt nicht mehr
            if (_sawPlayer)
            {
                // sieht player nicht mehr
                _sawPlayer = false;

                // Suche den nähsten WP und schaue ob er auf der route lag
                WayPoint _newNearest = Karte.SearchNearest(_sawPlayerAt);

                if (_newNearest != null)
                {

                    // nearest in path
                    PathNode nearestInPath = null;

                    // wenn der nähste wegpunkt im pfad ist, diesen als neues ziel setzten
                    if (_currentPath.IsWaypointInPath(_newNearest.ID, out nearestInPath))
                    {
                        _currentPath = nearestInPath;
                    }
                    else
                    {
                        // ansonsten den aktuellen pfad löschen und neuen berechnen
                        _nearest = _newNearest;
                        _currentPath = null;
                    }

                }
            }

            //

            // WP des Players
            WayPoint playerWayPoint = Main.MainObject.GameManager.GameState.Player.NearestWayPoint;

            // falls playerwegpunkt neu ist pfad neu berechnen und auch neuen nearest suchen
            if (playerWayPoint != null && _lastPlayerWaypoint != playerWayPoint)
            {
                _nearest = null;
                _currentPath = null;
            }

            // Falls es kein Wegpunkt gibt, der am nähesten bei mir ist
            if (_nearest == null)
                _nearest = Karte.SearchNearest(e.LocationBehavior.Position);

            // Sollte es kein Wegpunkt in meiner Nähe geben abbrechen
            if (_nearest == null)
                return;

            // wenn es kein pfad gigt, pfad zu player berechnen
            if (_currentPath == null && playerWayPoint != null)
            {
                _lastPlayerWaypoint = playerWayPoint;
                _currentPath = PathFinder.FindePath(_nearest, playerWayPoint);
            }

            // wenn _currentPath == null stehen bleiben )
            if (_currentPath != null)
            {
                // Steht enemy über wp => next wp
                if (Vector2.Distance(_currentPath.WayPoint.Location.Position, e.LocationBehavior.Position) < 10)
                {
                    // wenn es einen nächste wp gibt gehe zu dem ansonsten laufen=false /stehen bleiben
                    if (_currentPath.NextNode == null)
                    {
                        _lookAtPlayer = false;
                        _attack = false;
                        _lookAtNextNode = false;
                        _walk = false;
                    }
                    else
                    {
                        _currentPath = _currentPath.NextNode;

                        _lookAtPlayer = false;
                        _attack = false;
                        _lookAtNextNode = true;
                        _walk = true;
                    }
                }
                else
                {
                    // checken ob enemy festhängt - hängt fest wenn er halb so schnell wie normal läuft
                    if (_walkedDistance < e.Speed / 2)
                    {
                        searchNextVisibleNode(e);
                    }

                    _lookAtPlayer = false;
                    _attack = false;
                    _lookAtNextNode = true;
                    _walk = true;
                }
            }
            else
            {
                _lookAtPlayer = false;
                _attack = false;
                _lookAtNextNode = false;
                _walk = false;
            }
        }
예제 #6
0
        private static PathNode _findePath(WayPoint start, WayPoint target)
        {
            // Listen init
            openList = new List<PathNode>();
            closedList = new List<PathNode>();

            allNodesTemp = CloneNodeDic();

            // Start einfügen
            PathNode startNode = new PathNode(0, start);
            openList.Add(startNode);

            // solange openlist nicht leer ist
            while (openList.Count > 0)
            {
                //next Node aus openlist holen
                PathNode next = openList[0];
                openList.RemoveAt(0);

                // Nachbarn einfügen
                expandNode(next);

                // Node in closeliste einfügn
                closedList.Add(next);

                // prüfen ob ich schon fertig bin
                if (next.ID == target.ID)
                    break;
            }

            // pfad bauen
            buildPath(ref startNode, target.ID);

            return startNode;
        }
예제 #7
0
        private static void expandNode(PathNode n)
        {
            foreach (WayPoint w in n.WayPoint.connectedPoints)
            {
                // Pathnode mit distanz erzeugen
                PathNode node = allNodesTemp[w.ID];

                // node adden falls er noch nicht in openlist und closelist ist
                if (closedList.Contains(node))
                    continue;

                // distanz zu nachbar
                float dist = n.Distance + n.WayPoint.distances[w.ID];

                // checken ob er schon in openlist ist
                if (openList.Contains(node))
                {
                    // Distanz und vorgänger udpaten falls distanz kleiner ist
                    if (dist < node.Distance)
                    {
                        node.Distance = dist;
                        node.PreviousNode = n;
                    }
                }
                else
                {
                    // vorgänger setzten
                    node.PreviousNode = n;
                    node.Distance = dist;

                    // pathnode in open list
                    openList.Add(node);
                }
            }

            // List sortieren
            openList.Sort(CompareNodes);
        }
예제 #8
0
        /*private static PathNode _findePath(WayPoint start, WayPoint target)
        {
            //Debug.WriteLine("pfad berechnen von " + start.ID + " zu " + target.ID);

            if (start == target)
            {
                if (!savedPaths.ContainsKey(start.ID))
                    savedPaths.Add(start.ID, new Dictionary<int, PathNode>());

                // Pfad clonen und speichern
                savedPaths[start.ID].Add(target.ID, new PathNode(0, start.ID));
                return new PathNode(0, start.ID);
            }

            // Listen initialisieren
            openList = new List<PathNode>();
            closedList = new List<PathNode>();

            // Startpunkt in die openList machen
            PathNode startNode = new PathNode(0, start.ID);
            openList.Add(startNode);

            // Gefundener Pfad
            PathNode found = null;

            // Solange openlist nicht leer ist
            while (openList.Count > 0)
            {
                // Erster Knoten aus der openlist holen und entfernen (kürzester weg zum ziel)
                PathNode current = openList[0];
                openList.Remove(current);

                // Falls current == ziel beenden
                if (current.ID == target.ID)
                {
                    found = current;
                    break;
                }

                // Kinder in open list einfügen
                expandNode(current);

                // aktuelle knoten in closed list einfügen
                closedList.Add(current);
            }

            // Pfad umdrehen
            if (found != null)
            {
                PathNode reverse = null;
                PathNode reverseCurrent = null;
                while (found.PreviousNode != null)
                {
                    // Letzte Knoten holen
                    PathNode last = popLastNode(found);

                    // Letzte knoten an neue liste hängen
                    if (reverse == null)
                    {
                        reverse = last;
                        reverseCurrent = reverse;
                    }
                    else
                    {
                        reverseCurrent.NextNode = last;
                        reverseCurrent = reverseCurrent.NextNode;
                    }
                }

                // Letztes Element noch anhängen
                reverseCurrent.NextNode = found;

                // Pfad speichern um ihn nicht erneut berechnen zu müssen
                if (!savedPaths.ContainsKey(start.ID))
                    savedPaths.Add(start.ID, new Dictionary<int, PathNode>());

                // Pfad clonen und speichern
                savedPaths[start.ID].Add(target.ID, reverse.Clone());

                // Pfad zurückgeben
                return reverse;
            }

            // Pfad zurückgeben
            return found;
        }

        // ***************************************************************
        // holt den letzten node aus dem pfad
        private static PathNode popLastNode(PathNode n)
        {
            while (n.PreviousNode.PreviousNode != null)
            {
                n = n.PreviousNode;
            }

            PathNode prev = n.PreviousNode;
            n.PreviousNode = null;
            return prev;
        }

        // ***************************************************************
        // openlist etc updaten
        private static void expandNode(PathNode current)
        {
            WayPoint currentWayPoint = Main.MainObject.GameManager.GameState.Karte.WayPoints[current.ID];

            // Alle verlinkten knoten durchgehen
            foreach (WayPoint w in currentWayPoint.connectedPoints)
            {
                // falls der knoten in der closed list ist nicht unternehmen
                if (isIdInClosedList(w.ID))
                    continue;

                // weg zwischen current und neuen knoten
                float dX = currentWayPoint.Location.Position.X - w.Location.Position.X;
                float dY = currentWayPoint.Location.Position.Y - w.Location.Position.Y;
                float dist = (float)Math.Sqrt(Math.Pow(dX, 2) + Math.Pow(dY, 2));

                // neuer knoten erstellen
                PathNode newNode = new PathNode(current.Distance + dist, w.ID);
                newNode.PreviousNode = current;

                // In openlist schauen ob es den punkt schon gibt und prüfen ob er schneller zu erreichen ist
                PathNode nexter = GetOfOpenList(w.ID);
                if (nexter != null)
                {
                    // wenn der alte weg kürzer ist weiter machen
                    if (nexter.Distance < newNode.Distance)
                        continue;
                    else
                    {
                        // wenn der neue weg kürzer ist, node aktuallisiern
                        nexter.Distance = newNode.Distance;
                        nexter.PreviousNode = current;
                    }
                }
                else
                {
                    // knoten in open list adden
                    openList.Add(newNode);
                }
            }

            // list sortieren, damit oben der mit der kürzesten heuristik steht
            openList.Sort(CompareNodes);
        }

        private static bool isIdInClosedList(int id)
        {
            foreach (PathNode n in closedList)
                if (n.ID == id)
                    return true;
            return false;
        }

        private static PathNode GetOfOpenList(int id)
        {
            foreach (PathNode n in closedList)
                if (n.ID == id)
                    return n;
            return null;
        }*/
        // **************************************************************************
        // Vergleicht zwei PathNodes
        private static int CompareNodes(PathNode x, PathNode y)
        {
            if (x == null)
            {
                if (y == null)
                {
                    // equal
                    return 0;
                }
                else
                {
                    // y ist nicht null somit ist y "größer"
                    return -1;
                }
            }
            else
            {
                // x nicht null

                if (y == null)
                // und y ist null ist x "größer"
                {
                    return 1;
                }
                else
                {
                    // ansonsten vergleichen

                    if (x.Distance > y.Distance)
                    {
                        return 1;
                    }
                    else if (x.Distance < y.Distance)
                    {
                        return -1;
                    }
                    else
                    {
                        return 0;
                    }
                }
            }
        }
예제 #9
0
파일: PathNode.cs 프로젝트: StWol/Last-Man
        // **************************************************************************
        // Prüft ob sich in einem pfad ein bestimmter wegpunkt befindet
        public bool IsWaypointInPath(int waypointId, out PathNode outNode)
        {
            PathNode current = this;
            while (current != null)
            {
                if (current.ID == waypointId)
                {
                    outNode = current;
                    return true;
                }

                current = current.NextNode;
            }

            outNode = null;
            return false;
        }