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

Architekt

Community-Fossil

  • »Architekt« ist der Autor dieses Themas

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

11

14.02.2011, 19:40

@Architekt: Und du beschreibst genau das was der A* eben macht also verstehe ich nicht wo das Problem dabei ist.
Wenn er ein Hindernis detektiert dann sucht er den kostengünstigsten Weg um das Hindernis zu umgehen ...
Weis also nicht wo da das Problem ist.

Schorsch meinte, dass ich ansonsten auch den direkten Weg (Luftlinie) überprüfen könnte, anstelle des A* Algorithmus. Zumindest verstand ich das so.
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

12

14.02.2011, 20:33

Den A* wuerdest du dir dann nur sparen wenn wie ja beschrieben nichts im Weg liegt, wenn jedoch eni Hindernis vorhanden ist musst du dennoch irgendwie einen Ausweichkurs einschlagen, da wird man dann nicht drum rum kommen.

Architekt

Community-Fossil

  • »Architekt« ist der Autor dieses Themas

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

13

14.02.2011, 20:43

Den A* wuerdest du dir dann nur sparen wenn wie ja beschrieben nichts im Weg liegt, wenn jedoch eni Hindernis vorhanden ist musst du dennoch irgendwie einen Ausweichkurs einschlagen, da wird man dann nicht drum rum kommen.

Genau das war ja meine eigentliche Frage, also wie Schorsch sich das vorstellte.
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

14

14.02.2011, 21:44

Nebenbei ist das Testen des Weges ja auch fällig und A* geht eigentlich fast ideal endlang der direkten Verbindung, wenn es keine hindernisse gibt (siehe hier: http://dl.dropbox.com/u/6841319/path_pot2.bmp ->Bild aus meiner aktuellen Versuchsreihe per Potenziale "Knäckebrot das Schlausein" beizubringen).
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

15

14.02.2011, 23:20

Halt;)
Wenn du aufjedenfall einen Weg finden willst bist du mit A* an der richtigen Stelle. Aber je nach Spiel ist es ja nicht immer gewollt bzw. besonders schön, wenn der Gegner den Spieler findet, auch wenn er ihn eigentlich nicht sieht. In dem Beispiel was ich meinte könnte es so laufen:

Der Gegner läuft rum und sucht den Spieler(kann randomisiert laufen oder über Pfade, Er macht halt irgendwas;) ). Sobald der Gegner den Spieler sichtet, bewegt er sich auf diesen zu. Dabei wird jetzt mal davon ausgegangen, dass der Gegner nicht durch Hindernisse durchgucken kann, bzw wenn ein Hindernis im Weg ist, dann kann der Gegner dies einerseits nicht passieren, andererseits sieht er dann den Spieler aber auch nicht. Wenn jetzt der Fall eintritt, dass der Gegner den Spieler sieht und ihn verfolgt, der Spieler sich dann jedoch um eine Ecke bewegt, sieht der Gegner den Spieler ja nicht mehr. Nach obigem Ansatz würde er also wieder zu seiner alten Arbeit zurückkehren. Man könnte jetzt eine Art Memorysystem einbauen, indem der Gegner sich den Punkt merkt, andem er den Spieler zuletzt gesehen hat(Kann auch erweitert werden, sodass der Gegner auf Geräusche reagiert, welche mit Zusatzinformation wie Position bzw Richtung aus der das Geräusch kommt abgespeichert werden). Jetzt läuft der Gegner zu diesem Punkt. Wenn er den Spieler jetzt wieder sichtet, verfolg er ihn weiter. Sichtet er ihn nicht könnte er eine neue Strategie verfolgen(zu seiner letzten Arbeit zurückkehren oder möglicherweise zufällig nach dem Spieler in einem Bestimmten Umkreis suchen). Ich wollte dir damit eher eine Alternative zu deiner KI zeigen. Oft greift man bei Gegnern direkt zu A* oder Anderen, obwohl es vielleicht anders schöner für das Spiel wäre. Ich fand das Buch "Programming Game AI by Example" wirklich schön zu diesem Thema. Ist ne schöne Einführung in das Thema KI, einfach geschrieben und zeigt einem mal ein paar nette Ideen, was so möglich ist und was man wie machen kann. Ist vielleicht ja mal einen Blick wert.
Aber wie gesagt wenn du erreichen willst, dass der Gegner den Spieler in jeder Situation finden kann(solange Sie möglich ist) ist A* wohl ne gute Wahl;)
„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.“

16

14.02.2011, 23:54

