Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

11

04.11.2011, 19:59

Ich weiß nur nicht genau wie ich vorgehen soll. Ich scheitere oftmals. Habe viele Varianten angewendet trotzdem beim Berechnen kommt manchmal nicht das raus was sein sollte. Ich habe schon viele Sachen (nach)programmiert. Das ist ja das perverseste von allen für mich.

Ich habe jetzt wieder neu angefangen. Ich versuche das ein letztes mal. Hoffentlich mit hilfe krieg ich das endlich hin.

Die Punkte sind auf der Karte gesetzt. Sagen wir mal ich habe sechs stück.
Ich soll mit Start punkt starten

Quellcode

1
2
3
4
5
6
7
8
9
10
11
  #wenn ich Rechtsclick mache
    if(changed(owner():keyAttack2()) & owner():keyAttack2()) {
        Start = Nodes[1, vector] # Array, den ersten Punkt der gesetzt wurde als Startposition definieren. (Nodes enthalten die Positionen der Waypoints)
        Dest = Nodes[Nodes:count(), vector] #Ich nehme den letzten Punkt als Ziel
        
        Open[1, vector] = Start #Startposition in den Openlist hinzufügen
        OpenIsPushed[Start:toString(),number] = 1 #Setze Startposition als besucht aber noch nicht closed. Das ist eine Assoziale Array (Array["Vektor als STRING", number], number steht für integer.
        OpenScores[1, number] = 1
        
        Action = 1 #Setze Action auf 1 um Suche zu starten.
    }


