From e19259c2c4e7e855917937fb5cd408160a200e8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=E1=BA=BF=20H=C6=B0ng?= Date: Tue, 30 Sep 2025 11:36:42 +0700 Subject: [PATCH] fix: do not render invisible Scene and their root Table --- .../java/org/vibecoders/moongazer/Game.java | 27 ++++++++++++++++--- .../vibecoders/moongazer/scenes/Intro.java | 8 +++--- .../vibecoders/moongazer/scenes/MainMenu.java | 3 ++- .../vibecoders/moongazer/scenes/Scene.java | 3 +++ .../moongazer/scenes/Transition.java | 12 ++++++--- 5 files changed, 42 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/org/vibecoders/moongazer/Game.java b/app/src/main/java/org/vibecoders/moongazer/Game.java index 7dbd0cb..c7ab57e 100644 --- a/app/src/main/java/org/vibecoders/moongazer/Game.java +++ b/app/src/main/java/org/vibecoders/moongazer/Game.java @@ -7,6 +7,8 @@ import com.badlogic.gdx.scenes.scene2d.Stage; import com.badlogic.gdx.scenes.scene2d.ui.Table; import com.badlogic.gdx.utils.viewport.ScreenViewport; +import java.util.ArrayList; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.vibecoders.moongazer.managers.Assets; @@ -14,8 +16,8 @@ import org.vibecoders.moongazer.scenes.*; public class Game extends ApplicationAdapter { private static final Logger log = LoggerFactory.getLogger(Game.class); - public static State state = State.INTRO; - public static Transition transition = null; + public State state = State.INTRO; + public Transition transition = null; SpriteBatch batch; // UI stage public Stage stage; @@ -23,7 +25,8 @@ public class Game extends ApplicationAdapter { // Scenes Scene currentScene; Scene introScene; - public static Scene mainMenuScene; + public Scene mainMenuScene; + public ArrayList gameScenes; @Override public void create() { @@ -38,7 +41,9 @@ public class Game extends ApplicationAdapter { root.setFillParent(true); stage.addActor(root); // Scene initialization + gameScenes = new ArrayList<>(); currentScene = introScene = new Intro(this); + gameScenes.add(introScene); // By the end of the intro, the main menu scene will be created and assigned to Game.mainMenuScene } @@ -54,7 +59,7 @@ public class Game extends ApplicationAdapter { stage.draw(); return; } - switch (Game.state) { + switch (this.state) { case INTRO: currentScene = introScene; break; @@ -67,6 +72,20 @@ public class Game extends ApplicationAdapter { default: log.warn("Unknown state: {}", state); } + + for (var scene : gameScenes) { + // log.trace("Checking scene visibility: {}", scene.getClass().getSimpleName()); + if (scene != currentScene && scene.root.isVisible()) { + log.trace("Hiding scene: {}", scene.getClass().getSimpleName()); + scene.root.setVisible(false); + } + } + + if (!currentScene.root.isVisible()) { + log.trace("Showing current scene: {}", currentScene.getClass().getSimpleName()); + currentScene.root.setVisible(true); + } + batch.begin(); currentScene.render(batch); batch.end(); diff --git a/app/src/main/java/org/vibecoders/moongazer/scenes/Intro.java b/app/src/main/java/org/vibecoders/moongazer/scenes/Intro.java index b5cbcb5..028b8b4 100644 --- a/app/src/main/java/org/vibecoders/moongazer/scenes/Intro.java +++ b/app/src/main/java/org/vibecoders/moongazer/scenes/Intro.java @@ -29,6 +29,8 @@ public class Intro extends Scene { startTime = System.currentTimeMillis() + 500; log.info("Starting to load all remaining assets..."); Assets.loadAll(); + game.mainMenuScene = new MainMenu(game); + game.gameScenes.add(game.mainMenuScene); } /** @@ -38,10 +40,10 @@ public class Intro extends Scene { @Override public void render(SpriteBatch batch) { if (System.currentTimeMillis() > endTime + 2000 && endTime != 0) { - if (Game.transition == null) { + if (game.transition == null) { Assets.waitUntilLoaded(); - Game.mainMenuScene = new MainMenu(game); - Game.transition = new Transition(this, Game.mainMenuScene, State.MAIN_MENU, 1000); + log.info("All assets loaded successfully."); + game.transition = new Transition(game, this, game.mainMenuScene, State.MAIN_MENU, 1000); } batch.draw(TEXTURE_BLACK, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT); return; diff --git a/app/src/main/java/org/vibecoders/moongazer/scenes/MainMenu.java b/app/src/main/java/org/vibecoders/moongazer/scenes/MainMenu.java index 66ce7e3..ea075fe 100644 --- a/app/src/main/java/org/vibecoders/moongazer/scenes/MainMenu.java +++ b/app/src/main/java/org/vibecoders/moongazer/scenes/MainMenu.java @@ -21,7 +21,8 @@ public class MainMenu extends Scene { var font = Assets.getFont("ui", 24); textLabel = new Label("Moongazer", new LabelStyle(font, Color.BLACK)); textLabel.setPosition(WINDOW_WIDTH / 2f - textLabel.getWidth() / 2f, WINDOW_HEIGHT / 2f - textLabel.getHeight() / 2f); - game.root.addActor(textLabel); + root.addActor(textLabel); + game.stage.addActor(root); } /** * Renders the main menu scene. diff --git a/app/src/main/java/org/vibecoders/moongazer/scenes/Scene.java b/app/src/main/java/org/vibecoders/moongazer/scenes/Scene.java index 7865bf2..9d793e8 100644 --- a/app/src/main/java/org/vibecoders/moongazer/scenes/Scene.java +++ b/app/src/main/java/org/vibecoders/moongazer/scenes/Scene.java @@ -5,13 +5,16 @@ import org.vibecoders.moongazer.Game; import org.vibecoders.moongazer.managers.Assets; import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.scenes.scene2d.ui.Table; public abstract class Scene { protected final Logger log = org.slf4j.LoggerFactory.getLogger(getClass()); + public Table root; public Scene(Game game) { this(); } public Scene() { + root = new Table(); if (!Assets.isLoadedAll() && Assets.isStartLoadAll()) { Assets.waitUntilLoaded(); } diff --git a/app/src/main/java/org/vibecoders/moongazer/scenes/Transition.java b/app/src/main/java/org/vibecoders/moongazer/scenes/Transition.java index 3309fb2..ab8d63d 100644 --- a/app/src/main/java/org/vibecoders/moongazer/scenes/Transition.java +++ b/app/src/main/java/org/vibecoders/moongazer/scenes/Transition.java @@ -9,6 +9,7 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch; * Handles transitions between scenes with a linear transition effect. */ public class Transition extends Scene { + private Game game; private Scene from; private Scene to; private State targetState; @@ -22,7 +23,10 @@ public class Transition extends Scene { * @param targetState The target state of the game after the transition. * @param duration The duration of the transition in milliseconds. */ - public Transition(Scene from, Scene to, State targetState, long duration) { + public Transition(Game game, Scene from, Scene to, State targetState, long duration) { + // Transition does not need to render UI elements + this.root = null; + this.game = game; this.from = from; this.to = to; this.targetState = targetState; @@ -39,15 +43,17 @@ public class Transition extends Scene { var toOpacity = ((float) (System.currentTimeMillis() - startTime)) / duration; if (toOpacity >= 0.99) { log.trace("Transition complete to state: {}", targetState); - Game.state = targetState; - Game.transition = null; + game.state = targetState; + game.transition = null; return; } var fromOpacity = 1 - toOpacity; log.trace("Transition opacities - from: {}, to: {}", fromOpacity, toOpacity); batch.setColor(1, 1, 1, fromOpacity); + from.root.setVisible(true); from.render(batch); batch.setColor(1, 1, 1, toOpacity); + to.root.setVisible(true); to.render(batch); } }