PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : CommonEvent-Schleifen definitiv beenden - Wie?



IndependentArt
17.05.2013, 16:02
hallo,

mein KS besteht wie viele aus einer schleife von CE, die sich gegenseitig callen. zu dem finden kämpfe auf einer separaten map statt.

ich hab jetz das problem, dass manchmal der kampf vorbei ist und es ist noch irgendein CE aktiv. meistens ist das dann irgendne auswahl, zB die items oder meist das kampfmenü, allerdings ohne grafik. das scheint daran zu liegen, das eben nur der teil, an dem das event zuletzt war, noch durchläuft. mit ein bisschen enter und esc drücken kann man das dann meist beenden und das event called dann auch nicht mehr das nächste, aber ich würde schon gern wissen, woran das liegt bzw.:

wie gewähleistet man, dass ein CE nach dem kampf auf jeden fall beendet ist? kann man etwas im event selbst so einstellen oder gibt es vlt auch einen "letzten befehl", den man vor dem mapübergang anbringt, der alles beendet?

Morden
17.05.2013, 16:19
Heyo.
Deine ganzen CommonEvent's, die du dort ansprichst; die callst du alle nacheinander, ja?

Im ganz Allgemeinen würde ich das mit einer einfachen Abfrage eines Switches realisieren. Ist dieser an, soll das Skript per Label ans Ende von sich springen. Danach beendet sich dann der Call des CE's.

Corti
17.05.2013, 16:33
Das Problem lässt sich auch so beschreiben.


"Hilfe, ich weiss nicht, was mein Code tut."


Die Antwort lautet: Find es raus. Du hast das System erstellt, du weisst, was es tun sollte. Also pack MessageBoxen rein und lass dir bescheid geben wenn das Script an gewissen Stellen vorbei schaut. Wenn es das nicht genau so tut wie du es geplant hast dann hast du einen Fehler im System. Mit F9 kommt man in die Debugkonsole,dort kannst du nachschauen was gerade in deinen Variablen drin ist. Und dann heisst es debuggen. MessageBoxen setzen und Stück für Stück genauestens prüfen, was wann aufgerufen wird.

Btw. CE, die sich "gegenseitig callen" ...? Beenden die sich auch irgendwann wieder oder ist das so was


CE1 ruft CE2 ruft CE3 ruft CE2 ruft CE1 ruft wieder CE2 ...?