Ich habe hier also den Start- und Zielpunkt definiert und Startpunkt bereits in den Open eingetragen. OpenIsPushed heißt einfach, dass er auf dem Weg dahin ein Punkt gefunden hat und noch nicht in Closed ist.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
if(Action == 1) {

    if(Open:count()) {

        while(Open:count() & perf()) {
            #Den kleinsten F Wert rausnehmen als Index (für die Arrays)
            K = OpenScores:minIndex()
            CurrentNode = Open[K, vector]
            Durchlauf = 0

            #Wenn noch nicht geclosed
            if(!Closed[CurrentNode:toString(), number]){
           
                    while(perf()) {
                            #Hole ein Punkt aus der Nodesliste
                            Durchlauf++
                            NodeVec = Nodes[Durchlauf , vector]
                    

                            #Wenn der Punkt zuweit vom Punkt jetzt ist dann ist es unerreichbar und wird est mal übersprungen (Damit verbinde ich sozsagen die Knoten zusammen und zwar "live")
                            if(CurrentNode:distance(NodeVec) > 400) {
                                break
                            }

                            
                    }

            }
        }

    } else {
        Action = 2
    }


So ab nachdem es überprüft wurde ob ein Punkt in der nähe liegt weiß ich nicht weiter =/.



Die Sprache Expression 2 von wiremod.com. Die Sprache würde für ein Spiel Garry's Mod erstellt. In diesem Spiel kann man seine wünsche Programmieren und live die Resultaten an sehen. Es macht wirklich spaß. Nur manchmal hat es halt doofe Nachteile.
Nichts ist unmöglich.

12

04.11.2011, 20:50

So ab nachdem es überprüft wurde ob ein Punkt in der nähe liegt weiß ich nicht weiter =/.


Also nach dem du den Start knoten untersuchst hast must du mindestens ein direkten Nachbarknoten gefunden haben. Oder aber auch mehr. Für jeden Gefunden Knoten berechnest du H, G und F und weist die Werte dem jeweiligen Knoten zu. Jeder dieser Knoten kommt jetzt in die Openlist. Der Aktuel Untersuchte Knoten (im jetztigen Fall der Startknoten) kommt in die ClosedList.
Jetzt Suchst du dir aus der Openlist den Knoten aus mit dem geringsten F wert aus. Von diesem Knoten aus gehend untersuchst du wieder seine direkten Nachbarn. Die jetzt neu gefundenen Knoten bekommen wieder die jeweiligen Werte für H, G und F zu gewiesen und kommen in die Openlist. Der aktuell untersuchte Knoten kommt wieder in die Closedlist. Und dann wieder aus der Openlist den Knoten mit dem geringsten F wert nehmen und so weiter.

Knoten die nicht betreten werden können fallen Raus.
Knoten die ein zweites mal untersucht werden und bei denen sich dadurch der F wert verbessert werden Überschrieben.
Und auch noch ganz wichtig ist das in jedem Knoten steht von welchem Knoten aus er Untersucht wurde.

Wenn dann der Zielknoten erreicht ist brauchst du nur noch schaun von wo wurde der Zielknoten untersucht dann schaust dir an von wo wurde der untersucht und so arbeitest du dich wieder zum Anfang vor und dieser weg sollte dann der Kostengünstigste / kürzeste Weg sein.

Ich hoffe du kannst was mit anfangen.
Wer aufhört besser werden zu wollen hört auf gut zu sein!

aktuelles Projekt:Rickety Racquet

13

05.11.2011, 18:38

Woah danke dir. Ich bin sehr weit gekommen. Dein Satz mit "Und auch noch ganz wichtig ist das in jedem Knoten steht von welchem Knoten aus er Untersucht wurde. " War der Stichwort.

Ich habe jetzt eine Schleife drinne, der Steckt alle Knoten z. B. Knoten 1 zu Konten 3 unter 300 Units entfernt sind werden sie als benachbart eingetragen.
Danach habe ich das befolgt was du geschrieben hast. Ziel war: Von Knoten 1 zum Knoten 25 zu gelangen. Knoten 25 liegt zwischen Knoten 5 und 6. (Den punkt musste ich leider nachträglich hinzufügen weil 5 und 6 einfach zuweit voneinander waren und daher nicht benachbart waren)


Meine Konsole meldet das hier.

Quellcode

1
2
3
4
5
6
1 vorgaenger von 1 -- F von 1: 1
1 vorgaenger von 2 -- F von 2: 4301.363135724
2 vorgaenger von 3 -- F von 3: 3376.3886656224
3 vorgaenger von 4 -- F von 4: 2372.7225964861
4 vorgaenger von 5 -- F von 5: 1867.8513244202
5 vorgaenger von 25 -- F von 25: 1059.9489088838


Also heißt ich bin von 1 nach 25 korrekt gelaufen. Oh man wie ich mich freue.. könnte rumspringen ;( . Habe echt vllt seit Februar öfters versucht.

Jetzt hab ich aber einige andere Fragen dazu. Wie kann man ein Charakter ein verhalten zuweisen, wenn etwas zwischen Wegpunkt A und B etwas blockiert.. z. B. ein Auto steht da. In andern Worten, er soll um das Auto laufen. Da ja kein Wegpunkt ist, wo er z. B. berechnen könnte ob links oder rechts um das Auto der kürzere Weg ist.
Nichts ist unmöglich.

14

05.11.2011, 19:24

Puh da ich A-Stern bisher nur auf TileMap angewendet habe habe ich mit solch einer Map wie du sie hast keine Erfahrungswerte.
Der Pfad der blockiert ist zwischen 2 Knoten muß in irgend einer Form ungültig gemacht werden. Dann müste der Algorithmus normal nen anderen Weg wählen. Das wäre das was mir so spontan einfällt.
Wer aufhört besser werden zu wollen hört auf gut zu sein!

aktuelles Projekt:Rickety Racquet

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

15

06.11.2011, 15:57

Na so einfach geht das normalerweise nicht. Du könntest einen dynamischen Graphen benutzen. Heisst Knoten oder Wegpunkte wie du sie nennst werden zwischendurch eingefügt oder aber entfernt. Dann könntest du für das Auto einen Knoten entfernen und der Weg ist nicht mehr vorhanden. Wenn das Auto jetzt aber rumfahren kann dann ist das natürlich schlecht als Ansatz. Jedes mal den Graphen anzupassen und Nachbarn zu updaten kann je nach umsetzung des Graphen etwas länger dauern. Dazu kommen Probleme wie, wenn ein Knoten eines aktuellen Weges gelöscht wird, muss der Weg neu berechnet werden. Bewegliche Objekte zu umlaufen ist aber vermutlich ein allgemeines Problem. Du musst ja auch andere Spieler oder Gegner oder was auch immer umlaufen können, solange diese Kollidieren können. Was du jetzt machen könntest, ist deine Welt so einzuteilen, dass du begehbare Flächen auch vom Code schnell finden kannst. Guck dir zum Beispiel navigation meshs an. Das heisst, deine Knoten sind nicht mehr einfach einzelne Punkte, sondern ganze Flächen. Wenn jetzt ein Auto im Weg steht, dann kannst du relativ einfach einen Weg vorbei finden. Allgemein einen Weg um ein Objekt zu finden sollte ja nicht so schwer sein. Du kennst ja denke ich die Position des Objektes und die Maße. Damit lässt sich dann auch der Weg relativ fix berechnen. Bei Graphen und A* ist es aber allgemein ganz gut, wenn man die Graphen klein halten kann. Dann geht die Berechnung umso schneller. Von daher muss man nicht unbedingt jeden möglichen Punkt auf der Karte als Knoten haben, sondern Teilt die Welt einfach in Zonen und berechnet dann nur die Wege von Zone zu Zone. Aber da gibt es wie fast immer unendlich viele Möglichkeiten;) Wenn du dich mehr für das Thema interessierst, würde ich dir ein Buch dazu vorschlagen. Dass muss nicht unbedingt ein (langweiliges) Buch über Graphentheorie sein. Es gibt ja mittlerweile genug Bücher über KI und solche Probleme. Sowas lohnt sich dann auf dauer schon.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

Werbeanzeige