feat(game): use Stage & Table to render the UI.

This commit is contained in:
2025-09-30 10:23:46 +07:00
parent c47a0c9152
commit 2e5e260a0a
4 changed files with 38 additions and 8 deletions

View File

@ -1,8 +1,11 @@
package org.vibecoders.moongazer; package org.vibecoders.moongazer;
import com.badlogic.gdx.ApplicationAdapter; import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.utils.viewport.ScreenViewport;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -14,7 +17,10 @@ public class Game extends ApplicationAdapter {
public static State state = State.INTRO; public static State state = State.INTRO;
public static Transition transition = null; public static Transition transition = null;
SpriteBatch batch; SpriteBatch batch;
Texture logo; // UI stage
public Stage stage;
public Table root;
// Scenes
Scene currentScene; Scene currentScene;
Scene introScene; Scene introScene;
public static Scene mainMenuScene; public static Scene mainMenuScene;
@ -25,7 +31,14 @@ public class Game extends ApplicationAdapter {
Assets.loadIntroAndWait(); Assets.loadIntroAndWait();
log.info("Intro assets loaded successfully."); log.info("Intro assets loaded successfully.");
batch = new SpriteBatch(); batch = new SpriteBatch();
currentScene = introScene = new Intro(); // Stage for UI elements
stage = new Stage(new ScreenViewport(), batch);
Gdx.input.setInputProcessor(stage);
root = new Table();
root.setFillParent(true);
stage.addActor(root);
// Scene initialization
currentScene = introScene = new Intro(this);
// By the end of the intro, the main menu scene will be created and assigned to Game.mainMenuScene // By the end of the intro, the main menu scene will be created and assigned to Game.mainMenuScene
} }
@ -36,6 +49,9 @@ public class Game extends ApplicationAdapter {
batch.begin(); batch.begin();
transition.render(batch); transition.render(batch);
batch.end(); batch.end();
// Handle stage drawing for UI elements
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
return; return;
} }
switch (Game.state) { switch (Game.state) {
@ -54,6 +70,9 @@ public class Game extends ApplicationAdapter {
batch.begin(); batch.begin();
currentScene.render(batch); currentScene.render(batch);
batch.end(); batch.end();
// Handle stage drawing for UI elements
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
} }
@Override @Override
@ -61,6 +80,8 @@ public class Game extends ApplicationAdapter {
introScene.dispose(); introScene.dispose();
mainMenuScene.dispose(); mainMenuScene.dispose();
Assets.dispose(); Assets.dispose();
batch.dispose();
stage.dispose();
log.debug("Resources disposed"); log.debug("Resources disposed");
} }
} }

View File

@ -16,13 +16,15 @@ import com.badlogic.gdx.utils.ScreenUtils;
*/ */
public class Intro extends Scene { public class Intro extends Scene {
private Texture logo; private Texture logo;
private Game game;
private long startTime; private long startTime;
private long endTime = 0; private long endTime = 0;
/** /**
* Initializes the intro scene, starts loading assets. * Initializes the intro scene, starts loading assets.
*/ */
public Intro() { public Intro(Game game) {
this.game = game;
logo = Assets.getAsset("icons/logo.png", Texture.class); logo = Assets.getAsset("icons/logo.png", Texture.class);
startTime = System.currentTimeMillis() + 500; startTime = System.currentTimeMillis() + 500;
log.info("Starting to load all remaining assets..."); log.info("Starting to load all remaining assets...");
@ -38,7 +40,7 @@ public class Intro extends Scene {
if (System.currentTimeMillis() > endTime + 2000 && endTime != 0) { if (System.currentTimeMillis() > endTime + 2000 && endTime != 0) {
if (Game.transition == null) { if (Game.transition == null) {
Assets.waitUntilLoaded(); Assets.waitUntilLoaded();
Game.mainMenuScene = new MainMenu(); Game.mainMenuScene = new MainMenu(game);
Game.transition = new Transition(this, Game.mainMenuScene, State.MAIN_MENU, 1000); Game.transition = new Transition(this, Game.mainMenuScene, State.MAIN_MENU, 1000);
} }
batch.draw(TEXTURE_BLACK, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT); batch.draw(TEXTURE_BLACK, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);

View File

@ -3,6 +3,7 @@ package org.vibecoders.moongazer.scenes;
import static org.vibecoders.moongazer.Constants.*; import static org.vibecoders.moongazer.Constants.*;
import org.vibecoders.moongazer.managers.Assets; import org.vibecoders.moongazer.managers.Assets;
import org.vibecoders.moongazer.Game;
import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.g2d.SpriteBatch;
@ -15,11 +16,12 @@ import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle;
public class MainMenu extends Scene { public class MainMenu extends Scene {
Label textLabel; Label textLabel;
public MainMenu() { public MainMenu(Game game) {
super(); super(game);
var font = Assets.getFont("ui", 24); var font = Assets.getFont("ui", 24);
textLabel = new Label("Moongazer", new LabelStyle(font, Color.BLACK)); textLabel = new Label("Moongazer", new LabelStyle(font, Color.BLACK));
textLabel.setPosition(WINDOW_WIDTH / 2f - textLabel.getWidth() / 2f, WINDOW_HEIGHT / 2f - textLabel.getHeight() / 2f); textLabel.setPosition(WINDOW_WIDTH / 2f - textLabel.getWidth() / 2f, WINDOW_HEIGHT / 2f - textLabel.getHeight() / 2f);
game.root.addActor(textLabel);
} }
/** /**
* Renders the main menu scene. * Renders the main menu scene.
@ -28,6 +30,7 @@ public class MainMenu extends Scene {
@Override @Override
public void render(SpriteBatch batch) { public void render(SpriteBatch batch) {
batch.draw(TEXTURE_WHITE, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT); batch.draw(TEXTURE_WHITE, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
textLabel.draw(batch, 1.0f); // Unneeded as using Scene2D Stage to render the label
// textLabel.draw(batch, 1.0f);
} }
} }

View File

@ -1,12 +1,16 @@
package org.vibecoders.moongazer.scenes; package org.vibecoders.moongazer.scenes;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.vibecoders.moongazer.Game;
import org.vibecoders.moongazer.managers.Assets; import org.vibecoders.moongazer.managers.Assets;
import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.g2d.SpriteBatch;
public abstract class Scene { public abstract class Scene {
protected final Logger log = org.slf4j.LoggerFactory.getLogger(getClass()); protected final Logger log = org.slf4j.LoggerFactory.getLogger(getClass());
public Scene(Game game) {
this();
}
public Scene() { public Scene() {
if (!Assets.isLoadedAll() && Assets.isStartLoadAll()) { if (!Assets.isLoadedAll() && Assets.isStartLoadAll()) {
Assets.waitUntilLoaded(); Assets.waitUntilLoaded();