使用LibGDX切换屏幕在Android设备上很慢

时间:2015-09-15 21:36:39

标签: java android performance libgdx screen

在桌面模式下,屏幕加载完全正常,但在HTC One M8上加载下一个屏幕之前,屏幕会冻结约一两秒。

这发生在我的所有屏幕上,所以我只会展示两个。我尝试在上一个屏幕中为下一个屏幕加载所有资源,然后在加载下一个屏幕之前检查它们是否使用assets.update()加载,但冻结仍然发生。

public class MenuScreen implements Screen, InputProcessor {
    private Application game;
    private OrthographicCamera cam;
    private Viewport viewport;

    private GameIcon gameIcon;
    private ParticleEffect effect;

    private MenuBackground mb, mb2;
    private Texture title_background, title, play_button, instructions_button, about_button, black_bottom;
    private Sprite titleSprite, playButtonSprite, instructionsButtonSprite, aboutButtonSprite, blackBottomSprite;
    private GameButton playBtn, instructionsBtn, aboutBtn;

    private static Music title_music;

    private long timeTouchUp;
    private boolean playUp, instructionsUp, aboutUp;

    private int touchX, touchY;

    private AssetManager assets; //loaded in SplashScreen

    public MenuScreen(Application game, AssetManager assets){
        this.game = game;

        Gdx.input.setInputProcessor(this);

        cam = new OrthographicCamera();
        cam.setToOrtho(false, Application.WIDTH, Application.HEIGHT);
        viewport = new FitViewport(Application.WIDTH, Application.HEIGHT, cam);

        this.assets = assets;
        queueAssets();

        title_background = assets.get("menu/title_background.png", Texture.class);
        title = assets.get("menu/title.png", Texture.class);
        play_button = assets.get("menu/play_button.png", Texture.class);
        instructions_button = assets.get("menu/instructions_button.png", Texture.class);
        about_button = assets.get("menu/about_button.png", Texture.class);
        black_bottom = assets.get("menu/black_bottom.png", Texture.class);


        titleSprite = new Sprite(title);
        playButtonSprite = new Sprite(play_button);
        instructionsButtonSprite = new Sprite(instructions_button);
        aboutButtonSprite = new Sprite(about_button);
        blackBottomSprite = new Sprite(black_bottom);

        playBtn = new GameButton();
        instructionsBtn = new GameButton();
        aboutBtn = new GameButton();

        mb = new MenuBackground(1);
        mb2 = new MenuBackground(2);

        title_music = assets.get("music/title_screen.mp3", Music.class);
        title_music.setLooping(true);
        title_music.play();

        gameIcon = new GameIcon(Application.WIDTH/2 - Application.WIDTH/10, Application.HEIGHT/10);

        effect = new ParticleEffect();
        effect.load(Gdx.files.internal("game/particles1.party"), Gdx.files.internal("game"));
        effect.start();

        timeTouchUp = 0;

        //setting things

        mb.getSprite().setX(0);
        mb2.getSprite().setX(0);

        blackBottomSprite.setSize(Application.WIDTH, Application.HEIGHT * 3 / 4);
        blackBottomSprite.setAlpha(1f);

        titleSprite.setSize(Application.WIDTH, Application.WIDTH * 0.5f); //width, height
        titleSprite.setPosition(Application.WIDTH / 2 - titleSprite.getWidth() / 2, Application.HEIGHT / 2 * 1.35f);

        playBtn.setTexture(play_button);
        playBtn.setOrigSize(titleSprite.getWidth() * 0.7f, titleSprite.getWidth() * 0.127f);
        playBtn.setOrigPosition(cam.position.x - playBtn.getWidth() / 2, cam.position.y + 80);

        instructionsBtn.setTexture(instructions_button);
        instructionsBtn.setOrigSize(titleSprite.getWidth() * 0.7f, titleSprite.getWidth() * 0.127f);
        instructionsBtn.setOrigPosition(cam.position.x - instructionsBtn.getWidth() / 2, cam.position.y + 10);

        aboutBtn.setTexture(about_button);
        aboutBtn.setOrigSize(titleSprite.getWidth() * 0.7f, titleSprite.getWidth() * 0.127f);
        aboutBtn.setOrigPosition(cam.position.x - aboutBtn.getWidth() / 2, cam.position.y - 60);

        gameIcon.setSize(50, 50);
        gameIcon.setPosition(Application.WIDTH / 2 - Application.WIDTH / 20, Application.HEIGHT / 10 + 10);
        gameIcon.setvX(0);
        gameIcon.setvY(0);
    }

