feat(scene): implement transition

Should work :D
This commit is contained in:
2025-09-30 01:02:46 +07:00
parent c4c8235f45
commit 24f09bf303
5 changed files with 127 additions and 15 deletions

View File

@ -1,18 +1,34 @@
package org.vibecoders.moongazer;
import org.slf4j.Logger;
import com.badlogic.gdx.assets.AssetManager;
import com.badlogic.gdx.graphics.Texture;
public class Assets {
private static final AssetManager assetManager = new AssetManager();
private static final Logger log = org.slf4j.LoggerFactory.getLogger(Assets.class);
public static <T> T getAsset(String fileName, Class<T> type) {
return assetManager.get(fileName, type);
}
public static void loadAll() {
// We load all assets here for simplicity :)
/**
* Loads assets required for the intro scene only.
*
* This is used to load the logo before the main assets are loaded.
*/
public static void loadIntroAndWait() {
assetManager.load("icons/logo.png", Texture.class);
waitUntilLoaded();
}
public static void loadAll() {
log.info("Loading all assets....");
log.warn("stub");
}
public static void waitUntilLoaded() {
assetManager.finishLoading();
}

View File

@ -1,5 +1,9 @@
package org.vibecoders.moongazer;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Texture;
/**
* Client configuration constants and default values
* used throughout the Moongazer client application.
@ -12,4 +16,12 @@ public class Constants {
public static final int WINDOW_WIDTH = 1280;
public static final int WINDOW_HEIGHT = 720;
public static final String WINDOW_TITLE = "Moongazer";
public static final Texture TEXTURE_WHITE = new Texture(new Pixmap(1, 1, Pixmap.Format.RGBA8888) {{
setColor(Color.WHITE);
fill();
}});
public static final Texture TEXTURE_BLACK = new Texture(new Pixmap(1, 1, Pixmap.Format.RGBA8888) {{
setColor(Color.BLACK);
fill();
}});
}

View File

@ -11,28 +11,38 @@ import org.vibecoders.moongazer.scene.*;
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;
SpriteBatch batch;
Texture logo;
Scene currentScene;
Scene introScene;
public static Scene mainMenuScene;
@Override
public void create() {
log.info("Loading assets...");
Assets.loadAll();
log.info("Assets loaded successfully.");
log.info("Loading intro assets...");
Assets.loadIntroAndWait();
log.info("Intro assets loaded successfully.");
batch = new SpriteBatch();
currentScene = introScene = new Intro();
mainMenuScene = new MainMenu();
}
@Override
public void render() {
// Handle transition if any
if (transition != null) {
batch.begin();
transition.render(batch);
batch.end();
return;
}
switch (Game.state) {
case INTRO:
currentScene = introScene;
break;
case MAIN_MENU:
// Render main menu scene
currentScene = mainMenuScene;
break;
case IN_GAME:
// Render in-game scene
@ -48,6 +58,7 @@ public class Game extends ApplicationAdapter {
@Override
public void dispose() {
introScene.dispose();
mainMenuScene.dispose();
Assets.dispose();
log.debug("Resources disposed");
}

View File

@ -1,36 +1,57 @@
package org.vibecoders.moongazer.scene;
import static org.vibecoders.moongazer.Constants.WINDOW_HEIGHT;
import static org.vibecoders.moongazer.Constants.WINDOW_WIDTH;
import static org.vibecoders.moongazer.Constants.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.vibecoders.moongazer.Assets;
import org.vibecoders.moongazer.Game;
import org.vibecoders.moongazer.State;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.utils.ScreenUtils;
/**
* Intro scene displaying the game logo and handling asset loading.
*/
public class Intro extends Scene {
private Texture logo;
private long startTime;
private long endTime = 0;
private static final Logger log = LoggerFactory.getLogger(Intro.class);
/**
* Initializes the intro scene, starts loading assets.
*/
public Intro() {
logo = Assets.getAsset("icons/logo.png", Texture.class);
startTime = System.currentTimeMillis() + 500;
log.info("Starting to load all remaining assets...");
Assets.loadAll();
}
/**
* Renders the intro scene.
* @param batch The SpriteBatch to draw with.
*/
@Override
public void render(SpriteBatch batch) {
if (System.currentTimeMillis() > endTime + 2000 && endTime != 0) {
Assets.waitUntilLoaded();
if (Game.transition == null) {
Game.transition = new Transition(this, Game.mainMenuScene, State.MAIN_MENU, 1000);
}
batch.draw(TEXTURE_BLACK, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
return;
}
ScreenUtils.clear(Color.BLACK);
log.debug("Rendering logo at position: ({}, {})", WINDOW_WIDTH / 2 - logo.getWidth() / 4,
WINDOW_HEIGHT / 2 - logo.getHeight() / 4);
// log.debug("Rendering logo at position: ({}, {})", WINDOW_WIDTH / 2 - logo.getWidth() / 4, WINDOW_HEIGHT / 2 - logo.getHeight() / 4);
var currentOpacity = (float) (System.currentTimeMillis() - startTime) / 1000;
if (currentOpacity > 1) {
if (endTime == 0) {
endTime = System.currentTimeMillis() + 3000;
endTime = System.currentTimeMillis() + 2000;
}
currentOpacity = 1 - ((float) (System.currentTimeMillis() - endTime) / 1000);
}
@ -38,8 +59,4 @@ public class Intro extends Scene {
batch.draw(logo, WINDOW_WIDTH / 2 - logo.getWidth() / 4, WINDOW_HEIGHT / 2 - logo.getHeight() / 4,
logo.getWidth() / 2, logo.getHeight() / 2);
}
public void dispose() {
log.debug("sybau");
}
}

View File

@ -0,0 +1,56 @@
package org.vibecoders.moongazer.scene;
import org.slf4j.Logger;
import org.vibecoders.moongazer.Game;
import org.vibecoders.moongazer.State;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
/**
* Handles transitions between scenes with a linear transition effect.
*/
public class Transition extends Scene {
private Scene from;
private Scene to;
private State targetState;
private long startTime;
private long duration;
private static final Logger log = org.slf4j.LoggerFactory.getLogger(Transition.class);
/**
* Creates a new transition between two scenes.
* @param from The scene to transition from.
* @param to The scene to transition to.
* @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) {
this.from = from;
this.to = to;
this.targetState = targetState;
this.duration = duration;
startTime = System.currentTimeMillis();
}
/**
* Renders the transition effect.
* @param batch The SpriteBatch to draw with.
*/
@Override
public void render(SpriteBatch batch) {
var toOpacity = ((float) (System.currentTimeMillis() - startTime)) / duration;
if (toOpacity >= 0.99) {
log.debug("Transition complete to state: {}", targetState);
Game.state = targetState;
Game.transition = null;
return;
}
var fromOpacity = 1 - toOpacity;
log.debug("Transition opacities - from: {}, to: {}", fromOpacity, toOpacity);
batch.setColor(1, 1, 1, fromOpacity);
from.render(batch);
batch.setColor(1, 1, 1, toOpacity);
to.render(batch);
}
}