Ergebnis 1 bis 9 von 9

Thema: Simpeles KS

  1. #1

    Simpeles KS

    Servus,
    ich habe gerade damit begonnen, ein KS für mein Spiel zu erstellen, allerdings scheitere ich an der umsetzung.
    Es soll ein AKS werden und keinen komplexen Aufbau besitzen. Ich versuche mal zu beschreiben wie ich das meine:

    Die KI setzt sich aus 2 Variablen zusammen.

    1. Variable: GegnerReaktionszeit
    2. Variable: GegnerSchaden

    Der Gegner ist so definiert, dass wenn er den Helden berührt oder umgekehrt ein Timer startet (Variable: GegnerReaktionszeit). Nehmen wir als Beispiel eine Sekunde.
    Der Gegner berührt den Held -> Nun hat der Held eine Sekunde Zeit den Gegner zu schlagen, ansonsten greift der Gegner an und zieht ihn eine bestimmte Anzahl an HP ab (Variable: GegnerSchaden).

    Logischer Weise haben schwache Gegner eine schwache Angriffsstärke und eine hohe Reaktionszeit und stärkere Gegner eine hohe Angriffsstärke und eine niedrige Reaktionszeit.

    Das Problem ist, ich weiß echt nicht wie ich das umsetzen kann. Vorallem die Abfrage mit dem Timer ist kniffelig und will nicht funktionieren.

    Hat jemand eine Ahnung wie ich das machen kann?
    Wenn es nicht zu viel verlangt ist, wäre ein kleines Beispiel bestimmt besser zum erklären.

    Gruß,
    Baum

    Edit: Ich denke das mit dem Timer kann ich vergessen, da die kleinste Einheit eine Sekunde ist und Gegner dann eine Minimalreaktionszeit von einer Sekunde hätten.

  2. #2

    AW: Simpeles KS

    Du baust dir selbst nen Counter. Heißt: Sobald das Ganze aktiviert wird, startet ein Common Event auf Parallel Process das jede Zehntelsekunde (oder 60stelsekunde, so lange geht etwa ein Wait 0,0s) eine Variable um 1 erhöht/erniedrigt

    Wird innerhalb der Zeit Enter gedrückt, so wird ein Switch "Zugeschlagen" aktiviert, der verhindert, dass das Monster angreift.



    Btw, eine Sekunde ist für eine Angriffsreaktion viiiel zu lang, mach auch die schwächeren Monster schneller.

  3. #3

    AW: Simpeles KS

    Die Sekunde hat nur als Beispiel gedient. Okay danke, jetzt ist zumindest schonmal das Problem mit dem Counter gelöst. Aber wie soll die Abfrage jetzt genau aussehen? Das mit dem Switch hab ich mir auch schon überlegt, allerdings weiß ich nicht wie ich die Abfrage einbaue.

  4. #4

    AW: Simpeles KS

    Ich will das was Dhan gesagt hat nochmal weiter ausführen, da du ja auch um ein Beispiel gebeten hast. Ich hab das gerade im Maker nachgebaut und es funktioniert auch so recht gut. Dabei würde ich dir auch empfehlen die Reaktionszeit weit unter einer Sekunde anzusetzen. Das ist wirklich schon extreeem langsam

    Also, nun zum Code.
    Du brauchst folgende Variablen:
    Code:
    Held X -> X-Koordinate des Helden
    Held Y -> Y-Koordinate des Helden
    Gegner X -> X-Koordinate des Gegners
    Gegner Y -> Y-Koordinate des Gegners
    Held Schaden -> Angriffsschaden des Helden (die Berechnung überlasse ich dir ;) )
    Gegner Schaden -> Angriffsschaden des Gegners (s.o.)
    Gegner Reaktionszeit -> Zeit die der Gegner braucht bis er angreift in 60stel Sekunden
    Gegner HP -> Energie des Gegners
    Gegner Zeitzähler -> Die Zählervariable für den Gegner
    Außerdem brauchst du zwei Events (zumindest bei meiner Version ):
    Das erste ist ein Parallel-Process Event welches die Angriffskontrolle des Gegners übernimmt. Das zweite ist der Gegner selbst welcher nur die Angriffsfläche für den Helden darstellt.
    Fangen wir mal mit dem PP für den Gegner an:
    Code:
    Parallel-Process | Keine Startbedingung | Below Hero
    
    <>!Lable 1!
    <>Change Variable "Held X", set [(Hero) X-Coord.]
    <>Change Variable "Held Y", set [(Hero) Y-Coord.]
    <>Change Variable "Gegner X", set [(Gegner 1) X-Coord.]
    <>Change Variable "Gegner Y", set [(Gegner 1) Y-Coord.]
    <>
    <>Fork Event 'Gegner 1' Face Dir. = Down
    <><>Change Variable "Gegner Y" + 1
    <>Else:
    <>Fork Event 'Gegner 1' Face Dir. = Left
    <><>Change Variable "Gegner X" - 1
    <>Else:
    <>Fork Event 'Gegner 1' Face Dir. = Right
    <><>Change Variable "Gegner X" + 1
    <>Else:
    <>Fork Event 'Gegner 1' Face Dir. = Up
    <><>Change Variable "Gegner Y" - 1
    <>End:
    <>
    <>Fork Variable "Gegner X" = "Held X"
    <><>Fork Variable "Gegner Y" = "Held Y"
    <><><>Change Variable "Gegner Zeitzähler" +1
    <><><>Fork Variable "Gegner Zeitzähler" < "Gegner Reaktionszeit"
    <><><><>Wait 0,0 secs
    <><><><>Goto !Lable 1!
    <><><>Else:
    <><><><>Show Battle Animation "Hit A" at 'Hero' [wait until done]
    <><><><>Change HP [Whole Party] dec. "Gegner Schaden" [possible death]
    <><><>End:
    <><>End:
    <>End:
    <>
    <>Change Variable "Gegner Zeitzähler", set 0
    <>
    Sooo, was genau macht dieses Event nun?
    Am Anfang werden erst einmal die Koordinaten von Held und Gegner eingelesen.
    Für den nächsten Schritt muss man sich ins Gedächtnis rufen was wir eigentlich machen wollen:
    Wir wollen erreichen, dass der Gegner, wenn er den Helden vor sich hat, eine spezielle Zeit wartet und dann zuschlägt. Doch wie ermitteln wir ob der Held vor dem Gegner steht? Wir betrachten einfach nicht mehr das Feld auf dem der Gegner steht, sondern nehmen das Feld vor ihm. Dazu dient die folgende Abfrage. Sie kontrolliert in welche Richtung der Gegner schaut und passt dann seine Koordinatenvariablen so an, dass sie nicht mehr den Gegner, sondern das Feld vor ihm wiedergeben. Wenn man ein bisschen drüber nachdenkt dürfte das schnell klar werden .
    Der Rest ist dann ein Kinderspiel:
    Gleichen sich die Koordinaten des Feldes vor dem Gegner und die des Helden steht der Held logischerweise auf dem Feld vor dem Gegner. Damit können wir also die Zählervariable um 1 erhöhen und nach einer kurzen Pause von einer sechzigstel Sekunde kontrollieren ob bereits lange genug gewartet wurde. Wenn nicht springe ich per Lable wieder zum Anfang des Events, sodass erneut die Koordinaten überprüft werden und in dem Fall das der Held immer noch da ist wo er vorher auch war die Zählervariable wieder erhöht wird.
    Sollte nun lange genug gewartet worden sein attackiert der Gegner den Helden. Hier passiert dies mit einer einfachen Battle Animation. Danach noch schnell die Helden HP um den Wert "Gegner Schaden" verringern und fertig. Da nun die vorher aufgebaute Lable-Schleife verlassen wird setzte ich den Zähler wieder auf 0 und das Event wird erneut durchlaufen, nur mit genulltem Zähler, also muss der Gegner wieder seine Zeit lang warten.
    Damit ist dieses Event fertig. Nun kommen wir zum Gegnerevent, welches auch nicht wirklich schwieriger ist:
    Code:
    Push Key | Same Level As Hero | Keine Startbedingung
    
    Route: "Step Towards Hero ; Face towards Hero"
    
    <>Change Variable "Gegner Zeitzähler", set 0
    <>Show Battle Animation "Sword 1" at 'This Event'
    <>Change Variable "Gegner HP" - "Held Schaden"
    <>Fork Variable "Gegner HP" <= 0
    <><>Play SE: "Monster 2"
    <><>Move Event 'This Event': "Transp. Up ; Wait ; Transp. Up ; etc."
    <><>Flash Cjarakter 'This Event' [31 ; 0 ; 0 ; 31] for 1 sec [Wait until done]
    <><>Change Variable "Gegner X", set -10
    <><>Change Variable "Gegner Y", set -10
    <><>Clear Timer
    <>End:
    <>
    Erstmal ist es wichtig das du nicht die normale "Step Towards Hero" Einstellung unter dem "Movement Type" wählst, sondern selbst eine Route festlegst. Tust du dies nicht gibt es Probleme mit der Face Richtung, da dann der Gegner den Helden nie anguckt sondern dauernd hoch und runter läuft. Verwendest du diese Route schaut der Gegner nach jeder Bewegung in Richtung des Helden und bleibt auch stehen, sobald er diesen erreicht hat. Nachteil ist allerdings, dass er keine randomierten Bewegungen macht, wenn er nicht mehr weiterlaufen kann, weshalb ein Hindernis schnell zu seinem Verhängnis werden kann. Eine einfache andere Lösung ist mir leider nicht eingefallen...
    Aber weiter im Code:
    Dieses Event soll nichts anderes machen als sich selbst töten, sobald der Held an es ran tritt und Enter drückt. Gleich zu beginn wird die Zeitzähler Variable des Gegners auf 0 gesetzt, da du ja wolltest, das der Gegner neu mit zählen anfangen muss, sobald der Held ihn angreift. Danach kommt sofort die Battle Animation und das Verringern der HP um den Wert "Held Schaden".
    Sollten die HP des Gegners auf 0 oder darunter gesunken sein soll er einen Sterbesound spielen, seine Transparenz erhöhen (langsam verschwinden) und sich selbst rot "färben". Nach einer Sekunde vernichtet sich das Event selbst und wird erst wieder auftauchen sobald man die Map verlässt und erneut betritt. (Clear Timer ist leider eine falsche Übersetzung und bedeutet so viel wie "Lösche das Event".)
    Damit ist dein Mini-AKS auch schon fertig

    Ich hoffe ich konnte dir helfen

    mfg
    Phönix Tear

    P.S:
    Solltest du den Deutsch-Patch verwenden mach den weg T_T
    Ansonsten musst du wohl versuchen aus dem Sinn des Codes heraus die Übersetzung zu finden. Ich kenne die Übersetzung nämlich auch nicht und bin ein Verfechter der Englischen Version. Einmal weil es einfach besser klingt und zum anderen weil wir alle das gleiche nutzen sollten um solche Probleme zu verhindern. Da Englisch internationaler ist als Deutsch und außerdem im Normalfall den Kern der Sache besser trifft (Switch -> Tab???), sollte man also Englisch und nicht Deutsch wählen .

  5. #5

    AW: Simpeles KS

    Hab das mal so nachgebaut und zum Teil funktioniert es auch, allerdings habe ich bestimmt wieder mal was falsch gemacht ~~

    Hier sind die Events:




    Der Gegner verschwindet zwar nach 5 Schlägen (Gegner 5 HP, Angriffskraft 1 HP), aber irgendwie wird die Reaktionszeit nicht beachtet; ich glaub ich hab die gar nicht eingestellt ~~)

  6. #6

    AW: Simpeles KS

    Zitat Zitat
    (...ich glaub ich hab die gar nicht eingestellt ~~)
    Dann stell sie ein :S
    Denn so im Skript sehe ich keinen Fehler. Es muss also wohl daran liegen das du vorher vergessen hast die "Gegner Reaktionszeit" auf z.B. 30 zu setzen. Oder meinst du etwas anderes mit "nicht beachtet"?

    Ich kann nur wiederhohlen: Bei mir hats funktioniert

  7. #7

    AW: Simpeles KS

    Ohja verdammt, hab die falsche Variable benutzt (das war die, mit der ich es vorher versucht habe x))

    Okay, jetzt funktioniert es wunderbar, aber eine Kleinigkeit ist noch falsch. Wenn der Gegner besiegt, sprich wenn die GegnerHP Variable auf 0 ist, verschwindert zwar der Gegner, aber das Event bleibt unsichtbar auf der selben Position.

    Kann ich da einfach 'Set Event Place, this Event, 0;0' machen?

    Und wieviele Gegner sollte ich maximal auf eine Map machen, damit es nicht ruckelt? Sind ja ne Menge Variablen (das Spiel ist eher auf Rätsel und nicht auf das Kämpfen fokusiert.)

    Aufjedenfall bedank ich mich an der Stelle schonmal, ihr habt mir echt sehr viel weitergeholfen, vorallem Phönix Tear wegen dem Beispiel und wegen dem ganzen Rumtesten, einfach Spitze.

    Edit: Achja, und der Gegner greift auch noch an, wenn gerade das Moveevent läuft, um die Transparenz zu steigern, wenn der gegner tot ist.

    Geändert von dasBAUM (28.12.2006 um 22:55 Uhr)

  8. #8
    Tja, ich denke, dass eher du selbst die Maximalzahl festlegst, als der Maker. Denn für jeden neuen Gegner brauchst du erneut die Abfrage im PP und neue Variablen. D.h. jeder Gegner macht für dich mehr arbeit. Aber an sich sollte der Maker bei einem derart leichten KS 10 bis 20 solcher Gegner locker schaffen

    Und zu deinem Fehler:
    Durch den "Clear Timer" Befehl wird das Event komplett gelöscht. Es ist also wirklich nichts mehr übrig. Ich bevorzuge dies der "Set Event Place" Methode, da es sonst zu schwerwiegenden Bugs kommen kann, falls das Feld (0|0) dann doch mal erreichbar sein sollte .
    Damit der Gegner einen nach dem Tod nicht mehr angreift werden ja seinen X- und Y-Koordinate auf -10 gesetzt, also ein Feld das auf jeden Fall außerhalb der Reichweite des Helden liegt.
    Trotzdem kann es nicht schaden für jeden Gegner einen "Gegner tot" Switch einzubauen, der dann auch das PP beendet, bzw. den betroffenen Code-Teil überspringt. So kann es nämlich noch vorkommen, dass ein Gegner den Helden noch angreift, obwohl er schon am sterben ist...

    Damit du den Code auch auf mehrere Gegner anwenden kannst muss er allerdings noch angepasst werden. Kopierbare Gegner wären auch möglich, dass würde den Code allerdings schon um einiges komplizierter machen. Wenn du willst schreibe ich dir aber einen entsprechenden Code. Das würde dir zumindest die Arbeit ersparen für jeden Gegner eigene Variablen zu erstellen...
    Aber trotzdem, ich erweitere den Code jetzt mal auf 2 Gegner. Das Gegnerevent selbst muss nur marginal angepasst werden.

    Gegner 1:
    Code:
    Push Key | Same Level As Hero | Keine Startbedingung
    
    Route: "Step Towards Hero ; Face towards Hero"
    
    <>Change Variable "Gegner 1 Zeitzähler", set 0
    <>Show Battle Animation "Sword 1" at 'This Event'
    <>Change Variable "Gegner 1 HP" - "Held Schaden"
    <>Fork Variable "Gegner 1 HP" <= 0
    <><>Play SE: "Monster 2"
    <><>Move Event 'This Event': "Transp. Up ; Wait ; Transp. Up ; etc."
    <><>Flash Cjarakter 'This Event' [31 ; 0 ; 0 ; 31] for 1 sec [Wait until done]
    <><>Change Variable "Gegner 1 X", set -10
    <><>Change Variable "Gegner 1 Y", set -10
    <><>Clear Timer
    <>End:
    <>
    Gegner 2:
    Code:
    Push Key | Same Level As Hero | Keine Startbedingung
    
    Route: "Step Towards Hero ; Face towards Hero"
    
    <>Change Variable "Gegner 2 Zeitzähler", set 0
    <>Show Battle Animation "Sword 1" at 'This Event'
    <>Change Variable "Gegner 2 HP" - "Held Schaden"
    <>Fork Variable "Gegner 2 HP" <= 0
    <><>Play SE: "Monster 2"
    <><>Move Event 'This Event': "Transp. Up ; Wait ; Transp. Up ; etc."
    <><>Flash Cjarakter 'This Event' [31 ; 0 ; 0 ; 31] for 1 sec [Wait until done]
    <><>Change Variable "Gegner 2 X", set -10
    <><>Change Variable "Gegner 2 Y", set -10
    <><>Clear Timer
    <>End:
    <>
    Ich habe alles markiert was sich im Vergleich zum Gegner 1 Event verändert hat.

    Nun zum PP:
    Code:
    Parallel-Process | Keine Startbedingung | Below Hero
    
    <>Change Variable "Held X", set [(Hero) X-Coord.]
    <>Change Variable "Held Y", set [(Hero) Y-Coord.]
    <>Change Variable "Gegner 1 X", set [(Gegner 1) X-Coord.]
    <>Change Variable "Gegner 1 Y", set [(Gegner 1) Y-Coord.]
    <>Change Variable "Gegner 2 X", set [(Gegner 2) X-Coord.]
    <>Change Variable "Gegner 2 Y", set [(Gegner 2) Y-Coord.]
    <>... Weiter für alle Gegner ...
    <>
    <>Fork Event 'Gegner 1' Face Dir. = Down
    <><>Change Variable "Gegner 1 Y" + 1
    <>Else:
    <>Fork Event 'Gegner 1' Face Dir. = Left
    <><>Change Variable "Gegner 1 X" - 1
    <>Else:
    <>Fork Event 'Gegner 1' Face Dir. = Right
    <><>Change Variable "Gegner 1 X" + 1
    <>Else:
    <>Fork Event 'Gegner 1' Face Dir. = Up
    <><>Change Variable "Gegner 1 Y" - 1
    <>End:
    <>
    <>Fork Variable "Gegner 1 X" = "Held X"
    <><>Fork Variable "Gegner 1 Y" = "Held Y"
    <><><>Change Variable "Gegner 1 Zeitzähler" +1
    <><>Else:
    <><><>Change Variable "Gegner 1 Zeitzähler", set 0
    <><>End:
    <>Else:
    <><>Change Variable "Gegner 1 Zeitzähler", set 0
    <>End:
    <>
    <>Fork Event 'Gegner 2' Face Dir. = Down
    <><>Change Variable "Gegner 2 Y" + 1
    <>Else:
    <>Fork Event 'Gegner 2' Face Dir. = Left
    <><>Change Variable "Gegner 2 X" - 1
    <>Else:
    <>Fork Event 'Gegner 2' Face Dir. = Right
    <><>Change Variable "Gegner 2 X" + 1
    <>Else:
    <>Fork Event 'Gegner 2' Face Dir. = Up
    <><>Change Variable "Gegner 2 Y" - 1
    <>End:
    <>
    <>Fork Variable "Gegner 2 X" = "Held X"
    <><>Fork Variable "Gegner 2 Y" = "Held Y"
    <><><>Change Variable "Gegner 2 Zeitzähler" +1
    <><>Else:
    <><><>Change Variable "Gegner 2 Zeitzähler", set 0
    <><>End:
    <>Else:
    <><>Change Variable "Gegner 2 Zeitzähler", set 0
    <>End:
    <>
    <>... Weiter für alle Gegner ...
    <>
    <>Fork Variable "Gegner 1 Zeitzähler" >= "Gegner 1 Reaktionszeit"
    <><>Show Battle Animation "Hit A" at 'Hero' [wait until done]
    <><>Change HP [Whole Party] dec. "Gegner 1 Schaden" [possible death]
    <><>Change Variable "Gegner 1 Zeitzähler", set 0
    <>End:
    <>
    <>Fork Variable "Gegner 2 Zeitzähler" >= "Gegner 2 Reaktionszeit"
    <><>Show Battle Animation "Hit A" at 'Hero' [wait until done]
    <><>Change HP [Whole Party] dec. "Gegner 2 Schaden" [possible death]
    <><>Change Variable "Gegner 2 Zeitzähler", set 0
    <>End:
    <>
    <>... Weiter für alle Gegner ...
    <>
    <>Wait 0,0 secs
    <>
    Ich hab die Variante mit dem Lable diesmal bleiben lassen. Das würde es nur unnötig kompliziert machen. Ich hab diese Version jetzt zwar nicht getestet, ich gehe aber davon aus das sie funktioniert. Wenn nicht, sag bescheid

    mfg
    Phönix Tear

  9. #9
    Dass der Gegner verschwindet, sollte ja recht einfaach zu erreichen sein. Mach einfach einen Switch "Gegner 1 tot", und wenn der on ist, wird beim Gegner-Event ne zweite Page aktiviert, auf welcher kein Bild und Below Hero eingestellt ist. Das könntest du sogar auf Parallel Process einstellen, um mit diversen Scripten erreichen zu können, dass der Gegner respawnt, dass er eine giftige Wolke hinterlässt, dass nach einer Weile etwas dort passiert... Der Fantasie sind keine Grenzen gesetzt

    Und eigentlich sollte es bei fast jeder vernünftigen Monsterzahl ruckelfrei bleiben. So ein paar Charsets mit kleinem PP belasten die CPU ziemlich wenig. Ich denke, bis etwa 50 monster pro Map sollte das ruckelfrei ablaufen.

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •