JirkaDellOro / FUDGE

Furtwangen University Didactic Game Editor
https://jirkadelloro.github.io/FUDGE
MIT License
33 stars 27 forks source link

Statemachine entfernen #334

Closed KohlerAl closed 2 years ago

KohlerAl commented 2 years ago

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

JirkaDellOro commented 2 years ago

Prüfe mal bitte, ob Zeile 131 aufgerufen, der Loop-Listener also entfernt wird

KohlerAl commented 2 years ago

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...

JirkaDellOro commented 2 years ago

welche Methode hast Du den aufgerufen von der Variablen aus?

KohlerAl commented 2 years ago

Die Überprüfung ob Goomba runtergefallen ist oder nicht. Wenn ja, dann wird die Statemachine in den Sterbezustand versetzt

JirkaDellOro commented 2 years ago

Geschieht das immer wieder, wenn Goombas Position die Schwelle überschritten hat?

KohlerAl commented 2 years ago

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.

JirkaDellOro commented 2 years ago

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.

KohlerAl commented 2 years ago

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

JirkaDellOro commented 2 years ago

Wer ruft denn diese Methode auf?

KohlerAl commented 2 years ago

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();

}

JirkaDellOro commented 2 years ago

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?

KohlerAl commented 2 years ago

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 :)

JirkaDellOro commented 2 years ago

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 sollte

Und 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.

KohlerAl commented 2 years ago

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

JirkaDellOro commented 2 years ago

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

JirkaDellOro commented 2 years ago

korrekt?

KohlerAl commented 2 years ago

Ja, das stimmt, Ich war zwischendurch ziemlich verwirrt, aber ich glaube jetzt hab ichs verstanden