Closed KohlerAl closed 2 years ago
Prüfe mal bitte, ob Zeile 131 aufgerufen, der Loop-Listener also entfernt wird
Zeile 131 wird aufgerufen. Ich bin das ganze von dort aus nochmal im Debugger durchgegangen und ich habe das Problem gefunden. Ich habe den Goomba noch in einer Variablen gespeichert gehabt, an die ich gar nicht mehr gedacht habe. Mit der Variablen wird eine Methode von Goomba aufgerufen. Wenn ich da den Goomba auch lösche dann hört die Konsolenausgabe auf. Wird dann die Statemachine bzw der Goomba nicht richtig gelöscht wegen der Variablen? Oder lebt dann eine Art Geist-Goomba weiter? Weil eigentlich hätte ich damit gerechnet dass da Fehlermeldungen kommen, schließlich habe ich ja den Statemachine-Component von Goomba entfernt...
welche Methode hast Du den aufgerufen von der Variablen aus?
Die Überprüfung ob Goomba runtergefallen ist oder nicht. Wenn ja, dann wird die Statemachine in den Sterbezustand versetzt
Geschieht das immer wieder, wenn Goombas Position die Schwelle überschritten hat?
Goomba ist dann verschwunden, nachdem er aus dem Graph gelöscht wurde. Aber es kamen immer noch kontinuierlich Console.logs aus der Statemachine, dass Goomba tot ist. Die Überprüfung dafür (also ob die y-Position kleiner -5 ist) ist aber in der Goomba-Klasse nicht in der Statemachine. Nur wenn die Bedingung erfüllt ist, wurde der State der Statemachine verändert und die Methode die dann aufgerufen wurde hat die Console.logs verursacht.
Ich nehme an, Du meinst dies:
public update(): void {
if (this.mtxLocal.translation.y < -5) {
this.goombaStatemachine.transit(JOB.DIE);
}
}
Jetzt bleibt mir die Frage, wer wann update aufruft. Goomba hat sich offensichtlich die StateMachine gemerkt und ruft explizit deren transit auf, egal ob sie am Knoten hängt oder nicht. Ich nehme an, die Konsolenausgabe kommt dann im transit. Bitte prüfen.
Genau um den Teil geht es. Der Aufruf kommt aus der update-Funktion in der Main.ts . Die Konsolenausgabe kommt aber nicht aus dem transit sondern aus der Methode die aufgerufen wird wenn der State von Enemy "die" ist
Wer ruft denn diese Methode auf?
Hier ein mal der Listener: ƒ.Loop.addEventListener(ƒ.EVENT.LOOP_FRAME, update);
Und die Update-Funktion aus Main.ts: export function update(_event: Event): void { mario.update(); if (goombas.length > 0) { for (let goomba of goombas) goomba.update(); }
ƒ.Physics.simulate();
viewport.draw();
//ƒ.AudioManager.default.update();
}
Denke an den Grundsatz, dass man möglichst keine Strukturen verdoppeln sollte, da man diese dann synchronisieren muss. Das Goomba-Problem ist nun ein klassisches Beispiel. Geschickter ist es, die Struktur des Graphen zu nutzen und dort über die Goombas zu iterieren, die children sind auch nur ein Array.
Jetzt aber wieder zurück: Main ruft update von Goomba auf, die Methode stößt aber nur ggf. den transit an. Wer aber ruft das update der statemachine noch auf, wenn Goomba tot ist?
Update von Enemy hat einen Listener für Loop_Frame, also wird das da nochmal aufgerufen?
Und ich dachte dass das Programm vielleicht besser läuft wenn ich nur über das Array iteriere anstatt die Goombas immer im Graph zu suchen und dann zu iterieren, aber dann werde ich das noch ändern :)
Update von Enemy hat einen Listener für Loop_Frame, also wird das da nochmal aufgerufen?
Schau das mal im Debugger nach oder schick' mir einen Link zur App. Ich will schon noch rausfinden, ob etwas an der StateMachine geändert werden sollteUnd ich dachte dass das Programm vielleicht besser läuft Wenn Du den Goombs-Parentnode hast, liegen dir dessen children direkt als Array vor, da spart man nichts. Weitere Grundregel insbesondere beim Prototyping: erst lauffähig machen, später optimieren! Verfrühte Optimierung ist sehr teuer und meist überflüssig.
Also für mich sieht das aus als käme das tatsächlich nur von dem Aufruf der update-Methode aus Goomba. Ich hab das im Debugger durchgeklickt und bin nicht in der update-Methode von Enemy gelandet. Aber falls du selbst nochmal schauen möchtest ist hier der Link: https://kohleral.github.io/PRIMA/Super_Mario/index.html
Und das mit dem Array macht auf jeden Fall Sinn
Ich glaube, wir hatten ein Missverständnis. Du schriebst
"Die Konsolenausgabe kommt aber nicht aus dem transit sondern aus der Methode die aufgerufen wird wenn der State von Enemy "die" ist".
Daraus schloss ich, dass die Ausgabe aus einem act
kommt.
Jetzt sehe ich aber, dass auf der Konsole ausgegeben wird "305Enemy.ts:119 Transit to 2" und die Zeile ist in transitDefault
, so wie ich vermutete
korrekt?
Ja, das stimmt, Ich war zwischendurch ziemlich verwirrt, aber ich glaube jetzt hab ichs verstanden
Die Statemachine sorgt weiter für Konsolen-Ausgaben, auch wenn sowhl die Statemachine als auch der Parent-Knoten entfernt wurden. Link zum Statemachine-Script: https://github.com/KohlerAl/PRIMA/blob/main/Super_Mario/Script/Source/Enemy.ts