    public void queueAssets() {
        assets.load("fonts/fixedsys.fnt", BitmapFont.class);
        assets.load("menu/black_bottom.png", Texture.class);
        assets.load("level_select/play_level.png", Texture.class);
    }

    @Override
    public void show() {

    }

    @Override
    public void render(float delta) {

        Gdx.gl.glClearColor(0, 0, 0, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        cam.update();

        game.batch.setProjectionMatrix(cam.combined);
        game.batch.begin();

        mb.update();
        mb2.update();
        mb.getSprite().setY(mb.getPosition().y);
        mb2.getSprite().setY(mb2.getPosition().y);

        mb.getSprite().draw(game.batch);
        mb2.getSprite().draw(game.batch);

        blackBottomSprite.draw(game.batch);

        titleSprite.draw(game.batch);

        playBtn.update();
        playBtn.draw(game.batch);

        instructionsBtn.update();
        instructionsBtn.draw(game.batch);

        aboutBtn.update();
        aboutBtn.draw(game.batch);

        gameIcon.draw(game.batch);

        effect.getEmitters().first().setPosition(Application.WIDTH / 2 - Application.WIDTH / 20 + gameIcon.getWidth() / 2, Application.HEIGHT / 10 + 10); //doesnt follow gameIcon
        effect.update(delta);
        effect.draw(game.batch);

        game.batch.end();

        gameIcon.update();

        if (TimeUtils.timeSinceMillis(timeTouchUp) > 100 && assets.update()) {
            if (playUp) {
                game.setScreen(new LevelSelectScreen(game, assets, mb.getSprite().getY(), mb2.getSprite().getY(), gameIcon));
                dispose();
            }
            else if(instructionsUp) {

            }
            else if(aboutUp) {

            }
        }

    }

    public static void stopMenuMusic()
    {
        title_music.stop();
        title_music.dispose();
    }

    @Override
    public void resize(int width, int height) {
        viewport.update(width, height);
    }

    @Override
    public void pause() {

    }

    @Override
    public void resume() {

    }

    @Override
    public void hide() {

    }

    @Override
    public void dispose() {
        title_background.dispose();
        title.dispose();
        play_button.dispose();
        instructions_button.dispose();
        about_button.dispose();
    }

    @Override
    public boolean keyDown(int keycode) {
        return true;
    }

    @Override
    public boolean keyUp(int keycode) {
        return true;
    }

    @Override
    public boolean keyTyped(char character) {
        return true;
    }

    @Override
    public boolean touchDown(int screenX, int screenY, int pointer, int button) {
        touchX = GameButton.convertX(screenX);
        touchY = GameButton.convertY(screenY);

        if(playBtn.checkCoords(touchX, touchY))
        {
            playBtn.clickDown();
        }
        else if(instructionsBtn.checkCoords(touchX, touchY))
        {
            instructionsBtn.clickDown();
        }
        else if(aboutBtn.checkCoords(touchX, touchY))
        {
            aboutBtn.clickDown();
        }

        return true;
    }

    @Override
    public boolean touchUp(int screenX, int screenY, int pointer, int button) {
        timeTouchUp = TimeUtils.millis();
        if (playBtn.checkCoords(touchX, touchY)) {
            playUp = true;
            playBtn.clickUp();
        }
        else if(instructionsBtn.checkCoords(touchX, touchY))
        {
            instructionsUp = true;
            instructionsBtn.clickUp();
        }
        else if(aboutBtn.checkCoords(touchX, touchY))
        {
            aboutUp = true;
            aboutBtn.clickUp();
        }

        return true;
    }

    @Override
    public boolean touchDragged(int screenX, int screenY, int pointer) {
        return true;
    }

    @Override
    public boolean mouseMoved(int screenX, int screenY) {
        return true;
    }

    @Override
    public boolean scrolled(int amount) {
        return true;
    }

    public boolean isClicked(Sprite sprite, float x, float y)
    {
        if (x >= sprite.getX() && x <= sprite.getX() + sprite.getWidth())
        {
            if (y >= sprite.getY() && y <= sprite.getY() + sprite.getHeight())
            {
                return true;
            }
        }
        return false;
    }
}

点击上面屏幕上的按钮后,它应该加载这个:

public class LevelSelectScreen implements Screen, InputProcessor{