Eigentlich geht es darum, dass es ganz einfach mehrere Ebenen des Problems sind. Solange der Gegner den Spieler nicht sieht, weiß er nicht wo er hinlaufen soll, solange der Gegner keinen Wegfindungsalgorithmus benutzen kann, weiß er nicht, wie er dort hinlaufen kann, wo er hinlaufen will. Dementsprechend sollte man auch in mehreren Ebenen programmieren, nämlich im einfachen Falle "Was will ich tun" und im zweiten Schritt "Wie kann ich das tun". Man kann das natürlich später beliebig verfeinern z.B. "Ich bewache dieses Gebiet. Dafür bleibe ich hier und greife Gegner an, die zu Nahe kommen. Um Gegner anzugreifen, laufe ich zu ihnen hin. Um zu ihnen hin zu laufen, rechne ich mir einen Weg aus."
Lieber dumm fragen, als dumm bleiben!

Mastermind

unregistriert

17

16.02.2011, 06:59

Halt;)
Wenn jetzt der Fall eintritt, dass der Gegner den Spieler sieht und ihn verfolgt, der Spieler sich dann jedoch um eine Ecke bewegt, sieht der Gegner den Spieler ja nicht mehr. Nach obigem Ansatz würde er also wieder zu seiner alten Arbeit zurückkehren.


In der realen Welt würde natürlich jeder halbwegs intelligente Gegner davon ausgehen das der Spieler nicht einfach verschwunden ist sondern noch hinter der Ecke vorhanden und ihn daher weiter verfolgen. Also vorausgesetzt er kommt nicht aus anderen Gründen zu dem Schluss, dies zu lassen.

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

18

16.02.2011, 11:22

In der realen Welt würde natürlich jeder halbwegs intelligente Gegner davon ausgehen das der Spieler nicht einfach verschwunden ist sondern noch hinter der Ecke vorhanden und ihn daher weiter verfolgen. Also vorausgesetzt er kommt nicht aus anderen Gründen zu dem Schluss, dies zu lassen.
Naja genau darauf bin ich ja dann auch eingegangen. Ob man die KI nun in mehrere Schichten aufteilt oder nicht ist Geschmackssache. Da gibts zwei große Ansätze für KI die da in den meisten Fällen greifen sollten. Einmal die Statebasierte KI:
Hier hast du halt mehrere Zustände, welche untereinander wechseln und ausgetauscht werden. Jeder Zustand bestimmt das Verhalten des Agenten. Für das wechseln in einen anderen Zustand, sind die Zustände normal selbst zuständig;);). Das heisst bei obigem Beispiel: Der Gegner ist im Zustand "mach irgendwas", dann sieht er den Gegner. "mach irgendwas" entscheidet dann in den Zustand "gegner verfolgen" zu wechseln. Jetzt wird der Gegner verfolgt. Der Gegner ist auf einmal für den Agenten nicht mehr Sichtbar. "gegner verfolgen" entscheidet auf das Memorysystem zurückzugreifen, und an dem Punkt zu gucken, an dem der Gegner zuletzt gesehen wurde. Er sieht den Gegner wieder und verfolgt ihn weiter. Er erreicht den Gegner. "gegner verfolgen" entscheidet in "gegner angreifen" zu wechseln und der Agent fängt an den Gegner zu bekämpfen. Dies könnte jetzt so ein theoretischer Ablauf sein.
Der zweite große Ansatz ist die Zielgetriebene KI:
Hier hast du einfach Ziele die modeliert werden. Du hast zum Beispiel "gegner vernichten" als Ziel. Dies besteht aus den Unterzielen "gegner suchen", "gegner erreichen" und "gegner angreifen". Diese Unterziele bestehen dann wieder aus Unterzielen. Man wird also immer kleiner in der Aufgabe der Ziele.
Die Ziele werden dann in einem Kompositum angeordnet und es sollte möglichst so umgesetzt werden, dass du einfach Ziele hinzufügen bzw zwischenschieben kannst, sowie Ziele entfernen kannst. Dadurch kannst du dynamisch Ausnahmebehandlungen einfügen, zB einen nicht erwarteten Gegner des Agenten, der abgewehrt werden muss.

Ich denke für dein Rollenspiel eignet sich so ein State Ansatz wahrscheinlich ganz gut. Ich stelle mir das vor wie bei Diablo2;) Die Gegner laufen in einem bestimmten bereich rum. Von mir aus laufen sie auch vorbestimmte Pfade ab. Sobald der Spieler in ihre nähe oder ihren Sichtbereich kommt, welchseln sie ihren Zustand und versuchen den Spieler zu erreichen und zu töten. Man kann zusätzlich noch eine Art Nachrichtensystem einbauen, sodass Agenten sich untereinander über Nachrichten verständigen können. Dann könnte zum Beispiel ein Agent der den Spieler sichtet eine Nachricht an alle Agenten im Umkreis senden, sodass diese ihren Zustand ändern können, und ihm zur Hilfe kommen. Durch so einfache Systeme kann man schon einiges erreichen. Man sollte halt immer nur dran denken, dass viele toll gedachte Sachen dem Spieler später garnicht auffallen, oder sogar am Spielspaß kratzen. Zu kluge Gegner machen dann ja irgendwann auch kein Spaß mehr;)
„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.“

