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

21.04.2016, 14:38

Laufroute von KI bestimmen

Hallo Leute,

ich probiere grad ein wenig mit Vektoren aus und bin dann auf die Idee gekommen eine Laufroute für spätere Gegner/KI´s zu machen.

Jetzt spontan mit meinem Basiswissen hätte ich das so gemacht:

Ich bestimme 4 Punkte die ein Rechteck bilden also:

A(0,0) + <- + B(50,0)

C(0,50) + -> + D(50,50)

Als erstes Bilde ich den Richtungsvektor zu C also C- A und so weiter (AC = 0/50, CD = 50/0, DB = 0/50, BA = 50/0).

Wenn der Gegner dann den jeweiligen Vektor erreicht habe, ändere ich je nach Vektor einfach meine Variable welche die Geschwindigkeit angibt ->

Hat der Gegner AC noch nicht erreich, muss die xPos = 0 sein und die yPos = 1 (z.B). Dann wenn xPos/yPos = AC ist, muss xPos = 1 sein und yPos = 0 und immer so weiter.

Würde das für ganz einfache und dumme KI reichen? Oder gibt es da andere Methoden die ein Anfänger benutzten könnte?

Gruß

MitgliedXYZ

Alter Hase

Beiträge: 1 369

Wohnort: Bayern

  • Private Nachricht senden

2

21.04.2016, 15:17

Suchst du Pfadfindungsalgorithmen?

Da gibt es z.b.: Flood fill, Dijkstra und A*.

3

21.04.2016, 15:43

Hi, nein also fuer den Anfang eigentlich wirklich nur das im Rechteck laufen ^^

Jar

Treue Seele

Beiträge: 197

Wohnort: Lübeck

Beruf: Softwareentwickler

  • Private Nachricht senden

4

21.04.2016, 16:28

Vectoren in 2D sind irgendwie wie mit Kanonen auf Spatzen schießen.

Hole dir einfach den Winkel (SatzDesPythagoras) der zwischen dem Ausgangspunkt und dem Zielpunkt deines Gegners liegt.
Jetzt berechnest du anhand eine "schrittweite" wie weit sich dein Gegner pro Zeitintervall bewegen soll.
Mit jedem Intervall kommt der Gegner dem Zielpunkt näher.

x = schrittweite + Math.cos(winkel);
y = schrittweite + Math.sin(winkel);

Der Winkel ist dabei zwischen 0 und 2Pi.

Beste Grüße,
Jar

5

21.04.2016, 17:43

Hey Jar, danke fuer deinen Ansatz, aber muesste der Winkel bei einem Viereck nicht immer 90° sein ? Ich verstehe deswegen nicht wie man das ganz genau mit dem Winkel rechnen soll :/

Gruss



Gruss

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

6

21.04.2016, 17:44

Vektoren sind auch bei 2D super. Vieles machen sie einfacher, man muss sich nicht mit Winkeln rum schlagen. Und man benötigt die teuren sin und cos Aufrufe nicht. Zumindest bei einfacher Bewegung nicht.

Mach das ganze doch etwas generischer. Mach eine Liste von Punkten die der Charakter ablaufen soll. Er läuft immer zum ersten Punkt aus der Liste. Sobald er an dem Punkt angekommen ist wird der Punkt aus der Liste gelöscht. Dadurch rutscht automatisch der nächste Punkt an erste Stelle und ist das nächste Ziel. Jetzt kannst du deine Punkte vom Rechteck in die Liste packen aber genau so gut andere Pfade bestimmen. Wenn du dann hinterher zum Beispiel auf Algorithmen wie von MitgliedXYZ zurück greifst die dir Pfade berechnen dann könnten diese Algorithmen dir auch einfach Listen mit Punkten zurück geben und dein Code ist schon so weit dass er die Pfade ablaufen kann. Das ist auch gar nicht so schwer wie du feststellen wirst.
Anstatt immer zum ersten Punkt aus der Liste zu laufen könntest du das ganz auch so schreiben dass immer der letzte Punkt der Liste das aktuelle Ziel ist. Je nach Datenstruktur für deine Liste ist das löschen des letzten Elementes einer Liste oft günstiger als das erste Element zu löschen. Dann wäre die Liste also im Prinzip in umgekehrter Reihenfolge.
Weiterhin kann es sinnvoll sein nicht davon auszugehen dass der Charakter genau an dem Punkt ankommt sondern nahe diesem Punkt ist. Nach dem Motto, ist der Charakter 0.5 Einheiten von dem Punkt entfernt zählt es als angekommen.
Das ist erst mal ein recht einfaches System welches du hinterher wie gesagt schön weiter verwenden und erweitern kannst.
„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.“

7

22.04.2016, 02:20

Hi Schorsch,

danke für die Idee. Sie ist genial und einfach und es war wieder klar das ich da nicht alleine drauf komme -.-

Aber eine Sache wäre da noch: Wenn ich die Positionen aus der Liste wieder lösche, läuft mein Gegner ja theoretisch nur einmal die Route ab oder? Wäre es dann nicht noch gut sowas wie ein Enum zu benutzen, um Richtungswechsel zu triggern?

Gruß

MitgliedXYZ

Alter Hase

Beiträge: 1 369

Wohnort: Bayern

  • Private Nachricht senden

8

22.04.2016, 08:37

Was du suchst ist eine Queue, damit könntest du die Koordinaten nacheinander ablaufen und sobald du ein Zielpunkt erreichst, fügst du es wieder hinzu. Da es nach dem Prinzip first-in-first-out arbeitet, kannst du so die Route immer wieder ablaufen.

Jar

Treue Seele

Beiträge: 197

Wohnort: Lübeck

Beruf: Softwareentwickler

  • Private Nachricht senden

9

22.04.2016, 08:43

Winkel bei einem Viereck nicht immer 90° sein

Hehe, hatte angenommen du willst das Viereck auch Quer in den 2D-Raum legen können :)

Du kannst auch eine CircularList nehmen einen sogenannten Ring, dann musst du nichts entfernen oder hinzufügen.

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

10

22.04.2016, 13:38

Aber eine Sache wäre da noch: Wenn ich die Positionen aus der Liste wieder lösche, läuft mein Gegner ja theoretisch nur einmal die Route ab oder? Wäre es dann nicht noch gut sowas wie ein Enum zu benutzen, um Richtungswechsel zu triggern?

Das kannst du mit deiner Liste ja alles erreichen. Irgendwo wird deine Liste mit Punkten eben generiert und gefüllt und an anderer Stelle wird die Liste eben genutzt. Hättest du jetzt zum Beispiel die 4 Punkte deines Rechtecks und möchtest dieses Rechteck endlos im kreis ablaufen dann könntest du einen Punkt sobald er entfernt wird direkt wieder hinten in die Liste schieben. Für solche Richtungswechsel könntest du die Punkte zwischenspeichern und sobald der letzte Punkt erreicht wird werden die zwischengespeicherten Punkte in umgekehrter Reihenfolge wieder in die eigentliche Liste gefüllt. Das wäre halt ein Ansatz. Natürlich gibt es da auch zig andere Möglichkeiten. Du könntest auch sagen dass die Punkte nie gelöscht werden und du dir das aktuelle Element merkst und ob das nächste Element aus der Liste der Vorgänger oder der Nachfolger ist. Dann könntest du die Liste erst vorwärts durchlaufen und sobald du am Ende bist eben wieder rückwärts. Da kannst du dir auch wilde Mischungen raus machen. Was du am Ende wie umsetzt hängt davon ab was genau dein Ziel ist. Ich würde erst mal versuchen möglichst einfach anzufangen. Vielleicht erst mal nur einen Pfad in eine Richtung ablaufen. Und dann kannst du ja einfach mal ein wenig rum spielen und gucken was dir so einfällt und wie du es umsetzen möchtest. Wenn du verschiedene Varianten durchprobierst wirst du dann selbst merken welche Variante für dich gut geeignet ist. Einige Varianten werden zum Beispiel aufwendiger zu implementieren sein als andere.
„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