    private Application game;
    private OrthographicCamera cam;
    private Viewport viewport;

    private ParticleEffect effect;

    private Texture black_bottom, play_level_button;
    private Sprite blackBottomSprite;

    private String[] levelNames;

    private int maxLevel, level, touchX, touchY;
    private long timeTouchUp;

    private GameButton playLevelBtn;

    private GameIcon gameIcon;

    private MenuBackground mb, mb2;

    private boolean playUp;

    private BitmapFont font;
    public GlyphLayout levelLayout, levelNameLayout;

    private AssetManager assets; //loaded in MenuScreen

    public LevelSelectScreen(Application game, AssetManager assets, float mbY, float mb2Y, GameIcon gameIcon) {
        this.game = game;
        Gdx.input.setInputProcessor(this);

        this.assets = assets;
        queueAssets();

        levelNames = new String[2];
        levelNames[0] = "PLACEHOLDER";
        levelNames[1] = "Taking Off";
        maxLevel = levelNames.length - 1;
        level = 1;

        font = assets.get("fonts/fixedsys.fnt", BitmapFont.class);
        font.setColor(Color.BLACK);
        levelLayout = new GlyphLayout(font, "Level " + level);
        levelNameLayout = new GlyphLayout(font, levelNames[0]);

        cam = new OrthographicCamera();
        cam.setToOrtho(false, Application.WIDTH, Application.HEIGHT);
        viewport = new FitViewport(Application.WIDTH, Application.HEIGHT, cam);

        mb = new MenuBackground(mbY, true);
        mb2 = new MenuBackground(mb2Y, true);

        this.gameIcon = new GameIcon(Application.WIDTH / 2 - Application.WIDTH / 20, Application.HEIGHT / 10 + 10);

        black_bottom = assets.get("menu/black_bottom.png", Texture.class);
        play_level_button = assets.get("level_select/play_level.png", Texture.class);

        blackBottomSprite = new Sprite(black_bottom);

        //setting stuff
        mb.getSprite().setX(0);
        mb2.getSprite().setX(0);

        blackBottomSprite.setSize(Application.WIDTH, Application.HEIGHT * 3 / 4);
        blackBottomSprite.setAlpha(1f);

        this.gameIcon.setRotation(gameIcon.getRotation());
        this.gameIcon.setSize(gameIcon.getWidth(), gameIcon.getHeight());
        this.gameIcon.setvX(0);
        this.gameIcon.setvY(0);

        playLevelBtn = new GameButton();
        playLevelBtn.setTexture(play_level_button);
        playLevelBtn.setOrigSize(150, 90);
        playLevelBtn.setOrigPosition(
                Application.WIDTH / 2 - playLevelBtn.getWidth() / 2,
                this.gameIcon.getX() + this.gameIcon.getHeight() + 70);

        effect = new ParticleEffect();
        effect.load(Gdx.files.internal("game/particles1.party"), Gdx.files.internal("game"));
        effect.start();

        playUp = false;

    }

