From b837cb4f9e30e6ed3a9526ebbeba74563922636a Mon Sep 17 00:00:00 2001 From: Silas HW Date: Mon, 12 Aug 2024 14:13:59 +0100 Subject: [PATCH] Add ScreenData record to pass persistent arguments between screens --- src/core/src/com/mygdx/scngame/SCNGame.java | 21 ++++------ .../src/com/mygdx/scngame/dialog/Dialog.java | 11 ++++-- .../mygdx/scngame/entity/player/Player.java | 8 +++- .../entity/player/states/PlayerMoveState.java | 5 +-- .../scngame/screens/AssetLoadingScreen.java | 7 +++- .../com/mygdx/scngame/screens/GameScreen.java | 38 +++++++++---------- .../mygdx/scngame/screens/MainMenuScreen.java | 23 +++++------ .../scngame/screens/data/ScreenData.java | 34 +++++++++++++++-- 8 files changed, 85 insertions(+), 62 deletions(-) diff --git a/src/core/src/com/mygdx/scngame/SCNGame.java b/src/core/src/com/mygdx/scngame/SCNGame.java index 488f8ff..d395738 100644 --- a/src/core/src/com/mygdx/scngame/SCNGame.java +++ b/src/core/src/com/mygdx/scngame/SCNGame.java @@ -14,26 +14,21 @@ public class SCNGame extends Game { public SpriteBatch batch; public ShapeRenderer shape; - private static AssetManager assetManager; - - public static final AssetManager getAssetManager() { - if(assetManager == null) { - assetManager = new AssetManager(); - } - - return assetManager; - } + private AssetManager assetManager; @Override public void create () { batch = new SpriteBatch(); shape = new ShapeRenderer(); + assetManager = new AssetManager(); + ScreenData screenData = new ScreenData( this, batch, shape, - PrefSettings.getInstance() + PrefSettings.getInstance(), + assetManager ); this.setScreen(new AssetLoadingScreen(screenData)); @@ -54,9 +49,7 @@ public void dispose () { batch.dispose(); shape.dispose(); - if(assetManager != null) { - assetManager.clear(); - assetManager.dispose(); - } + assetManager.clear(); + assetManager.dispose(); } } diff --git a/src/core/src/com/mygdx/scngame/dialog/Dialog.java b/src/core/src/com/mygdx/scngame/dialog/Dialog.java index 38800db..cb8fa55 100644 --- a/src/core/src/com/mygdx/scngame/dialog/Dialog.java +++ b/src/core/src/com/mygdx/scngame/dialog/Dialog.java @@ -13,6 +13,7 @@ import com.mygdx.scngame.SCNGame; import com.mygdx.scngame.event.DialogEventListener; import com.mygdx.scngame.event.GlobalEventBus; +import com.mygdx.scngame.screens.data.ScreenData; import com.mygdx.scngame.settings.Controls; import com.mygdx.scngame.settings.PrefSettings; import com.mygdx.scngame.settings.Settings; @@ -32,7 +33,7 @@ public class Dialog extends InputAdapter implements DialogEventListener { private Viewport view; - private static Skin skin = SCNGame.getAssetManager().get("skin/uiskin.json"); + private static Skin skin; private Label label; @@ -56,8 +57,10 @@ public class Dialog extends InputAdapter implements DialogEventListener { private Settings settings; - public Dialog(Settings settings) { - this.settings = settings; + public Dialog(ScreenData screenData) { + this.settings = screenData.settings(); + this.skin = screenData.assets().get("skin/uiskin.json", Skin.class); + stage = new Stage(new ScreenViewport()); root = new Table(); @@ -74,7 +77,7 @@ public Dialog(Settings settings) { wrapper.center(); wrapper.fill(); - Texture patchTexture = SCNGame.getAssetManager().get("sprites/patch.9.png", Texture.class); + Texture patchTexture = screenData.assets().get("sprites/patch.9.png", Texture.class); icon = new Image(patchTexture); icon.setAlign(Align.center); diff --git a/src/core/src/com/mygdx/scngame/entity/player/Player.java b/src/core/src/com/mygdx/scngame/entity/player/Player.java index 2382163..5352fae 100644 --- a/src/core/src/com/mygdx/scngame/entity/player/Player.java +++ b/src/core/src/com/mygdx/scngame/entity/player/Player.java @@ -1,5 +1,7 @@ package com.mygdx.scngame.entity.player; +import com.badlogic.gdx.assets.AssetManager; +import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.glutils.ShapeRenderer; import com.dongbat.jbump.Item; @@ -24,7 +26,11 @@ public class Player extends Entity { public HealthComponent health; public HurtBox hurtbox; - public Player() { + public Texture texture; + + public Player(AssetManager assets) { + texture = assets.get("sprites/test.png", Texture.class); + Box foot; foot = new Box(); foot.solid = true; diff --git a/src/core/src/com/mygdx/scngame/entity/player/states/PlayerMoveState.java b/src/core/src/com/mygdx/scngame/entity/player/states/PlayerMoveState.java index 96522ab..5ebac6f 100644 --- a/src/core/src/com/mygdx/scngame/entity/player/states/PlayerMoveState.java +++ b/src/core/src/com/mygdx/scngame/entity/player/states/PlayerMoveState.java @@ -21,8 +21,6 @@ public class PlayerMoveState implements EntityState { protected Player container; protected World world; - private Texture texture; - @Override public EntityState update(float delta) { int dx = 0; @@ -62,7 +60,7 @@ public EntityState update(float delta) { @Override public EntityState draw(SpriteBatch batch, ShapeRenderer shape, float alpha) { - batch.draw(texture, container.position.x, container.position.y); + batch.draw(container.texture, container.position.x, container.position.y); return null; } @@ -78,7 +76,6 @@ public void setWorld(World world) { @Override public void enter() { - texture = SCNGame.getAssetManager().get("sprites/test.png"); container.hurtbox.setTakesDamage(true); } diff --git a/src/core/src/com/mygdx/scngame/screens/AssetLoadingScreen.java b/src/core/src/com/mygdx/scngame/screens/AssetLoadingScreen.java index 17d2928..be63923 100644 --- a/src/core/src/com/mygdx/scngame/screens/AssetLoadingScreen.java +++ b/src/core/src/com/mygdx/scngame/screens/AssetLoadingScreen.java @@ -35,12 +35,15 @@ public class AssetLoadingScreen implements Screen { Settings settings; + ScreenData screenData; + public AssetLoadingScreen(ScreenData args) { this.game = args.game(); this.batch = args.batch(); this.shapeRenderer = args.shapeRenderer(); this.settings = args.settings(); + this.screenData = args; } AssetManager assetManager; @@ -70,7 +73,7 @@ public AssetLoadingScreen(ScreenData args) { @Override public void show() { - assetManager = SCNGame.getAssetManager(); + assetManager = screenData.assets(); loadAssets(assetManager, "sprites/", spriteExtensions, Texture.class); loadAssets(assetManager, "skin/", skinExtensions, Skin.class); @@ -119,7 +122,7 @@ public void render(float delta) { Gdx.app.log(logTag, "Loading assets... " + assetManager.getProgress()*100 + "%"); if(assetManager.isFinished()) { - game.setScreen(new MainMenuScreen(game, batch, shapeRenderer, settings)); + game.setScreen(new MainMenuScreen(screenData)); return; } diff --git a/src/core/src/com/mygdx/scngame/screens/GameScreen.java b/src/core/src/com/mygdx/scngame/screens/GameScreen.java index 33214f6..2c74103 100644 --- a/src/core/src/com/mygdx/scngame/screens/GameScreen.java +++ b/src/core/src/com/mygdx/scngame/screens/GameScreen.java @@ -34,6 +34,7 @@ import com.mygdx.scngame.physics.DamageBox; import com.mygdx.scngame.physics.HitBox; import com.mygdx.scngame.scene.Scene; +import com.mygdx.scngame.screens.data.ScreenData; import com.mygdx.scngame.settings.PrefSettings; import com.mygdx.scngame.settings.Settings; @@ -45,9 +46,6 @@ public class GameScreen implements Screen { OrthographicCamera camera; Viewport gameViewport; - SpriteBatch batch; - ShapeRenderer shape; - World world; Player player; @@ -59,17 +57,17 @@ public class GameScreen implements Screen { PathNodes pathNodes; - Settings settings; + ScreenData screenData; // want to avoid large constructors // maybe wrap arguments into a datastructure? // ScreenData: game, batch, shape, settings // GameScreenData: player, map id, spawn id - public GameScreen(Game game, SpriteBatch batch, ShapeRenderer shape, Player player, Settings settings) { - this.game = game; - this.batch = batch; - this.shape = shape; + public GameScreen(ScreenData screenData, Player player) { + this.game = screenData.game(); + + this.screenData = screenData; this.pathNodes = new PathNodes(); @@ -80,13 +78,12 @@ public GameScreen(Game game, SpriteBatch batch, ShapeRenderer shape, Player play world = new World(); - dialog = new Dialog(PrefSettings.getInstance()); + dialog = new Dialog(screenData); - this.settings = settings; } - public GameScreen(Game game, SpriteBatch batch, ShapeRenderer shape, Settings settings) { - this(game, batch, shape, new Player(), settings); + public GameScreen(ScreenData screenData) { + this(screenData, new Player(screenData.assets())); } /* @@ -101,14 +98,14 @@ public GameScreen(Game game, SpriteBatch batch, ShapeRenderer shape, Settings se @Override public void show() { - bg = SCNGame.getAssetManager().get("music/bgtest2.mp3", Music.class); + bg = screenData.assets().get("music/bgtest2.mp3", Music.class); bg.setLooping(true); bg.play(); - scene = new Scene(gameViewport, batch, shape, world); + scene = new Scene(gameViewport, screenData.batch(), screenData.shapeRenderer(), world); - tiledMap = SCNGame.getAssetManager().get("tilemaps/testmap1.tmx"); - mapRenderer = new OrthogonalTiledMapRenderer(tiledMap, 1f, this.batch); + tiledMap = screenData.assets().get("tilemaps/testmap1.tmx"); + mapRenderer = new OrthogonalTiledMapRenderer(tiledMap, 1f, screenData.batch()); // extract objects and parse them for(MapLayer layer : tiledMap.getLayers()) { @@ -227,7 +224,7 @@ private void parseMapObject(MapObject obj, float offsetX, float offsetY) { public void render(float delta) { Gdx.graphics.setTitle("" + Gdx.graphics.getFramesPerSecond()); - bg.setVolume(settings.getMusicVolume()); + bg.setVolume(screenData.settings().getMusicVolume()); ScreenUtils.clear(Color.BLACK); @@ -244,6 +241,7 @@ public void render(float delta) { Gdx.gl.glEnable(GL20.GL_BLEND); Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_BLEND); + ShapeRenderer shape = screenData.shapeRenderer(); shape.setProjectionMatrix(camera.combined); shape.begin(ShapeRenderer.ShapeType.Filled); @@ -268,15 +266,15 @@ public void render(float delta) { Gdx.gl.glDisable(GL20.GL_BLEND); if(Gdx.input.isKeyJustPressed(Input.Keys.F)) { - game.setScreen(new MainMenuScreen(game, batch, shape, settings)); + game.setScreen(new MainMenuScreen(screenData)); } if(Gdx.input.isKeyJustPressed(Input.Keys.I)) { - settings.setDialogScale(settings.getDialogScale() + 0.1f); + screenData.settings().setDialogScale(screenData.settings().getDialogScale() + 0.1f); } if(Gdx.input.isKeyJustPressed(Input.Keys.K)) { - settings.setDialogScale(settings.getDialogScale() - 0.1f); + screenData.settings().setDialogScale(screenData.settings().getDialogScale() - 0.1f); } } diff --git a/src/core/src/com/mygdx/scngame/screens/MainMenuScreen.java b/src/core/src/com/mygdx/scngame/screens/MainMenuScreen.java index 546c31d..6aeb2a3 100644 --- a/src/core/src/com/mygdx/scngame/screens/MainMenuScreen.java +++ b/src/core/src/com/mygdx/scngame/screens/MainMenuScreen.java @@ -19,6 +19,7 @@ import com.badlogic.gdx.utils.viewport.ScreenViewport; import com.badlogic.gdx.utils.viewport.Viewport; import com.mygdx.scngame.SCNGame; +import com.mygdx.scngame.screens.data.ScreenData; import com.mygdx.scngame.settings.PrefSettings; import com.mygdx.scngame.settings.Settings; @@ -32,31 +33,26 @@ public class MainMenuScreen implements Screen { OrthographicCamera camera; Game game; - SpriteBatch batch; - ShapeRenderer shape; Music bg; - Settings settings; + ScreenData screenData; - public MainMenuScreen(Game game, SpriteBatch batch, ShapeRenderer shape, Settings settings) { - this.game = game; - - this.batch = batch; - this.shape = shape; + public MainMenuScreen(ScreenData screenData) { + this.game = screenData.game(); camera = new OrthographicCamera(); viewport = new ScreenViewport(); - bg = SCNGame.getAssetManager().get("music/bgtest1.mp3", Music.class); + bg = screenData.assets().get("music/bgtest1.mp3", Music.class); - this.settings = settings; + this.screenData = screenData; } @Override public void show() { - skin = new Skin(Gdx.files.internal("skin/uiskin.json")); + skin = screenData.assets().get("skin/uiskin.json", Skin.class); label = new Label(" ", skin); label.setText("Press E to Start"); @@ -69,7 +65,7 @@ public void show() { stage.addActor(container); - bg.setVolume(settings.getMusicVolume()); + bg.setVolume(screenData.settings().getMusicVolume()); bg.setLooping(true); bg.play(); } @@ -80,7 +76,7 @@ public void render(float delta) { stage.draw(); if(Gdx.input.isKeyJustPressed(Input.Keys.E)) { - game.setScreen(new GameScreen(game, batch, shape, settings)); + game.setScreen(new GameScreen(screenData)); } } @@ -101,7 +97,6 @@ public void resume() { @Override public void hide() { - skin.dispose(); stage.dispose(); bg.stop(); } diff --git a/src/core/src/com/mygdx/scngame/screens/data/ScreenData.java b/src/core/src/com/mygdx/scngame/screens/data/ScreenData.java index 250c91c..b371284 100644 --- a/src/core/src/com/mygdx/scngame/screens/data/ScreenData.java +++ b/src/core/src/com/mygdx/scngame/screens/data/ScreenData.java @@ -1,10 +1,38 @@ package com.mygdx.scngame.screens.data; import com.badlogic.gdx.Game; +import com.badlogic.gdx.assets.AssetManager; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.glutils.ShapeRenderer; import com.mygdx.scngame.settings.Settings; -public record ScreenData(Game game, SpriteBatch batch, ShapeRenderer shapeRenderer, Settings settings) { - -} \ No newline at end of file +/** + * Holds all the data that is required between different game screens. + * + * This is used instead of individual arguments for a number of reasons: + *
    + *
  1. Records are immutable. Although not forced, it encourages + * a ScreenData instance to persist across screens instead of + * re-instantiating everything + *
  2. + * + *
  3. + * Reduces the number of arguments in each screen constructor, + * especially since every screen will require these values + *
  4. + * + *
  5. + * Still allows for testing screens with fake values. Using singletons + * or static values held in the main game class wouldn't allow for this, and could + * create some gnarly inter-dependencies between sub-systems. + *
  6. + *
+ * + * @author Silas Hayes-Williams + */ +public record ScreenData(Game game, + SpriteBatch batch, + ShapeRenderer shapeRenderer, + Settings settings, + AssetManager assets +) {} \ No newline at end of file