CommonEvents sind nicht wiedereintrittsfähig (http://de.wikipedia.org/wiki/Eintrittsinvarianz), du darfst also nie ein CE aufrufen, wenn du dieses anderswo nicht sauber beendet hast. Also:

Nie durch parallele Prozesse, Autostart etc. gleichzeitig, vielleicht gleichzeitig oder gehofft nicht gleichzeitig
Niemals in Form von Rekursion oder indirekter "Rekursion" weil du deine CE-Aufrufe weiter stapelst aber nie sauber beendest.


Wenn du an irgendeiner Stelle nicht genau weisst was dein System tut hast du verloren. Fang damit an genau das rauszufinden.

IndependentArt
17.05.2013, 21:23
Deine ganzen CommonEvent's, die du dort ansprichst; die callst du alle nacheinander, ja?

Im ganz Allgemeinen würde ich das mit einer einfachen Abfrage eines Switches realisieren. Ist dieser an, soll das Skript per Label ans Ende von sich springen. Danach beendet sich dann der Call des CE's.

das ist bei mir wohl der switch "kampf läuft". der ist in so ziemlich jedem CE. wenn der mapwechsel erfolgt, ist er off, isofern sollte eig auch kein call mehr erfolgen. erfolgt im grunde auch nicht, die events scheinen eher so zwischendrin stecken geblieben und dann am ende noch auszulaufen.

meine callstruktur sieht ungefähr so aus:

ATB EVENT ruft KAMPFMENÜ ruft GEGNERAUSWAHL ruft SKILL ruft ATB EVENT

(ich hab das zunächst 1:1 von serges ks übernommen gehabt, da called sich das ATB EVENT selbst, lies den eventstack aber ziemlich schnell voll werden, deswegen hat es jetzt ein label)

dabei ist nach jedem call der nächste befehl ein jump to label, welcher das event ans ende springen lässt, sodass die events dann theoretisch auslaufen sollten.


CommonEvents sind nicht wiedereintrittsfähig

hab ich nicht vor zu verursachen aber was sollte passieren?

Rettan
18.05.2013, 09:43
ATB EVENT ruft KAMPFMENÜ ruft GEGNERAUSWAHL ruft SKILL ruft ATB EVENT
[...]
hab ich nicht vor zu verursachen aber was sollte passieren?

Haste aber genau hier versucht.
1. Wird dein Stack hier früher oder später auch voll laufen, weil das alte ATB-Event immer noch vorhanden ist, wenn das neue aufgerufen wird. (Alles dazwischen ebenfalls)
2. Werden deine ganzen Events nie sauber beendet, wenn sie ein neues aufrufen. Sauber beendet sind sie nur dann, wenn sie bis zum Schluss durchlaufen.
3. Wäre es besser in deinem ATB-Event eine Schleife zu bauen und alles da rein zu setzen. Das ATB-Event ist quasi das zentrale Element und darf nur ein einziges mal aufgerufen werden, zum Kampfbeginn. Dann nie wieder. Indem du hier das zweite mal ATB-Event aufrufst, hast du einen Wiedereintritt versucht.

Besser wäre folgender Ablauf:
Kampfbeginn ruft ATB-Event mit Schleife
ATB-Event ruft Kampfmenü ruft ... beendet, Kampfmenü beendet
ATB-Event läuft von vorne

Corti
18.05.2013, 10:13
das ist bei mir wohl der switch "kampf läuft". der ist in so ziemlich jedem CE. wenn der mapwechsel erfolgt, ist er off, isofern sollte eig auch kein call mehr erfolgen. erfolgt im grunde auch nicht, die events scheinen eher so zwischendrin stecken geblieben und dann am ende noch auszulaufen.
Du kannst nicht wissen oder beeinflussen wie viel der Maker noch macht zwischen dem "off setzen" des Switch und dem Beenden. Sauberer wäre es nicht, dass Switch "Off" zu setzen, sondern ein Switch zu setzen, dass im Evencode dazu führt, dass die Funktion sich selbst beendet, also durchläuft bis auf die unterste Ebene der Aufrufe und dort das Switch "off" setzt.

Rettan hat insofern recht, das eine Hauptschleife das sinnvollere Design wäre.

Dein Variante

ATB EVENT ruft KAMPFMENÜ ruft GEGNERAUSWAHL ruft SKILL ruft ATB EVENT
zu ersetzen mit :

ATB EVENT ruft KAMPFMENÜ ruft GEGNERAUSWAHL ruft SKILL .. dann Stack auflösen und beenden bis um ursprünglichen Atb-Event.

IndependentArt
18.05.2013, 13:03
ich verstehe, was ihr meint.

aber wie genau lass ich es so auslaufen, dass ich es dann auch wieder aufgreifen kann?

könnte ich zB statt dem call einen swicht machen, der ein PP event betätigt, welches das ATB called?


dass im Evencode dazu führt, dass die Funktion sich selbst beendet, also durchläuft bis auf die unterste Ebene der Aufrufe und dort das Switch "off" setzt.

ich verstehe leider nicht genau, was damit gemeint ist. den code zwischendrin zu beenden, geht ja schlecht.

Corti
18.05.2013, 14:27
Also:

Du brauchst genau ein einziges PP oder Autostart, nur eines und das ist deine Hauptschleife. Für Unterfunktionen überall PPs machen, macht es komplizierter weil du zwischen ihnen synchronisieren musst.Mach das so wenig wie möglich, je sequenzieller dein Code ist, desto einfacher fällt es die Funktion zu überprüfen und Fehler zu finden.


Common Event "Hauptschleife" [Switch:001(KS läuft)]: ParallelProcess

Initialisierung, alles was nur einmal beim Kampfbeginn passiert. Wahlweise auch ein CE in dem das passiert, dadurch hälst du diesen CE übersichtlich
Label X
Aufruf CE(z.B. Anzeigen aktualisieren)
Aufruf CE( Bestimmen, wer dran ist)
Aufruf CE( Kampfhandlung für Teilnehmer, der an der Reihe ist)
Aufruf CE(Sind noch Feinde/Helden am Leben?)
Bedingung: Wenn Switch:002(Beende KS)=Off dann: Jump to Label X // Wenn der Kampf nicht vorbei ist, springe wieder nach oben
Entladen, alles was am Ende eines Kampfes passieren muss. ( Grafiken wegräumen etc. )
Switch:002(Beende KS) = Off
Switch:001(KS läuft)=Off // Letzte Aktion, das Event deaktiviert sich selbst



Der Kniff besteht nun daraus, dass dein CE "Bestimmen, wer dran ist" nicht das CE für die Kampfhandlung aufruft, sondern nur rausfindet und hinterlegt, wer dran ist. Dann läuft das CE durch und die Hauptschleife startet die Kampfhandlung Kampfteilnehmers. Darin kannst du dann wenn es ein Held ist die Zielauswahl, die Skillauswahl, Animation anzeigen und Schaden ebrechnen etc. machen



ich verstehe leider nicht genau, was damit gemeint ist. den code zwischendrin zu beenden, geht ja schlecht.
Das Switch, an das der PP/Autostart gebunden ist wird in dem Beispiel in der allerletzten Zeile auf Off gesetzt. Kein anderer Code darf das tun. In der Hauptschleife kann man dann einen CE machen wie im Beispiel CE"(Sind noch Feinde/Helden am Leben?)". Ein Gewonnen/Gameover-Check. Der Kampf ist ja dann zuende wenn entweder alle Monster oder Helden tot sind. In dem CE wird dann Switch:002(Beende KS) auf On gesetzt. Das ist der Befehl an die Hauptschleife, das Kampfsystem zu beenden. Anstatt nun wieder nach oben zu springen läuft der Code nach unten durch. Du kannst noch Grafiken entladen, oder wenn der Kampf gewonnen wurde Exp und Items verteilen, solche Dinge. Als allerletzte Zeile deaktiviert sich der CE selbst. Nur so kannst du ganz sicher sein in welchem Zustand das System ausläuft.

IndependentArt
19.05.2013, 16:03
bin dann grad dabei, es umzustellen, was mal wieder in einer von diesen größeren umstrukturierungsaktionen mündet, wo man versucht nichts zu vergessen ^^

danke für die hilfe.

Corti
19.05.2013, 22:58
Wenn du dieses Tool noch nicht hast:
http://www.multimediaxis.de/threads/104052-Entdeckt-HOT-STUFF

Lerne es zu benutzen ist sehr einfach und simpel in der Handhabung und pures Gold.

IndependentArt
20.05.2013, 21:37
Nach Switches, Variablen (auch bei Pointern und in Event Start Conditions!), Events, Texten, Dateinamen (!), Eventnamen suchen - mit vielen Suchoptionen

du beziehst dich in dem fall wohl auf die suchfunktionen? ^^

edit: hattest wieder mal recht ;)