【问题标题】:Reuse code when using screens in Libgdx在 Libgdx 中使用屏幕时重用代码
【发布时间】:2014-02-21 01:04:37
【问题描述】:

根据我在阅读其他人关于如何制作不同屏幕的代码时的理解。你做一个主处理程序类......然后为每个屏幕创建一个新类。

让我感到困惑的是,每当你创建一个新屏幕时,你必须重新定义将要渲染的所有内容,比如 SpriteBatch、精灵、字体等。有没有办法在所有屏幕中重用这些东西?我的意思是,如果我有 10 个屏幕,并且希望能够在每个屏幕上绘制文本。为所有 10 个屏幕类制作新的 BitmapFont 真的是一种很好的编程习惯吗?

【问题讨论】:

    标签: java android libgdx


    【解决方案1】:

    我创建了一个包含所有常见屏幕对象的抽象屏幕类,我的每个屏幕都扩展了这个抽象类。看起来像这样:

    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();
        }
    }
    

    当我想创建一个新类时,我只需扩展抽象屏幕并添加我需要的内容。例如,我有一个基本的制作人员屏幕,我只需要创建组件,但抽象屏幕会绘制它:

    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();
        }
    }
    

    我还有一个类来处理所有屏幕的输入,其具体目的是处理后退按钮在不同屏幕周围的工作方式。而这个输入处理类是在抽象类中创建的。

    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;
        }
    
    }
    

    【讨论】:

    • 如果它是可接受的解决方案,您可以通过按投票旁边的勾号来接受答案。谢谢。
    • +1。很好的解释和良好的形式。只有一件事@user3335152:你说你想在每个屏幕类中使用 BitMapFont。我建议使用 Assets 类,它在内部与 AssetManager 一起使用。例如,您可以在那里存储 BitMapFont(由 AssetManager 在启动时加载)并调用 Assets.getFont()。只是一个想法
    • 虽然让我感到困惑的是,即使已经创建了一个类的新实例(例如后面),您也总是创建一个新实例?这是好的做法吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-15
    • 2013-10-05
    • 1970-01-01
    • 2015-09-08
    • 1970-01-01
    相关资源
    最近更新 更多