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

1

04.04.2012, 12:43

[ SFML ] Pathfinding - Pfad gefunden, aber wie folgen?

Aloha Leute,

Nachdem ich mich mit A* Pathfinding beschäftigt habe, hab ich mir ein Pathfinding-script geschrieben,
nicht das beste und auch noch arg verbesserungswürdig aber soweit wird der Pfad eigentlich gefunden.

Nur krieg ich es einfach nicht hin das dem Pfad "smooth" gefolgt wird.

Es soll in 4 richtungen gehen, also oben,unten,links,rechts.

Ich dachte mir das ganze in etwa so:

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
34
35
36
37
38
39
void CGame::followPath()
{
    for(i = ClosedList.begin(); i != ClosedList.end(); i++ )
    {
        ElapsedTime = g_pTimer->Get_Elapsed();

if(i->x == static_cast<int>(Enemy.pSprite->GetPosition().x/32) +1)
{
while((i->x - Enemy.pSprite->GetPosition().x/32) >= 0)
{
    Enemy.pSprite->Move(2*ElapsedTime,0);

}
}
else if(i->x == static_cast<int>(Enemy.pSprite->GetPosition().x/32) -1)
{
    while((Enemy.pSprite->GetPosition().x/32 - i->x) >= 0)
{
    Enemy.pSprite->Move(-2*ElapsedTime,0);
   }
}
else if(i->y == static_cast<int>(Enemy.pSprite->GetPosition().y/32) +1)
{
        while((i->y - Enemy.pSprite->GetPosition().y/32) >= 0)
{
    Enemy.pSprite->Move(0,2*ElapsedTime);
}
}
else if(i->y == static_cast<int>(Enemy.pSprite->GetPosition().y/32) -1)
{
        while(( Enemy.pSprite->GetPosition().y/32 - i->y) >= 0)
{
    Enemy.pSprite->Move(0,-2*ElapsedTime);
  }
}
   
    }

}

So klappt das jedoch nicht, es freezed und nach ein paar Sekunden ist es dann aufeinmal an der richtigen stelle.

Hoffe mir kann dabei jemand helfen den ich komm einfach nicht drauf.


MfG Dastan

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Dastan« (04.04.2012, 20:25)


rewb0rn

Supermoderator

Beiträge: 2 773

Wohnort: Berlin

Beruf: Indie Game Dev

  • Private Nachricht senden

2

04.04.2012, 13:25

Ja logisch, du frühstückst das Ganze in einer Schleife ab, d.h. der Rechner freezt solange die Schleife läuft und danach steht dein Spieler an der richtigen Position. Korrekt wäre, nach jedem Zeichenvorgang nur einen oder begrenzt viele Schritte zu machen.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »rewb0rn« (04.04.2012, 13:58)


Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

3

04.04.2012, 19:50

Man kann so einen gefundenen Pfad auch noch selbst weich rechnen. In deinen Ansatz wäre das jetzt etwas schwierig, da du die Bewegung auf die 4 Richtungen beschränkst. Wenn das nicht unbedingt so sein muss kannst du folgenden Ansatz zusätzlich benutzen um den Pfad selbst weicher zu bekommen:
Pfad:
A->B->C
Wenn zwischen A und C kein Hindernis liegt dann mache daraus
A->C
Bei einem größeren Pfad würdest du vorne Anfangen und die ersten 3 Knoten prüfen. Wenn du Knoten B aus der Liste nehmen konntest, dann wieder vorn Anfangen. Das machst du so lange, bis du am Ende angekommen bist. Dadurch bekommst du einen direkteren Weg, welcher nicht mehr von den Kacheln bzw Knoten deines Graphen abhängig ist. Funktioniert natürlich nur je nach Anforderung. Meistens ist aber eher sowas gewollt. Das wäre natürlich dann nur eine Optimierung, nachdem du reb0rns Hilfestellung umgesetzt hast;)
„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.“

4

04.04.2012, 20:25

Erstmal danke für die Antworten! :)

Zitat

Ja logisch, du frühstückst das Ganze in einer Schleife ab, d.h. der Rechner freezt solange die Schleife läuft und danach steht dein Spieler an der richtigen Position. Korrekt wäre, nach jedem Zeichenvorgang nur einen oder begrenzt viele Schritte zu machen.


Ich glaub ich versteh es nich ganz, meinst du damit ich soll zuerst die Richtungen prüfen und dannach quasi "seperat" die eigentliche Bewegung ?

also so ungefähr:


C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
if ... 
if...
if...
if..
//
//checken die Richtung und geben einen Wert zurück


While...  //holt sich den Wert und führt die entsprechende Bewegung aus

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

5

04.04.2012, 21:25