    public void queueAssets() {
        assets.load("game/backgrounds/shadow_mask.png", Texture.class);
        assets.load("game/backgrounds/background_orange.png", Texture.class);
        assets.load("game/border_left.png", Texture.class);
        assets.load("game/border_right.png", Texture.class);
        assets.load("game/backgrounds/white_only.png", Texture.class);
        assets.load("game/backgrounds/circles_pattern.png", Texture.class);
    }

    @Override
    public void show() {
    }

    @Override
    public void render(float delta) {
        Gdx.gl.glClearColor(0, 0, 0, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        cam.update();

        game.batch.setProjectionMatrix(cam.combined);
        game.batch.begin();

        mb.update();
        mb2.update();
        mb.getSprite().setY(mb.getPosition().y);
        mb2.getSprite().setY(mb2.getPosition().y);

        mb.getSprite().draw(game.batch);
        mb2.getSprite().draw(game.batch);
        blackBottomSprite.draw(game.batch);

        gameIcon.update();
        gameIcon.draw(game.batch);

        levelLayout.setText(font, "Level " + level);
        levelNameLayout.setText(font, levelNames[level]);
        font.draw(
                game.batch,
                "Level " + level,
                Application.WIDTH / 2 - levelLayout.width / 2,
                Application.HEIGHT / 2 + levelLayout.height / 2
        );

        effect.getEmitters().first().setPosition(Application.WIDTH / 2 - Application.WIDTH / 20 + gameIcon.getWidth() / 2, Application.HEIGHT / 10 + 10); //doesnt follow gameIcon
        effect.update(delta);
        effect.draw(game.batch);

        playLevelBtn.update();
        playLevelBtn.draw(game.batch);

        game.batch.end();

        if (TimeUtils.timeSinceMillis(timeTouchUp) > 100 && assets.update()) {
            if (playUp) {                game.setScreen(new com.xx4everPixelatedxx.gaterunner.screens.Levels.Level1Screen(game, assets));

                MenuScreen.stopMenuMusic();
                dispose();
            }
        }
    }

    @Override
    public void resize(int width, int height) {
        viewport.update(width, height);
    }

    @Override
    public void pause() {

    }

    @Override
    public void resume() {

    }

    @Override
    public void hide() {

    }

    @Override
    public void dispose() {

    }

    @Override
    public boolean keyDown(int keycode) {
        return false;
    }

    @Override
    public boolean keyUp(int keycode) {
        return false;
    }

    @Override
    public boolean keyTyped(char character) {
        return false;
    }

    @Override
    public boolean touchDown(int screenX, int screenY, int pointer, int button) {
        touchX = GameButton.convertX(screenX);
        touchY = GameButton.convertY(screenY);

        if(playLevelBtn.checkCoords(touchX, touchY))
        {
            playLevelBtn.clickDown();
        }

        return true;
    }

    @Override
    public boolean touchUp(int screenX, int screenY, int pointer, int button) {
        timeTouchUp = TimeUtils.millis();
        if (playLevelBtn.checkCoords(touchX, touchY)) {
            playUp = true;
            playLevelBtn.clickUp();
        }
        return true;
    }

    @Override
    public boolean touchDragged(int screenX, int screenY, int pointer) {
        return false;
    }

    @Override
    public boolean mouseMoved(int screenX, int screenY) {
        return false;
    }

    @Override
    public boolean scrolled(int amount) {
        return false;
    }
}

如果您现在还没有猜到,我的问题是:如何让我的Android设备上的屏幕转换花费更少的时间?

1 个答案:

答案 0 :(得分:2)

我更确定您的问题出在加载资源中。请注意,虽然您要在 MenuScreen 中加载 LevelSelectScreen 的资源,但您仍在LevelSelect构造函数中调用 queueAssets();

进行一些测试 - 使用它们删除所有资产和ui元素,然后检查加载时间。

首先使用TextureAtlas将加载的纹理打包到TexturePacker中,以减少加载纹理的数量。 I / O操作非常昂贵。

其次,您可以创建ResourcesManager(例如实现Singleton)并保留其静态实例,在应用程序的开始时加载所有资源。