Reuse code when using screens in Libgdx

From what I understand when I read other people's code on how to create different screens. You make the main handler class ... And then create a new class for each screen.

What confuses me is that whenever you create a new screen, you need to redefine everything that will be displayed, for example SpriteBatch, sprites, fonts, etc. Is there a way to reuse such things on all screens? I mean, if I have 10 screens and want to be able to draw text on each screen. Is it really good programming practice to create a new BitmapFont for all 10 screen classes?

+6
source share
1 answer

I created an abstract screen class that contains all the common objects for the screen, and each of my screens extends this abstract class. And it looks like this:

public abstract class AbstractScreen implements Screen { protected final Game game; protected InputMultiplexer multiInputProcessor; protected ScreenInputHandler screenInputHandler; protected Stage uiStage; protected Skin uiSkin; public AbstractScreen(Game game) { this.game = game; this.uiStage = new Stage(); this.uiSkin = new Skin(); this.screenInputHandler = new ScreenInputHandler(game); this.multiInputProcessor = new InputMultiplexer(); multiInputProcessor.addProcessor(uiStage); multiInputProcessor.addProcessor(screenInputHandler); Gdx.input.setInputProcessor(multiInputProcessor); } private static NinePatch processNinePatchFile(String fname) { final Texture t = new Texture(Gdx.files.internal(fname)); final int width = t.getWidth() - 2; final int height = t.getHeight() - 2; return new NinePatch(new TextureRegion(t, 1, 1, width, height), 3, 3, 3, 3); } @Override public void render (float delta) { Gdx.gl.glClearColor(0.2f, 0.2f, 0.2f, 1); Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT); uiStage.act(Math.min(Gdx.graphics.getDeltaTime(), 1 / 30f)); uiStage.draw(); Table.drawDebug(uiStage); } @Override public void resize (int width, int height) { } @Override public void show() { } @Override public void hide() { dispose(); } @Override public void pause() { } @Override public void resume() { } @Override public void dispose() { uiStage.dispose(); uiSkin.dispose(); } } 

When I want to create a new class, I just expand the abstract screen and add what I need. For example, I have a screen with basic credits, I just need to create components, but an abstract screen draws it:

 public class CreditsScreen extends AbstractScreen { public CreditsScreen(final Game game) { super(game); // Generate a 1x1 white texture and store it in the skin named "white". Pixmap pixmap = new Pixmap(1, 1, Format.RGBA8888); pixmap.setColor(Color.WHITE); pixmap.fill(); uiSkin.add("white", new Texture(pixmap)); // Store the default libgdx font under the name "default". BitmapFont buttonFont = new BitmapFont(); buttonFont.scale(scale); uiSkin.add("default", buttonFont); // Configure a TextButtonStyle and name it "default". Skin resources are stored by type, so this doesn't overwrite the font. TextButtonStyle textButtonStyle = new TextButtonStyle(); textButtonStyle.up = uiSkin.newDrawable("white", Color.DARK_GRAY); textButtonStyle.down = uiSkin.newDrawable("white", Color.DARK_GRAY); textButtonStyle.checked = uiSkin.newDrawable("white", Color.BLUE); textButtonStyle.over = uiSkin.newDrawable("white", Color.LIGHT_GRAY); textButtonStyle.font = uiSkin.getFont("default"); uiSkin.add("default", textButtonStyle); // Create a table that fills the screen. Everything else will go inside this table. Table table = new Table(); table.setFillParent(true); uiStage.addActor(table); table.debug(); // turn on all debug lines (table, cell, and widget) table.debugTable(); // turn on only table lines // Label BitmapFont labelFont = new BitmapFont(); labelFont.scale(scale); LabelStyle labelStyle = new LabelStyle(labelFont, Color.BLUE); uiSkin.add("presents", labelStyle); final Label myName = new Label("Credits and all that stuff", uiSkin, "presents"); table.add(myName).expand().center(); } } 

I also have one class that processes input for all screens, a specific task is intended for this, how the back button works around different screens. And this handler class is created in an abstract class.

 public class ScreenInputHandler implements InputProcessor { private final Game game; public ScreenInputHandler(Game game) { this.game = game; } @Override public boolean keyDown(int keycode) { if(keycode == Keys.BACK || keycode == Keys.BACKSPACE){ if (game.getScreen() instanceof MainMenuScreen) { Gdx.app.exit(); } if (game.getScreen() instanceof GameScreen) { World.getInstance().togglePause(false); } if (game.getScreen() instanceof CreditsScreen) { game.setScreen(new MainMenuScreen(game)); } } return false; } } 
+10
source

All Articles