Kürzesten Weg finden?
-
Hey,
Ich schreibe gerade mit einem Freund ein kleines Spiel (Tower Defense), es geht uns eigentlich nur um den Lerneffekt, wir kopieren keinen Code und denken und so weit es geht alles selbst aus
Nun habe ich allerdings eine Frage, die ich ohne weiteres nicht lösen kann.
Es gibt schon Monster, Pfade, eine Karte, Tower, halt soweit alles was man braucht
Die Tower können schon schießen und haben einen entsprechenden Cooldown, nur die Kugeln müssen ja auf direktem Wege zum Monster fliegen, und im Moment weiß ich nicht genau wie ich das realisieren soll.
Ich habe mir überlegt dass ich ja eigentlich nur die Differenz der beiden Punkte (Also Kugel aktuell und Monster aktuell) nehmen, und durch den kleineren Wert teilen muss (Sei es X oder Y) um die Angabe zu bekommen, wie viele Y ich beispielsweise bei einem X gehen muss, damit die Linie so gerade wie möglich wird.
Ich hab das auch eingebaut, aber irgendwie fliegt die Kugel erstmal gerade, bis die Differenz von X und Y gleich ist, erst dann tritt der Effekt in Kraft und die Linie wird tatsächlich schön gerade.
Ich habe auch daran gedacht die Werte mal 10 zu rechnen, damit ich keine halben Pixel herausbekomme
Leider bin ich gerade relativ verwirrt und weiß nicht so recht weiter, die Kugel muss ja schließlich nichtmal auf irgendwelche Wände Rücksicht nehmen, sondern soll nur von A nach B bewegt werden, währrend sich B (Monster) natürlich währrend des Prozesses bewegt (Die Funktion muss die Kugel also nur um einen Pixel bewegen, da Sie in jedem Schleifendurchlauf ausgeführt wird).
Ich hoffe mir kann einer weiterhelfen oder einen logischen Tipp geben, weil ich gerade wirklich etwas fest stecke...Danke
-
Also erst fliegt die Kugel gerade, dann gerade?
Also, es hört sich so an als solltest du float statt int verwenden.
float xKugel, yKugel, xZiel, yZiel; //Wie du dem Zeug Werte zuweist ist deine Sache float bewegungProSchritt = 1.5; //hier kannst auch was nehmen was du brauchst float xAbstand = xKugel - xZiel; float yAbstand = yKugel - yZiel; float abstand = sqrt(xAbstand*xAbstand+yAbstand*yAbstand); if (abstand <= bewegungProSchritt) //Wir wollen ja nicht übers Ziel hinausschießen { xKugel -= xAbstand; //oder direkt xKugel = xZiel; yKugel -= yAbstand; //oder direkt yKugel = yZiel; } else { //Hier schaun wie weit du in diesem Frame gehen willst pro Koordinate //(xAbstand*bewegungProSchritt/abstand)^2 + (yAbstand*bewegungProSchritt/abstand)^2 = //((xAbstand^2 + yAbstand^2)/(abstand^2))*bewegungProSchritt = // 1 * bewegungProSchritt = bewegungProSchritt // (zumindest bis auf Rundungsfehler) // Wir gehen also insgesamt nur "bewegungProSchritt" weit xKugel -= xAbstand*bewegungProSchritt/abstand; yKugel -= yAbstand*bewegungProSchritt/abstand; }
Am Anfang einfach die Koordinaten in floats umwandeln, und nur zum zeichnen wieder zurück in ints.
Ich hoffe das stimmt alles so, ist ja schon spät
[edit]
Den static_cast rausgetan, hatte am Anfang die Koordinaten selbst als int drinnen, daher kam der
-
Prinzipiell kannst du bei jedem Durchlauf die Differenz der Positionsvektoren normalisieren und mit einem Faktor multiplizieren. So kommst du auf eine "genormte" Schrittweite.
Das bringt dir aber _keine_ gerade Schusslinie wenn das Ziel sich bewegt. Die Sichtbarkeit dieser Krümmung der Schusslinie ist von der Geschwindigkeit des Ziels abhängig. Wenn es schnell ist wird die Kugel dem Ziel vmtl in einer größeren Kurve folgen. Ist das Ziel langsamer, wird man die Krümmung kaum/weniger sehen.
Natürlich auch nur dann wenn die Berechnung der Positionsdifferenz in jedem Frame erneut durchgeführt wird. Falls du sie nur einmal beim "Abfeuern" ausführst trifft die Kugel mit großer Sicherheit ins Leere (auch wieder abhängig von der Geschwindigkeit des Ziels)
Was ich damit sagen will ist:
Für zielsuchende Geschosse ist das eine nette Möglichkeit - für jene die eigentlich nur gerade fliegen sollten, solltest du die Geschwindigkeit und Bewegungsrichtung des Ziels miteinberechnen.Wie sieht denn die Wegfindung für die Monster aus? Verwendet ihr A*, Dijkstra o.Ä. ?
-
Haha nein, wir haben uns das einfach mit ner Char-Map gemacht, also:
char map[25][25];
Die einzelnen Blöcke (Wiese etc.) sind alle 25*25 Pixel groß, so dass die Monster nur ihre X/Y-Position durch 25 teilen müssen, um auf ihren aktuellen "Block" zu kommen. Ist der Block == 'D' gehe Sie runter, und so weiter.
-
Scratch schrieb:
Haha nein, wir haben uns das einfach mit ner Char-Map gemacht[...]
Dann wäre das vmtl der nächste Schritt. Die Monster sollen ja wahrscheinlich von A nach B laufen und dabei nicht irgendwo auf der Karte herumirren.
Sieh dir mal A* an. Ist für soetwas wirklich zu empfehlen und hat einen hohen Lerneffekt
Dadurch kann man nette Maps basteln ohne einen spezifischen Pfad eingeben zu müssen. Außerdem kann man dadurch zur Laufzeit Wege versperren und die Monster suchen sich einfach erneut den kürzesten Pfad.
-
sehr gutes tutorial mit fertiger lernanwendung.