Nimm die Whiles aus deinen Schleifen.
Vom Prinzip läuft es so:
Nimm ersten Punkt von der Liste, bewege dann deine Figur um den Wert ihrer Geschwindigkeit in die Richtung des Punktes. Fertig.
Im nächsten Frame das selbe. Ist die Figur irgendwann bei dem Punkt angekommen, kannst du ihn aus der Liste nehmen und es geht mit dem 2ten Punkt der Liste weiter.
Du gehst bei dir in einem Frame die ganze Liste durch und bewegst immer direkt zu dem Punkt. Dadurch wird der ganze Pfad in einem Frame abgelaufen.
„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.“

6

04.04.2012, 22:54

Zitat

Nimm die Whiles aus deinen Schleifen.
Vom Prinzip läuft es so:
Nimm ersten Punkt von der Liste, bewege dann deine Figur um den Wert ihrer Geschwindigkeit in die Richtung des Punktes. Fertig.
Im nächsten Frame das selbe. Ist die Figur irgendwann bei dem Punkt angekommen, kannst du ihn aus der Liste nehmen und es geht mit dem 2ten Punkt der Liste weiter.
Du gehst bei dir in einem Frame die ganze Liste durch und bewegst immer direkt zu dem Punkt. Dadurch wird der ganze Pfad in einem Frame abgelaufen.


Ok danke, soweit versteh ich dass jetzt.
Aber die While-schleife brauch ich doch trotzdem noch um zu checken das er anhält, sobalt er den "Knotenpunkt" erreicht hat, sonst läuft der mir ja ewig in die eine Richtung.
(ich kann natürlich auch eine for-schleife benützen aber das kommt aufs gleiche raus)

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

7

05.04.2012, 00:00

Nein, keine lokale Schleife!
Du musst das in den Ablauf deines Spiels integrieren, das ist ja im Prinzip eine große Schleife.

Architekt

Community-Fossil

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

8

05.04.2012, 00:12

Bei jeder Iteration deiner Game Loop setzt du deinen Spieler mehr und mehr zum aktuellen Knotenpunkt, den du ganz oben in einer Liste speicherst.
(Die Liste ist dann wie folgt aufgebaut: [A, B, C], wobei jeder Buchstabe für einen Knotenpunkt steht.)
Das lässt sich ganz einfach berechnen, denn du hast die momentane Position des Spielers, die Geschwindigkeit (oder Anzahl an Pixel um die der Spieler sich bewegt) und den nächsten Punkt in deiner Liste.
Stimmen die Koordinaten mit denen des Punktes überein, wird dieser aus der Liste gelöscht und an seiner statt tritt der nächstfolgende Knotenpunkt (Stichwort Stack, vllt. ein Begriff?).
Dies geschieht immer weiter, bis die Liste leer ist und dein Spieler somit die Zielposition erreicht hat.
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

9

05.04.2012, 17:36

Tut mir leid , aber ich glaub ich hab grade nen kompletten Blackout.
Ich schaff es nicht das ganze in verschiedenen Frames zu regeln.
Da ich mir den nächsten Knotenpunkt dadurch hole, dass ganze in der for-Schleife abspielen zu lassen und jedesmal den Iterator zu erhöhen.
Dadurch habe ich immer nur einen "Zyklus" der Schleife Zeit bis es zum nächsten Knotenpunkt übergeht.


Zitat

Bei jeder Iteration deiner Game Loop setzt du deinen Spieler mehr und mehr zum aktuellen Knotenpunkt, den du ganz oben in einer Liste speicherst.
(Die Liste ist dann wie folgt aufgebaut: [A, B, C], wobei jeder Buchstabe für einen Knotenpunkt steht.)
Das lässt sich ganz einfach berechnen, denn du hast die momentane Position des Spielers, die Geschwindigkeit (oder Anzahl an Pixel um die der Spieler sich bewegt) und den nächsten Punkt in deiner Liste.
Stimmen die Koordinaten mit denen des Punktes überein, wird dieser aus der Liste gelöscht und an seiner statt tritt der nächstfolgende Knotenpunkt (Stichwort Stack, vllt. ein Begriff?).
Dies geschieht immer weiter, bis die Liste leer ist und dein Spieler somit die Zielposition erreicht hat.


Kann ich dafür den nicht meine ClosedList benützen denn, sie enthält ja den kompletten Pfad schon der gegangen werden muss und sollte bei erreichen des Ziels sowieso komplett leer sein.

PS: Danke für die schnellen und ausführlichen Antworten.

MfG Dastan

Architekt

Community-Fossil

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

10

05.04.2012, 17:42

Ja, die ClosedList benutzt du. Du holst dir diese und arbeitest sie dann solange ab bis sie leer ist. Dazu gehst du in jedem Frame ein Stückchen weiter auf den aktuellsten, sprich obersten, Knotenpunkt zu. Ist dieser erreicht wird er aus der Liste gekickt und du machst das gleiche für den nächsten Knoten.
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

Werbeanzeige