Merge branch 'main' into button
This commit is contained in:
@ -16,12 +16,4 @@ public class Constants {
|
|||||||
public static final int WINDOW_WIDTH = 1280;
|
public static final int WINDOW_WIDTH = 1280;
|
||||||
public static final int WINDOW_HEIGHT = 720;
|
public static final int WINDOW_HEIGHT = 720;
|
||||||
public static final String WINDOW_TITLE = "Moongazer";
|
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();
|
|
||||||
}});
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,6 +7,8 @@ import com.badlogic.gdx.scenes.scene2d.Stage;
|
|||||||
import com.badlogic.gdx.scenes.scene2d.ui.Table;
|
import com.badlogic.gdx.scenes.scene2d.ui.Table;
|
||||||
import com.badlogic.gdx.utils.viewport.ScreenViewport;
|
import com.badlogic.gdx.utils.viewport.ScreenViewport;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.vibecoders.moongazer.managers.Assets;
|
import org.vibecoders.moongazer.managers.Assets;
|
||||||
@ -14,8 +16,8 @@ import org.vibecoders.moongazer.scenes.*;
|
|||||||
|
|
||||||
public class Game extends ApplicationAdapter {
|
public class Game extends ApplicationAdapter {
|
||||||
private static final Logger log = LoggerFactory.getLogger(Game.class);
|
private static final Logger log = LoggerFactory.getLogger(Game.class);
|
||||||
public static State state = State.INTRO;
|
public State state = State.INTRO;
|
||||||
public static Transition transition = null;
|
public Transition transition = null;
|
||||||
SpriteBatch batch;
|
SpriteBatch batch;
|
||||||
// UI stage
|
// UI stage
|
||||||
public Stage stage;
|
public Stage stage;
|
||||||
@ -23,7 +25,8 @@ public class Game extends ApplicationAdapter {
|
|||||||
// Scenes
|
// Scenes
|
||||||
Scene currentScene;
|
Scene currentScene;
|
||||||
Scene introScene;
|
Scene introScene;
|
||||||
public static Scene mainMenuScene;
|
public Scene mainMenuScene;
|
||||||
|
public ArrayList<Scene> gameScenes;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void create() {
|
public void create() {
|
||||||
@ -38,7 +41,9 @@ public class Game extends ApplicationAdapter {
|
|||||||
root.setFillParent(true);
|
root.setFillParent(true);
|
||||||
stage.addActor(root);
|
stage.addActor(root);
|
||||||
// Scene initialization
|
// Scene initialization
|
||||||
|
gameScenes = new ArrayList<>();
|
||||||
currentScene = introScene = new Intro(this);
|
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
|
// 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();
|
stage.draw();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch (Game.state) {
|
switch (this.state) {
|
||||||
case INTRO:
|
case INTRO:
|
||||||
currentScene = introScene;
|
currentScene = introScene;
|
||||||
break;
|
break;
|
||||||
@ -67,6 +72,20 @@ public class Game extends ApplicationAdapter {
|
|||||||
default:
|
default:
|
||||||
log.warn("Unknown state: {}", state);
|
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();
|
batch.begin();
|
||||||
currentScene.render(batch);
|
currentScene.render(batch);
|
||||||
batch.end();
|
batch.end();
|
||||||
|
|||||||
@ -2,6 +2,8 @@ package org.vibecoders.moongazer;
|
|||||||
|
|
||||||
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application;
|
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application;
|
||||||
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration;
|
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration;
|
||||||
|
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration.GLEmulation;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import static org.vibecoders.moongazer.Constants.*;
|
import static org.vibecoders.moongazer.Constants.*;
|
||||||
@ -20,6 +22,7 @@ public class Main {
|
|||||||
*/
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
Lwjgl3ApplicationConfiguration cfg = new Lwjgl3ApplicationConfiguration();
|
Lwjgl3ApplicationConfiguration cfg = new Lwjgl3ApplicationConfiguration();
|
||||||
|
cfg.setOpenGLEmulation(GLEmulation.GL32, 3, 2);
|
||||||
cfg.setTitle(WINDOW_TITLE);
|
cfg.setTitle(WINDOW_TITLE);
|
||||||
cfg.setWindowedMode(WINDOW_WIDTH, WINDOW_HEIGHT);
|
cfg.setWindowedMode(WINDOW_WIDTH, WINDOW_HEIGHT);
|
||||||
cfg.useVsync(true);
|
cfg.useVsync(true);
|
||||||
|
|||||||
@ -5,6 +5,8 @@ import org.slf4j.Logger;
|
|||||||
import com.badlogic.gdx.assets.AssetManager;
|
import com.badlogic.gdx.assets.AssetManager;
|
||||||
import com.badlogic.gdx.assets.loaders.FileHandleResolver;
|
import com.badlogic.gdx.assets.loaders.FileHandleResolver;
|
||||||
import com.badlogic.gdx.assets.loaders.resolvers.InternalFileHandleResolver;
|
import com.badlogic.gdx.assets.loaders.resolvers.InternalFileHandleResolver;
|
||||||
|
import com.badlogic.gdx.graphics.Color;
|
||||||
|
import com.badlogic.gdx.graphics.Pixmap;
|
||||||
import com.badlogic.gdx.graphics.Texture;
|
import com.badlogic.gdx.graphics.Texture;
|
||||||
import com.badlogic.gdx.graphics.g2d.BitmapFont;
|
import com.badlogic.gdx.graphics.g2d.BitmapFont;
|
||||||
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGeneratorLoader;
|
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGeneratorLoader;
|
||||||
@ -19,9 +21,21 @@ public class Assets {
|
|||||||
private static final ArrayList<String> loadedFonts = new ArrayList<>();
|
private static final ArrayList<String> loadedFonts = new ArrayList<>();
|
||||||
private static boolean startLoadAll = false;
|
private static boolean startLoadAll = false;
|
||||||
private static boolean loadedAll = false;
|
private static boolean loadedAll = false;
|
||||||
|
private static Texture textureWhite;
|
||||||
|
private static Texture textureBlack;
|
||||||
|
|
||||||
public static <T> T getAsset(String fileName, Class<T> type) {
|
public static <T> T getAsset(String fileName, Class<T> type) {
|
||||||
|
try {
|
||||||
|
if (!assetManager.isLoaded(fileName, type)) {
|
||||||
|
log.warn("Asset not loaded: {}", fileName);
|
||||||
|
assetManager.load(fileName, type);
|
||||||
|
assetManager.finishLoadingAsset(fileName);
|
||||||
|
}
|
||||||
return assetManager.get(fileName, type);
|
return assetManager.get(fileName, type);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Failed to load asset: {}", fileName, e);
|
||||||
|
throw new RuntimeException("Asset loading failed: " + fileName, e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -71,6 +85,9 @@ public class Assets {
|
|||||||
assetManager.setLoader(com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator.class,
|
assetManager.setLoader(com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator.class,
|
||||||
new FreeTypeFontGeneratorLoader(resolver));
|
new FreeTypeFontGeneratorLoader(resolver));
|
||||||
assetManager.setLoader(BitmapFont.class, ".ttf", new FreetypeFontLoader(resolver));
|
assetManager.setLoader(BitmapFont.class, ".ttf", new FreetypeFontLoader(resolver));
|
||||||
|
// Load all assets here
|
||||||
|
assetManager.load("textures/main_menu/background.png", Texture.class);
|
||||||
|
assetManager.load("textures/main_menu/title.png", Texture.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isLoadedAll() {
|
public static boolean isLoadedAll() {
|
||||||
@ -83,8 +100,7 @@ public class Assets {
|
|||||||
|
|
||||||
public static void waitUntilLoaded() {
|
public static void waitUntilLoaded() {
|
||||||
assetManager.finishLoading();
|
assetManager.finishLoading();
|
||||||
if (startLoadAll) {
|
if (startLoadAll) {;
|
||||||
log.info("All assets loaded.");
|
|
||||||
loadedAll = true;
|
loadedAll = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -93,7 +109,37 @@ public class Assets {
|
|||||||
return assetManager;
|
return assetManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Texture getWhiteTexture() {
|
||||||
|
if (textureWhite == null) {
|
||||||
|
Pixmap pixmap = new Pixmap(1, 1, Pixmap.Format.RGBA8888);
|
||||||
|
pixmap.setColor(Color.WHITE);
|
||||||
|
pixmap.fill();
|
||||||
|
textureWhite = new Texture(pixmap);
|
||||||
|
pixmap.dispose(); // Important: dispose pixmap after creating texture
|
||||||
|
}
|
||||||
|
return textureWhite;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Texture getBlackTexture() {
|
||||||
|
if (textureBlack == null) {
|
||||||
|
Pixmap pixmap = new Pixmap(1, 1, Pixmap.Format.RGBA8888);
|
||||||
|
pixmap.setColor(Color.BLACK);
|
||||||
|
pixmap.fill();
|
||||||
|
textureBlack = new Texture(pixmap);
|
||||||
|
pixmap.dispose();
|
||||||
|
}
|
||||||
|
return textureBlack;
|
||||||
|
}
|
||||||
|
|
||||||
public static void dispose() {
|
public static void dispose() {
|
||||||
assetManager.dispose();
|
assetManager.dispose();
|
||||||
|
if (textureWhite != null) {
|
||||||
|
textureWhite.dispose();
|
||||||
|
textureWhite = null;
|
||||||
|
}
|
||||||
|
if (textureBlack != null) {
|
||||||
|
textureBlack.dispose();
|
||||||
|
textureBlack = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,6 +29,8 @@ public class Intro extends Scene {
|
|||||||
startTime = System.currentTimeMillis() + 500;
|
startTime = System.currentTimeMillis() + 500;
|
||||||
log.info("Starting to load all remaining assets...");
|
log.info("Starting to load all remaining assets...");
|
||||||
Assets.loadAll();
|
Assets.loadAll();
|
||||||
|
game.mainMenuScene = new MainMenu(game);
|
||||||
|
game.gameScenes.add(game.mainMenuScene);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -38,12 +40,12 @@ public class Intro extends Scene {
|
|||||||
@Override
|
@Override
|
||||||
public void render(SpriteBatch batch) {
|
public void render(SpriteBatch batch) {
|
||||||
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);
|
log.info("All assets loaded successfully.");
|
||||||
Game.transition = new Transition(this, Game.mainMenuScene, State.MAIN_MENU, 1000);
|
game.transition = new Transition(game, this, game.mainMenuScene, State.MAIN_MENU, 1000);
|
||||||
}
|
}
|
||||||
batch.draw(TEXTURE_BLACK, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
|
batch.draw(Assets.getBlackTexture(), 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ScreenUtils.clear(Color.BLACK);
|
ScreenUtils.clear(Color.BLACK);
|
||||||
|
|||||||
@ -11,15 +11,19 @@ import org.vibecoders.moongazer.managers.Assets;
|
|||||||
import org.vibecoders.moongazer.Game;
|
import org.vibecoders.moongazer.Game;
|
||||||
|
|
||||||
import com.badlogic.gdx.graphics.Color;
|
import com.badlogic.gdx.graphics.Color;
|
||||||
|
import com.badlogic.gdx.graphics.Texture;
|
||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Label;
|
import com.badlogic.gdx.scenes.scene2d.ui.Label;
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle;
|
import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle;
|
||||||
|
|
||||||
/**
|
|
||||||
* Main menu scene.
|
|
||||||
*/
|
|
||||||
public class MainMenu extends Scene {
|
public class MainMenu extends Scene {
|
||||||
Label textLabel;
|
private Label newGameLabel;
|
||||||
|
private Label loadGameLabel;
|
||||||
|
private Label settingsLabel;
|
||||||
|
private Label quitGameLabel;
|
||||||
|
|
||||||
|
private Texture backgroundTexture;
|
||||||
|
private Texture titleTexture;
|
||||||
|
|
||||||
public MainMenu(Game game) {
|
public MainMenu(Game game) {
|
||||||
super(game);
|
super(game);
|
||||||
@ -82,14 +86,24 @@ public class MainMenu extends Scene {
|
|||||||
game.root.addActor(settingsButton.getActor());
|
game.root.addActor(settingsButton.getActor());
|
||||||
game.root.addActor(exitButton.getActor());
|
game.root.addActor(exitButton.getActor());
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* Renders the main menu scene.
|
|
||||||
* @param batch The SpriteBatch to draw with.
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void render(SpriteBatch batch) {
|
public void render(SpriteBatch batch) {
|
||||||
batch.draw(TEXTURE_WHITE, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
|
batch.draw(backgroundTexture, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
|
||||||
// Unneeded as using Scene2D Stage to render the label
|
|
||||||
// textLabel.draw(batch, 1.0f);
|
float targetTitleWidth = 300f;
|
||||||
|
float originalWidth = titleTexture.getWidth();
|
||||||
|
float originalHeight = titleTexture.getHeight();
|
||||||
|
float scale = targetTitleWidth / originalWidth;
|
||||||
|
float titleWidth = originalWidth * scale;
|
||||||
|
float titleHeight = originalHeight * scale;
|
||||||
|
float titleX = (WINDOW_WIDTH - titleWidth) / 2f;
|
||||||
|
float titleY = WINDOW_HEIGHT * 0.58f;
|
||||||
|
batch.draw(titleTexture, titleX, titleY, titleWidth, titleHeight);
|
||||||
|
|
||||||
|
newGameLabel.draw(batch, 1.0f);
|
||||||
|
loadGameLabel.draw(batch, 1.0f);
|
||||||
|
settingsLabel.draw(batch, 1.0f);
|
||||||
|
quitGameLabel.draw(batch, 1.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5,13 +5,16 @@ 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;
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.ui.Table;
|
||||||
|
|
||||||
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 Table root;
|
||||||
public Scene(Game game) {
|
public Scene(Game game) {
|
||||||
this();
|
this();
|
||||||
}
|
}
|
||||||
public Scene() {
|
public Scene() {
|
||||||
|
root = new Table();
|
||||||
if (!Assets.isLoadedAll() && Assets.isStartLoadAll()) {
|
if (!Assets.isLoadedAll() && Assets.isStartLoadAll()) {
|
||||||
Assets.waitUntilLoaded();
|
Assets.waitUntilLoaded();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
|||||||
* Handles transitions between scenes with a linear transition effect.
|
* Handles transitions between scenes with a linear transition effect.
|
||||||
*/
|
*/
|
||||||
public class Transition extends Scene {
|
public class Transition extends Scene {
|
||||||
|
private Game game;
|
||||||
private Scene from;
|
private Scene from;
|
||||||
private Scene to;
|
private Scene to;
|
||||||
private State targetState;
|
private State targetState;
|
||||||
@ -22,7 +23,10 @@ public class Transition extends Scene {
|
|||||||
* @param targetState The target state of the game after the transition.
|
* @param targetState The target state of the game after the transition.
|
||||||
* @param duration The duration of the transition in milliseconds.
|
* @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.from = from;
|
||||||
this.to = to;
|
this.to = to;
|
||||||
this.targetState = targetState;
|
this.targetState = targetState;
|
||||||
@ -39,15 +43,17 @@ public class Transition extends Scene {
|
|||||||
var toOpacity = ((float) (System.currentTimeMillis() - startTime)) / duration;
|
var toOpacity = ((float) (System.currentTimeMillis() - startTime)) / duration;
|
||||||
if (toOpacity >= 0.99) {
|
if (toOpacity >= 0.99) {
|
||||||
log.trace("Transition complete to state: {}", targetState);
|
log.trace("Transition complete to state: {}", targetState);
|
||||||
Game.state = targetState;
|
game.state = targetState;
|
||||||
Game.transition = null;
|
game.transition = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var fromOpacity = 1 - toOpacity;
|
var fromOpacity = 1 - toOpacity;
|
||||||
log.trace("Transition opacities - from: {}, to: {}", fromOpacity, toOpacity);
|
log.trace("Transition opacities - from: {}, to: {}", fromOpacity, toOpacity);
|
||||||
batch.setColor(1, 1, 1, fromOpacity);
|
batch.setColor(1, 1, 1, fromOpacity);
|
||||||
|
from.root.setVisible(true);
|
||||||
from.render(batch);
|
from.render(batch);
|
||||||
batch.setColor(1, 1, 1, toOpacity);
|
batch.setColor(1, 1, 1, toOpacity);
|
||||||
|
to.root.setVisible(true);
|
||||||
to.render(batch);
|
to.render(batch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
app/src/main/resources/textures/main_menu/background.png
Normal file
BIN
app/src/main/resources/textures/main_menu/background.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 574 KiB |
BIN
app/src/main/resources/textures/main_menu/title.png
Normal file
BIN
app/src/main/resources/textures/main_menu/title.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 MiB |
Reference in New Issue
Block a user