Architekt

Community-Fossil

  • »Architekt« ist der Autor dieses Themas

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

19

16.02.2011, 13:25

Ich wollt es eigentlich so handhaben, dass, sobald der Spieler in dem Sichtradius des Gegners gekommen ist, der Weg zu ihm berechnet und beschritten wird. Angekommen wird überprüft, ob der Spieler sich entfernt hat und ein neuer Weg wird berechnet, sofern der Spieler noch im Sichtradius ist, andernfalls bleibt der Gegner an der Position (welche ja die alte Position des Spielers darstellt). Das ermöglicht dem Spieler auch einige Fluchtversuch.
Aber das mit dem Nachrichtensystem finde ich interessant, werde ich irgendwie noch einbauen.

edit: Das ist soweit auch super gelöst. Ich brauche keine G und damit auch keine F Werte, ich regel alles über die Heuristik zum Ziel, da ich eh nur kurze Strecken haben. Sollte der Weg nicht gefunden werden (Was ohne resultierende und ändernde G Werte ja vorkommen kann) bleibt der Gegner einfach stehen. Ich denke, dass kommt bei meinen kurzen Wegen zum Ziel (also zum Spieler der in den Sichtradius zum Gegner gekommen ist) so gut wie nie vor und ist wenn nicht weiter schlimm.
Ob ich nun auch noch ein Msg System einbaue, also das der Agent der auf mich zu rennt auch eine Message an umliegende/alle Agenten macht, wo der Spieler zu finden ist, muss ich noch gucken, könnte recht aufwändig werden.
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »Architekt« (17.02.2011, 01:43)


Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

20

17.02.2011, 14:28

Wenn du es so löst dann solltest du dir vielleicht wirklich mal Steering Behaviors angucken. http://www.red3d.com/cwr/steer/ Da findest du einiges dazu. ist ne super Sache. Sind alles nur Kleinigkeiten und relativ einfache Prinzipien, welche im richtigen Einsatz und in der richtigen Kombination aber einiges erreichen können. Mit dem Messagesystem ists eigentlich relativ schnell gemacht. Hab die Idee auch aus nem KI Buch. Du hast eine Klasse, welche eine Message darstellt. Diese kennt den Sender und den Empfänger der Nachricht. Zusätzlich hat ne nachricht noch nen Typ. Damit kannst du die einzelnen Nachrichten auseinander halten. Zum Beispiel einfach nen Int-Wert. Im oberen Beispiel könnte eine 1 dann bedeuten, dass der Sender Hilfe braucht. Als letzten Wert hat die Nachricht einen (void*) bzw ein Object oder was auch immer. Je nach Sprache. Halt einfach nen Zeiger, der irgendwas speichern kann. In unserem Beispiel könnte hier die Position, an die die Hilfe angefordert wird stehen. Zusätzlich zur Klasse für Nachrichten kannst du dir ne Versand-Klasse schreiben. Die hat einfach Methoden wie send oder sendToAll oder was auch immer du genau brauchst. Und diese Klasse wird einfach von deinem Agenten aufgerufen und darüber sendet er die Nachricht an die anderen Agenten. Zum Beispiel die im Umkreis. Welcher Agent im Umkreis ist, könnte von der SenderKlasse übernommen werden. Die Agenten brauchen dann natürlich zusätzlich ne Methode ReceiveMessage oder sowas, damit sie auch Nachrichten erhalten können. Dort können sie dann entsprechend reagieren, solange diese Nachricht für sie interessant ist. Kann ja sein das ein Typ Agent auf bestimmte Nachrichten nicht reagiert, warum auch immer. Son System ist schnell umgesetzt und kann je nach Anwendung sehr mächtig sein. Im Buch werden da einige Anwätze zu genannt. Zum Beispiel ein Spieler der einen Gegner schlägt und wenn er trifft sendet er an den Gegner ne Nachricht hey ich hab dich getroffen. Der Gegner kann dann entsprechend reagieren. Zum Beispiel nach hinten prallen und Leben verlieren etc. Gibt es einige Möglichkeiten. http://www.ai-junkie.com/books/index.html
Das ist die Seite von dem Kerl, der das Buch geschrieben hat aus dem ich das Message zeug habe. Dort gibts auch den Code zu dem Buch. Musst du einfach mal im Teil zum ersten Kapitel gucken. Die Beispiele da sind nicht sehr lang und da kannst du dir ja mal angucken, wie er es einsetzt.
„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