add basic MVVM setup
This commit is contained in:
@@ -2,6 +2,7 @@ package io.github.com.quillraven.audio;
|
|||||||
|
|
||||||
import com.badlogic.gdx.audio.Music;
|
import com.badlogic.gdx.audio.Music;
|
||||||
import com.badlogic.gdx.maps.tiled.TiledMap;
|
import com.badlogic.gdx.maps.tiled.TiledMap;
|
||||||
|
import com.badlogic.gdx.math.MathUtils;
|
||||||
import io.github.com.quillraven.asset.AssetService;
|
import io.github.com.quillraven.asset.AssetService;
|
||||||
import io.github.com.quillraven.asset.MusicAsset;
|
import io.github.com.quillraven.asset.MusicAsset;
|
||||||
|
|
||||||
@@ -10,11 +11,34 @@ public class AudioService {
|
|||||||
private final AssetService assetService;
|
private final AssetService assetService;
|
||||||
private Music currentMusic;
|
private Music currentMusic;
|
||||||
private MusicAsset currentMusicAsset;
|
private MusicAsset currentMusicAsset;
|
||||||
|
private float musicVolume;
|
||||||
|
private float soundVolume;
|
||||||
|
|
||||||
public AudioService(AssetService assetService) {
|
public AudioService(AssetService assetService) {
|
||||||
this.assetService = assetService;
|
this.assetService = assetService;
|
||||||
this.currentMusic = null;
|
this.currentMusic = null;
|
||||||
this.currentMusicAsset = null;
|
this.currentMusicAsset = null;
|
||||||
|
this.musicVolume = 0.5f;
|
||||||
|
this.soundVolume = 0.33f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMusicVolume(float volume) {
|
||||||
|
this.musicVolume = MathUtils.clamp(volume, 0f, 1f);
|
||||||
|
if (this.currentMusic != null) {
|
||||||
|
this.currentMusic.setVolume(volume);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getMusicVolume() {
|
||||||
|
return musicVolume;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSoundVolume(float soundVolume) {
|
||||||
|
this.soundVolume = MathUtils.clamp(soundVolume, 0f, 1f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getSoundVolume() {
|
||||||
|
return soundVolume;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void playMusic(MusicAsset musicAsset) {
|
public void playMusic(MusicAsset musicAsset) {
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ public class GameScreen extends ScreenAdapter {
|
|||||||
this.physicWorld = new World(Vector2.Zero, true);
|
this.physicWorld = new World(Vector2.Zero, true);
|
||||||
this.physicWorld.setAutoClearForces(false);
|
this.physicWorld.setAutoClearForces(false);
|
||||||
this.engine = new Engine();
|
this.engine = new Engine();
|
||||||
this.tiledAshleySpawner = new TiledAshleySpawner(this.engine, this.physicWorld);
|
this.tiledAshleySpawner = new TiledAshleySpawner(this.engine, this.physicWorld, this.game.getAssetService());
|
||||||
ImmutableArray<Entity> controllerEntities = this.engine.getEntitiesFor(Family.all(Controller.class).get());
|
ImmutableArray<Entity> controllerEntities = this.engine.getEntitiesFor(Family.all(Controller.class).get());
|
||||||
this.keyboardController = new KeyboardController(GameControllerState.class, controllerEntities);
|
this.keyboardController = new KeyboardController(GameControllerState.class, controllerEntities);
|
||||||
|
|
||||||
|
|||||||
@@ -1,22 +1,15 @@
|
|||||||
package io.github.com.quillraven.screen;
|
package io.github.com.quillraven.screen;
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx;
|
|
||||||
import com.badlogic.gdx.InputMultiplexer;
|
import com.badlogic.gdx.InputMultiplexer;
|
||||||
import com.badlogic.gdx.ScreenAdapter;
|
import com.badlogic.gdx.ScreenAdapter;
|
||||||
import com.badlogic.gdx.scenes.scene2d.InputEvent;
|
|
||||||
import com.badlogic.gdx.scenes.scene2d.Stage;
|
import com.badlogic.gdx.scenes.scene2d.Stage;
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Image;
|
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Label;
|
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.ProgressBar;
|
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
|
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Table;
|
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
|
|
||||||
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
|
|
||||||
import com.badlogic.gdx.utils.Align;
|
|
||||||
import com.badlogic.gdx.utils.viewport.FitViewport;
|
import com.badlogic.gdx.utils.viewport.FitViewport;
|
||||||
import com.badlogic.gdx.utils.viewport.Viewport;
|
import com.badlogic.gdx.utils.viewport.Viewport;
|
||||||
import io.github.com.quillraven.GdxGame;
|
import io.github.com.quillraven.GdxGame;
|
||||||
import io.github.com.quillraven.asset.SkinAsset;
|
import io.github.com.quillraven.asset.SkinAsset;
|
||||||
|
import io.github.com.quillraven.ui.model.MenuViewModel;
|
||||||
|
import io.github.com.quillraven.ui.view.MenuView;
|
||||||
|
|
||||||
public class MenuScreen extends ScreenAdapter {
|
public class MenuScreen extends ScreenAdapter {
|
||||||
|
|
||||||
@@ -44,7 +37,7 @@ public class MenuScreen extends ScreenAdapter {
|
|||||||
this.inputMultiplexer.clear();
|
this.inputMultiplexer.clear();
|
||||||
this.inputMultiplexer.addProcessor(stage);
|
this.inputMultiplexer.addProcessor(stage);
|
||||||
|
|
||||||
menuUI();
|
this.stage.addActor(new MenuView(stage, skin, new MenuViewModel(game)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -52,72 +45,6 @@ public class MenuScreen extends ScreenAdapter {
|
|||||||
this.stage.clear();
|
this.stage.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void menuUI() {
|
|
||||||
Table table = new Table();
|
|
||||||
table.setFillParent(true);
|
|
||||||
|
|
||||||
Image image = new Image(skin, "banner");
|
|
||||||
table.add(image);
|
|
||||||
|
|
||||||
table.row();
|
|
||||||
Table table1 = new Table();
|
|
||||||
table1.setBackground(skin.getDrawable("frame"));
|
|
||||||
table1.padLeft(40.0f);
|
|
||||||
table1.padRight(40.0f);
|
|
||||||
table1.padTop(25.0f);
|
|
||||||
table1.padBottom(20.0f);
|
|
||||||
|
|
||||||
TextButton textButton = new TextButton("Start Game", skin);
|
|
||||||
textButton.addListener(new ClickListener() {
|
|
||||||
@Override
|
|
||||||
public void clicked(InputEvent event, float x, float y) {
|
|
||||||
game.setScreen(GameScreen.class);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
table1.add(textButton);
|
|
||||||
|
|
||||||
table1.row();
|
|
||||||
Table table2 = new Table();
|
|
||||||
|
|
||||||
Label label = new Label("Music Volume", skin);
|
|
||||||
label.setColor(skin.getColor("sand"));
|
|
||||||
table2.add(label);
|
|
||||||
|
|
||||||
table2.row();
|
|
||||||
ProgressBar progressBar = new ProgressBar(0.0f, 100.0f, 1.0f, false, skin);
|
|
||||||
table2.add(progressBar);
|
|
||||||
table1.add(table2).padTop(10.0f);
|
|
||||||
|
|
||||||
table1.row();
|
|
||||||
table2 = new Table();
|
|
||||||
|
|
||||||
label = new Label("Sound Volume", skin);
|
|
||||||
label.setColor(skin.getColor("sand"));
|
|
||||||
table2.add(label);
|
|
||||||
|
|
||||||
table2.row();
|
|
||||||
progressBar = new ProgressBar(0.0f, 100.0f, 1.0f, false, skin);
|
|
||||||
table2.add(progressBar);
|
|
||||||
table1.add(table2).padTop(10.0f);
|
|
||||||
|
|
||||||
table1.row();
|
|
||||||
textButton = new TextButton("Quit Game", skin);
|
|
||||||
textButton.addListener(new ClickListener() {
|
|
||||||
@Override
|
|
||||||
public void clicked(InputEvent event, float x, float y) {
|
|
||||||
Gdx.app.exit();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
table1.add(textButton).padTop(10.0f);
|
|
||||||
table.add(table1).align(Align.top).expandY().padTop(20f);
|
|
||||||
|
|
||||||
table.row();
|
|
||||||
label = new Label("by Quillraven 2025", skin, "small");
|
|
||||||
label.setColor(skin.getColor("white"));
|
|
||||||
table.add(label).padRight(5.0f).padBottom(5f).expand().align(Align.bottomRight);
|
|
||||||
stage.addActor(table);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(float delta) {
|
public void render(float delta) {
|
||||||
stage.act(delta);
|
stage.act(delta);
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package io.github.com.quillraven.ui.model;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Gdx;
|
||||||
|
import io.github.com.quillraven.GdxGame;
|
||||||
|
import io.github.com.quillraven.audio.AudioService;
|
||||||
|
import io.github.com.quillraven.screen.GameScreen;
|
||||||
|
|
||||||
|
public class MenuViewModel extends ViewModel {
|
||||||
|
public static final String MUSIC_VOLUME_PROPERTY = "musicVolume";
|
||||||
|
|
||||||
|
private final AudioService audioService;
|
||||||
|
|
||||||
|
public MenuViewModel(GdxGame game) {
|
||||||
|
super(game);
|
||||||
|
this.audioService = game.getAudioService();
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getMusicVolume() {
|
||||||
|
return audioService.getMusicVolume();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMusicVolume(float volume) {
|
||||||
|
this.propertyChangeSupport.firePropertyChange(MUSIC_VOLUME_PROPERTY, getMusicVolume(), volume);
|
||||||
|
this.audioService.setMusicVolume(volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getSoundVolume() {
|
||||||
|
return audioService.getSoundVolume();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startGame() {
|
||||||
|
game.setScreen(GameScreen.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void quitGame() {
|
||||||
|
Gdx.app.exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package io.github.com.quillraven.ui.model;
|
||||||
|
|
||||||
|
import io.github.com.quillraven.GdxGame;
|
||||||
|
|
||||||
|
import java.beans.PropertyChangeListener;
|
||||||
|
import java.beans.PropertyChangeSupport;
|
||||||
|
|
||||||
|
public abstract class ViewModel {
|
||||||
|
protected final GdxGame game;
|
||||||
|
protected final PropertyChangeSupport propertyChangeSupport;
|
||||||
|
|
||||||
|
public ViewModel(GdxGame game) {
|
||||||
|
this.game = game;
|
||||||
|
this.propertyChangeSupport = new PropertyChangeSupport(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
|
||||||
|
this.propertyChangeSupport.addPropertyChangeListener(propertyName, listener);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
package io.github.com.quillraven.ui.view;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.Stage;
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.ui.Image;
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.ui.Label;
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.ui.ProgressBar;
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.ui.Table;
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
|
||||||
|
import com.badlogic.gdx.utils.Align;
|
||||||
|
import io.github.com.quillraven.ui.model.MenuViewModel;
|
||||||
|
|
||||||
|
public class MenuView extends View<MenuViewModel> {
|
||||||
|
|
||||||
|
public MenuView(Stage stage, Skin skin, MenuViewModel viewModel) {
|
||||||
|
super(stage, skin, viewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setupUI() {
|
||||||
|
setFillParent(true);
|
||||||
|
|
||||||
|
Image image = new Image(skin, "banner");
|
||||||
|
add(image).row();
|
||||||
|
|
||||||
|
setupMenuContent();
|
||||||
|
|
||||||
|
Label label = new Label("by Quillraven 2025", skin, "small");
|
||||||
|
label.setColor(skin.getColor("white"));
|
||||||
|
add(label).padRight(5.0f).padBottom(5f).expand().align(Align.bottomRight);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupMenuContent() {
|
||||||
|
Table contentTable = new Table();
|
||||||
|
contentTable.setBackground(skin.getDrawable("frame"));
|
||||||
|
contentTable.padLeft(40.0f);
|
||||||
|
contentTable.padRight(40.0f);
|
||||||
|
contentTable.padTop(25.0f);
|
||||||
|
contentTable.padBottom(20.0f);
|
||||||
|
|
||||||
|
TextButton textButton = new TextButton("Start Game", skin);
|
||||||
|
onClick(textButton, ((event, x, y) -> viewModel.startGame()));
|
||||||
|
contentTable.add(textButton).row();
|
||||||
|
|
||||||
|
ProgressBar musicBar = setupVolumeBar(contentTable, "Music Volume", viewModel.getMusicVolume());
|
||||||
|
viewModel.addPropertyChangeListener(MenuViewModel.MUSIC_VOLUME_PROPERTY, (event) ->
|
||||||
|
musicBar.setValue((Float) event.getNewValue())
|
||||||
|
);
|
||||||
|
setupVolumeBar(contentTable, "Sound Volume", viewModel.getSoundVolume());
|
||||||
|
|
||||||
|
textButton = new TextButton("Quit Game", skin);
|
||||||
|
onClick(textButton, ((event, x, y) -> viewModel.quitGame()));
|
||||||
|
contentTable.add(textButton).padTop(10.0f);
|
||||||
|
|
||||||
|
add(contentTable).align(Align.top).expandY().padTop(20f).row();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ProgressBar setupVolumeBar(Table contentTable, String title, float initialValue) {
|
||||||
|
Table table = new Table();
|
||||||
|
Label label = new Label(title, skin);
|
||||||
|
label.setColor(skin.getColor("sand"));
|
||||||
|
table.add(label).row();
|
||||||
|
|
||||||
|
ProgressBar progressBar = new ProgressBar(0.0f, 1f, 0.05f, false, skin);
|
||||||
|
progressBar.setValue(initialValue);
|
||||||
|
table.add(progressBar).fill();
|
||||||
|
contentTable.add(table).padTop(10.0f).row();
|
||||||
|
return progressBar;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package io.github.com.quillraven.ui.view;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.InputEvent;
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.Stage;
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.ui.Table;
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
|
||||||
|
import io.github.com.quillraven.ui.model.ViewModel;
|
||||||
|
|
||||||
|
public abstract class View<T extends ViewModel> extends Table {
|
||||||
|
|
||||||
|
protected final Stage stage;
|
||||||
|
protected final Skin skin;
|
||||||
|
protected final T viewModel;
|
||||||
|
|
||||||
|
public View(Stage stage, Skin skin, T viewModel) {
|
||||||
|
super(skin);
|
||||||
|
this.stage = stage;
|
||||||
|
this.skin = skin;
|
||||||
|
this.viewModel = viewModel;
|
||||||
|
setupUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void setupUI();
|
||||||
|
|
||||||
|
public static void onClick(Actor actor, OnClickConsumer consumer) {
|
||||||
|
actor.addListener(new ClickListener() {
|
||||||
|
@Override
|
||||||
|
public void clicked(InputEvent event, float x, float y) {
|
||||||
|
consumer.onClick(event, x, y);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface OnClickConsumer {
|
||||||
|
void onClick(InputEvent event, float x, float y);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user