- Tja, die "einfache" Methode wäre die, die ~Jack~ schon beschrieben hat. Stumpf abfragen wo das Zielfeld im Vergleich zum zu bewegenden Objekt ist und dieses in die entsprechenden Richtungen bewegen. Bringt nur leider nichts, sobald ein Hindernis in den Weg kommt. Für solche Fälle kann man dann die unschöne Gegenmaßnahme wählen und das Objekt 2 oder 3 mal randomiert bewegen, in der Hoffnung, dass das Hindernis recht klein ist. Sieht aber schlecht aus und funktioniert nur in sehr seltenen Fällen.
Daher hast du nur 3 Möglichkeiten.
- Die Routen-Version wie oben beschrieben. (Schlecht)
- Eine Wegpunkt-Version. Dazu platzierst du auf der Map mehrere Wegpunkte in möglichst offenen Bereichen an denen sich dein Objekt entlang hangeln kann. Dazu ermittelst du als erstes den Wegpunkt der dem Objekt am nächsten ist und bewegst es dorthin (um anderen NPCs oder dem Helden auszuweichen ist hier die Zufallsbewegungs-Ausweich-Taktik durchaus angebracht). Hat es diesen erreicht hast du wiederum 2 Möglichkeiten:
- Jeder Wegpunkt hat eine Auswahl von festgelegten Routen zu anderen Wegpunkten. Du ermittelst nun also, welcher Wegpunkt dem Zielfeld am nächsten ist und wählst aus den Möglichkeiten des Wegpunktes den richtigen Weg aus (dieser kann auch über andere Wegpunkte führen, welche dann die Bewegung übernehmen). (Sehr umständliche Methode)
- Du ermittelst den nächsten Wegpunkt auf dem Weg zum Zielfeld und wendest die selbe Bewegungsabfrage wie oben beschrieben auf diesen Wegpunkt als neues Zielfeld an. Von diesem geht es dann weiter.
Diese Methode würde so lange weiterlaufen, bis du einen Wegpunkt erreicht hast, dem das Zielfeld näher ist, als ein anderer Wegpunkt.
Leider ist die Wegpunkt-Variante sehr umständlich und häufig auch unnütz, da man schon eine recht dichte Verteilung braucht um komplizierte Hindernisse vernünftig umgehen zu können. Daher kann ich davon eigentlich nur abraten...- Pathfinding. Dies ist leider sehr kompliziert! Lachsen hat mal den A*-Algorithmus im Maker umgesetzt, der zwar scheinbar (so wie ich gehört habe) noch ein paar Schwächen hat (es kann angeblich zu Abstürzen kommen), bei meinen Test jedoch einwandfrei funktioniert hat. Wenn du Interesse daran hast kannst du entweder die Suchfunktion benutzen oder mir eine PN schreiben, ich glaub das Projekt verstaubt noch irgendwo auf meiner Festplatte...
Wenn du es selbst umsetzten willst (gehe ich nicht davon aus, da du ja schon nach "einfacheren" Sachen gefragt hast) ist Google ein guter Freund. Da gibt es eine Menge Seiten wo man sich die Funktionsweise des relativ einfachen A*-Algorithmus erklären lassen kann.- Ein "Kegel" macht die Sache natürlich kompliziert. Mal sehen. Als erstes solltest du berechnen, ob der Held vom "Gegner" überhaupt gesehen werden kann. Dies geht über eine einfache Variablenabfrage, in der Kontrolliert wird, ob der Gegner in die richtige Richtung schaut, und ob der Abstand nicht zu groß ist:
Öhm, ja... Irgendwie ist das jetzt schon der ganze Code... Er ist nicht getestet, kann also sein das es zu Fehlern kommt ^^°.Zitat
Aber was passiert da jetzt genau?
Ich werde mal versuchen es am Beispiel "Gegner Face Up" zu erklären, aber als erstes zur Anfangs-Fork:
Du hast ja angegeben, dass dein "Gegner" nur 5 Felder weit sehen kann. Dazu benutze ich die "Abstandsrechner"-Variablen. In diesen ist der relative Abstand zwischen Held und Objekt gespeichert. Dabei bedeuten die Werte folgendes:
- "Abstandsrechner X" < 0
Held links vom Gegner- "Abstandsrechner X" > 0
Held rechts vom Gegner- "Abstandsrechner Y" < 0
Held über dem Gegner- "Abstandsrechner Y" > 0
Held unter dem Gegner
Diese Werte sind natürlich kombinierbar, d.h. wenn beide Rechner > 0 sind, ist der Held rechts unter dem Gegner.
Die Zahl die in der Variable gespeichert ist, gibt mir sozusagen die Anzahl Schritte an, die ich in jede Richtung bräuchte, um vom Helden zum Gegner zu kommen.
Wenn ich jetzt also einen "Rahmen" ziehen will, muss ich lediglich die obigen 4 Bedingungen berücksichtigen:
- Der Held darf maximal 5 Felder links vom Gegner sein ("Abstandsrechner X" >= -5)
- Der Held darf maximal 5 Felder rechts vom Gegner sein ("Abstandsrechner X" <= 5)
- Der Held darf maximal 5 Felder über dem Gegner sein ("Abstandsrechner Y" >= -5)
- Der Held darf maximal 5 Felder unter dem Gegner sein ("Abstandsrechner Y" <= 5)
Damit habe ich dann scho nmal eingeschränkt das der Held überhaupt in Sichtweite des Gegner ist. Ich habe also um ihn sozusagen einen "Kasten" erschaffen. Ist der Held innerhalb dieses Kastens, sind die obigen Bedingungen wahr und ich kann weiter abfragen. Sind sie dies nicht, kann ich mir den ganzen Rest sparen.
Nun aber zum "ganzen Rest".
Da du ja einen Kegel haben wolltest, konnte ich nicht einfach nur abfragen, ob der Gegner in Richtung des Helden schaut, ich musste diagonale Trennlinien ziehen. Um das besser zu verstehen muss man sich die Funktionsweise der Abstandsrechner-Variablen genauer ansehen:
Das rote ist der Gegner mit Blickrichtung, türkis ist sein Sichtfeld, das helle Blau ist der Rand des Sichtfeldes. Lila sind zwei mögliche Heldenpositionen. Die hellblauen Striche geben an, wie man sich bewegen müsste um vom Gegner zum Helden zu kommen (daneben steht die Schrittzahl).
In diesem Bild wird schnell deutlich, dass man sich - um im Sichtfeld zu bleiben - maximal so viele Schritte hoch wie zu den Seiten bewegen darf. Anders ausgedrückt heißt das, dass der Held maximal so viele Schritte neben dem Gegner stehen darf, wie er über ihm steht.
Und genau das frage ich in den Forks unter "Face Up" ab.
Ich weiß, dass der Gegner nach oben schaut. Also prüfe ich als erstes, ob der Held über dem Gegner steht (das ist wahr, solange der "Abstandsrechner Y" < 0 ist). Ist dies der Fall, muss ich nur noch prüfen, ob der Held nicht zu weit rechts oder links steht, um nicht mehr im Sichtfeld zu sein. Da ich nicht weiß auf welcher Seite vom Gegner er steht, prüfe ich genau wie beim Abstecken des Rahmens zuvor einfach alle Möglichkeiten. D.h. er darf maximal "Abstand von Gegner zu Held in Y-Richtung" Felder links vom Gegner sein und maximal "Abstand von Gegner zu Held in Y-Richtung" Felder rechts vom Gegner sein. Guck dir die Forks und die Umrechnung mit "* -1" noch mal genauer an, dann wirst du verstehen wie das funktioniert.
Damit sollte eigentlich alles geklärt sein ^^°- Tja, dazu gibt es auch wieder eine Menge Möglichkeiten...
Ich denke mal, dein größtes Problem ist dabei die Sache mit dem zwischenschiebbaren Objekt. Da frage ich mich allerdings wie du das in deinem Spiel verdeutlichen willst. Ich meine, nehmen wir an das ist eine Laserschranke die dem Helden schadet. Wenn man ein Objekt dazwischenschiebt hilft das dem Helden ja kein Stück weiter, außer er klettert über das Objekt. Davon gehe ich aber mal nicht aus.
Um dieses Problem zu umgehen dürfte eine solche "Schranke" nur von einer Seite ausgestrahlt werden und davon gehe ich hier auch aus.
Um ein solches System umzusetzen brauchst du an sich nur 1 Event, das sich komplett selbst steuert und den Ausgangspunkt der Schranke (sowie dessen Blickrichtung). Ich sage einfach mal, das das in diesem Fall ein NPC mit Laseraugen ist (). Dieser soll frei bewegbar sein. Den grafischen Aspekt berücksichtige ich jedoch nicht. Damit musst du selbst fertig werden
.
Also zum Code. Damit die Sache funktioniert würde ich erstmal eine Abfrage per Koordinaten vorschlagen. Danach kommt dann noch ein Hilfsobjekt zum Einsatz, welches kontrolliert, ob ein Gegenstand zwischen Aussender und Held steht. Aber erst mal zur Variablenabfrage:
Hoffe das es einigermaßen verständlich ist... Erst fragt man die Richtung in der die Schranke schaut ab und prüft ob der Held überhaupt auf der Linie steht. Danach setzt man das Event selbst (muss auf "Same Level As Hero" stehen) auf die Position der Schranke und versucht den Helden zu erreichen. Gelingt dies, ist kein Hindernis im Weg, dementsprechend wird der Held getroffen. Dabei muss man jedoch beachten, dass das Event automatisch ein Feld vorm Helden stehen bleibt, da der Held ja selbst auch ein "Hindernis" ist, den es nicht passieren kann.Zitat
Ich hoffe mal, dass du damit etwas anfangen kannst... (>6 Seiten in Word xD)
mfg
Phönix Tear