android - Libgdx:屏幕管理器

标签 android performance libgdx game-center

你好,先生们,我已经开始开发一款使用大量屏幕(介绍屏幕、闪屏、预览屏幕、主菜单屏幕等)的游戏,并且遇到了以下一些问题:

从一个屏幕切换到另一个屏幕有时会 react 迟钝或出现错误,有时会一遍又一遍地重复相同的屏幕。 我已经回收了一个后退按钮,我计划在不同的窗口中使用它,但它只在一个窗口中可见,而在另一个窗口中可见。 我将我的屏幕实现为 SCREENS,这是否与抽象屏幕类有任何关系,因为正如我在不同的示例代码中看到的那样,它们将屏幕扩展到实现屏幕的某个类。

我对这部分很困惑,我希望能找到解决这个问题的合适方法。

有没有一种方法可以让我正确地导航或使它对我的屏幕响应更快?它是否有助于提高游戏的性能我会创建一个屏幕管理器?屏幕管理器应该有哪些实例?

这是我的主菜单屏幕代码,遇到后退按钮问题。

public class MainMenuScreen implements Screen {

public static final String LOG = "MainMenu Class";
private OrthographicCamera camera;
private SpriteBatch batch;
private Texture texture = Assets.bgmenu;
private Sprite sprite;
private static Stage stage;
private static DugManMainClass game;
private TextButton tb;
private TextButton tb2;
private TextButton tb3;
private TextButton tb4;
private TextButton tb5;
private TextButton load;
private TextButton newgame;
private TextButton back;
private TextButton saveslot1;
private TextButton saveslot2;
private TextButton saveslot3;
private TextButton loadslot1;
private TextButton loadslot2;
private TextButton loadslot3;
private Window ww;
private Window storywindow;
private Window newgamesaveslotwindow;
private Window loadgameloadslotwindow;
private static float time = 0;
private float temp;



public MainMenuScreen(DugManMainClass game)
{
    this.game = game;
}

@Override
public void dispose() {

    Gdx.app.log(MainMenuScreen.LOG, "Disposing...");
    batch.dispose();
    texture.dispose();
    stage.dispose();

}

@Override
public void resize(int width, int height) {
}

@Override
public void pause() {
}

@Override
public void resume() {
}

@Override
public void render(float delta) {

    Gdx.app.log(MainMenuScreen.LOG, "Rendering...");


    temp += Gdx.graphics.getDeltaTime();
    while(temp>1.0f/60.0f)
    {
        MainMenuScreen.tick();
        temp -=1.0f/60.0f;
    }

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

    stage.act(Gdx.graphics.getDeltaTime());

    batch.setProjectionMatrix(camera.combined);
    batch.begin();
    batch.disableBlending();
    sprite.draw(batch);
    batch.end();

    batch.begin();
    batch.enableBlending();
    stage.draw();
    batch.end();
    // TODO Auto-generated method stub
    }

@Override
public void show() {


    Gdx.app.log(MainMenuScreen.LOG, "Showing SplashScreen...");

    float w = Gdx.graphics.getWidth();
    float h = Gdx.graphics.getHeight();
    camera = new OrthographicCamera(1, h/w);
    //(x,y)
    //camera = new 
    batch = new SpriteBatch();

    stage = new Stage(w,h,true);

    Assets.bgsound.play(1f);

    Gdx.input.setInputProcessor(stage);

    stage.clear();

    texture.setFilter(TextureFilter.Linear, TextureFilter.Linear);

    TextureRegion region = new TextureRegion(texture, 0, 0, texture.getWidth(), texture.getHeight());

    sprite = new Sprite(region);
    sprite.setSize(1f, 1f * sprite.getHeight() / sprite.getWidth());
    sprite.setOrigin(sprite.getWidth()/2, sprite.getHeight()/2);
    sprite.setPosition(-sprite.getWidth()/2, -sprite.getHeight()/2);

    Skin skin = new Skin(Assets.atlas);

    TextButtonStyle ts = new TextButtonStyle();
    ts.up = skin.getDrawable("btnpressed");
    ts.down = skin.getDrawable("btnunpressed");
    ts.font = Assets.menufont2;

    //main menu
    tb = new TextButton("Story mode", ts);
    tb.padTop(5).padBottom(5).padLeft(5).padRight(5);
    tb.addListener(new InputListener() 
    {

            public boolean touchDown(InputEvent event, float x, float y,
                            int pointer, int button) {
                    return true;
            }

            public void touchUp(InputEvent event, float x, float y,
                            int pointer, int button) {

                    time = 0;
                    storywindow.setVisible(true);
                    ww.setVisible(false);
                    Assets.pressedsound.play(1f);


            }
    });


    tb2 = new TextButton("Arcade", ts);
    tb2.padTop(5).padBottom(5).padLeft(5).padRight(5);
    tb2.addListener(new InputListener() 
    {

            public boolean touchDown(InputEvent event, float x, float y,
                            int pointer, int button) {
                    return true;
            }

            public void touchUp(InputEvent event, float x, float y,
                            int pointer, int button) {
                    Assets.pressedsound.play(1f);

            }
    });

    tb3 = new TextButton("Time Trial", ts);
    tb3.padTop(5).padBottom(5).padLeft(5).padRight(5);
    tb3.addListener(new InputListener() 
    {

            public boolean touchDown(InputEvent event, float x, float y,
                            int pointer, int button) {
                    return true;
            }

            public void touchUp(InputEvent event, float x, float y,
                            int pointer, int button) {
                time = 0;
                    Assets.pressedsound.play(1f);

            }
    });

    tb4 = new TextButton("Option",ts);
    tb4.padTop(5).padBottom(5).padLeft(5).padRight(5);
    tb4.addListener(new InputListener() 
    {

            public boolean touchDown(InputEvent event, float x, float y,
                            int pointer, int button) {
                    return true;
            }

            public void touchUp(InputEvent event, float x, float y,
                            int pointer, int button) {

                    Assets.pressedsound.play(1f);

            }
    });


    tb5 = new TextButton("Exit",ts);
    tb5.padTop(5).padBottom(5).padLeft(5).padRight(5);
    tb5.addListener(new InputListener() 
    {

            public boolean touchDown(InputEvent event, float x, float y,
                            int pointer, int button) {
                    return true;
            }

            public void touchUp(InputEvent event, float x, float y,
                            int pointer, int button) {
                    Assets.pressedsound.play(1f);
                    Gdx.app.exit();

            }
    });
    //storymode-newgame
    newgame = new TextButton("New Game", ts);
    newgame.padTop(5).padBottom(5).padLeft(5).padRight(5);
    newgame.addListener(new InputListener() 
     {

        public boolean touchDown(InputEvent event, float x, float y,
                        int pointer, int button) {
                return true;
        }

        public void touchUp(InputEvent event, float x, float y,
                        int pointer, int button) {
                newgamesaveslotwindow.setVisible(true);
                storywindow.setVisible(false);
                Assets.pressedsound.play(1f);

        }
     });

    //newgamesaveslot
    saveslot1 = new TextButton("Save slot 1", ts);
    saveslot1.padTop(5).padBottom(5).padLeft(5).padRight(5);
    saveslot1.addListener(new InputListener() 

     {

        public boolean touchDown(InputEvent event, float x, float y,
                        int pointer, int button) {
                return true;
        }

        public void touchUp(InputEvent event, float x, float y,
                        int pointer, int button) {
                game.setScreen(new LoadingScreen(game));
                Assets.ekek.play(1f);
                Assets.bgsound.stop();

        }
     });

    saveslot2 = new TextButton("Save slot 2", ts);
    saveslot2.padTop(5).padBottom(5).padLeft(5).padRight(5);
    saveslot2.addListener(new InputListener() 
     {

        public boolean touchDown(InputEvent event, float x, float y,
                        int pointer, int button) {
                return true;
        }

        public void touchUp(InputEvent event, float x, float y,
                        int pointer, int button) {
                game.setScreen(new DugManGameScreen(game));
                Assets.ekek.play(1f);
                Assets.bgsound.stop();

        }
     });

    saveslot3 = new TextButton("Save slot 3", ts);
    saveslot3.padTop(5).padBottom(5).padLeft(5).padRight(5);
    saveslot3.addListener(new InputListener() 
     {

        public boolean touchDown(InputEvent event, float x, float y,
                        int pointer, int button) {
                return true;
        }

        public void touchUp(InputEvent event, float x, float y,
                        int pointer, int button) {
                game.setScreen(new DugManGameScreen(game));
                Assets.ekek.play(1f);
                Assets.bgsound.stop();

        }
     });

    //storymode-loadgames
    load = new TextButton("Load game", ts);
    load.padTop(5).padBottom(5).padLeft(5).padRight(5);
    load.addListener(new InputListener() 

     {

        public boolean touchDown(InputEvent event, float x, float y,
                        int pointer, int button) {
                return true;
        }

        public void touchUp(InputEvent event, float x, float y,
                        int pointer, int button) {
                loadgameloadslotwindow.setVisible(true);
                ww.setVisible(false);
                storywindow.setVisible(false);
                Assets.pressedsound.play(1f);


        }
     });

    //loadsaveslot
    loadslot1 = new TextButton("load slot 1", ts);
    loadslot1 .padTop(5).padBottom(5).padLeft(5).padRight(5);
    loadslot1 .addListener(new InputListener() 

     {

        public boolean touchDown(InputEvent event, float x, float y,
                        int pointer, int button) {
                return true;
        }

        public void touchUp(InputEvent event, float x, float y,
                        int pointer, int button) {
                game.setScreen(new DugManGameScreen(game));
                Assets.pressedsound.play(1f);
                Assets.bgsound.stop();

        }
     });

    loadslot2 = new TextButton("load slot 2", ts);
    loadslot2 .padTop(5).padBottom(5).padLeft(5).padRight(5);
    loadslot2 .addListener(new InputListener() 
     {

        public boolean touchDown(InputEvent event, float x, float y,
                        int pointer, int button) {
                return true;
        }

        public void touchUp(InputEvent event, float x, float y,
                        int pointer, int button) {
                game.setScreen(new DugManGameScreen(game));
                Assets.pressedsound.play(1f);
                Assets.bgsound.stop();

        }
     });
    loadslot3 = new TextButton("load slot 3", ts);
    loadslot3 .padTop(5).padBottom(5).padLeft(5).padRight(5);
    loadslot3 .addListener(new InputListener() 
     {

       public boolean touchDown(InputEvent event, float x, float y,
                       int pointer, int button) {
               return true;
       }

       public void touchUp(InputEvent event, float x, float y,
                       int pointer, int button) {
            game.setScreen(new DugManGameScreen(game));
            Assets.pressedsound.play(1f);
            Assets.bgsound.stop();

       }
     });

    back = new TextButton("back", ts);
    back.padTop(5).padBottom(5).padLeft(5).padRight(5);
    back.addListener(new InputListener() 
     {

        public boolean touchDown(InputEvent event, float x, float y,
                        int pointer, int button) {
                return true;
        }

        public void touchUp(InputEvent event, float x, float y,
                        int pointer, int button) {


            if(storywindow.isVisible()==true)
            {
                ww.setVisible(true);
                storywindow.setVisible(false);
                 Assets.pressedsound.play(1f);
            }
            else if(newgamesaveslotwindow.isVisible()==true)
            {
                ww.setVisible(false);
                storywindow.setVisible(true);
                newgamesaveslotwindow.setVisible(false);
                 Assets.pressedsound.play(1f);
            }
            else if(loadgameloadslotwindow.isVisible()==true)
            {
                ww.setVisible(false);
                storywindow.setVisible(true);
                loadgameloadslotwindow.setVisible(false);
                 Assets.pressedsound.play(1f);
            }




        }

     });




    WindowStyle www = new WindowStyle();
    www.background = skin.getDrawable("windowmenu1");
    www.titleFont = Assets.menufont2;

    ww = new Window("", www);
    ww.setPosition(0,0);
    ww.setY(10);
    ww.setX(260);

    ww.defaults().spaceBottom(10);
    ww.padTop(25);
    ww.padLeft(50);
    ww.padRight(50);
    ww.row().fill().expandX();
    ww.add(tb);
    ww.row().fill().expandX();
    ww.add(tb2);
    ww.row().fill().expandX();
    ww.add(tb3);
    ww.row().fill().expandX();
    ww.add(tb4);
    ww.row().fill().expandX();
    ww.add(tb5);
    ww.padBottom(25);
    ww.pack();

    storywindow = new Window("",www);
    storywindow.setPosition(0, 0);
    storywindow.setY(10);
    storywindow.setX(260);
    storywindow.defaults().spaceBottom(10);
    storywindow.padTop(25);
    storywindow.padLeft(50);
    storywindow.padRight(50);
    storywindow.row().fill().expandX();
    storywindow.add(newgame);
    storywindow.row();
    storywindow.add(load);
    storywindow.row();
    storywindow.add(back);
    storywindow.padBottom(25);
    storywindow.pack();
    storywindow.setVisible(false);

    newgamesaveslotwindow = new Window("",www);
    newgamesaveslotwindow.setPosition(0, 0);
    newgamesaveslotwindow.setY(10);
    newgamesaveslotwindow.setX(260);
    newgamesaveslotwindow.defaults().spaceBottom(10);
    newgamesaveslotwindow.padTop(25);
    newgamesaveslotwindow.padLeft(50);
    newgamesaveslotwindow.padRight(50);
    newgamesaveslotwindow.row();
    newgamesaveslotwindow.add(saveslot1);
    newgamesaveslotwindow.row();
    newgamesaveslotwindow.add(saveslot2);
    newgamesaveslotwindow.row();
    newgamesaveslotwindow.add(saveslot3);
    newgamesaveslotwindow.row();
    newgamesaveslotwindow.add(back);
    newgamesaveslotwindow.padBottom(25);
    newgamesaveslotwindow.pack();
    newgamesaveslotwindow.setVisible(false);

    loadgameloadslotwindow = new Window("",www);
    loadgameloadslotwindow.setPosition(0, 0);
    loadgameloadslotwindow.setY(10);
    loadgameloadslotwindow.setX(260);
    loadgameloadslotwindow.defaults().spaceBottom(10);
    loadgameloadslotwindow.padTop(25);
    loadgameloadslotwindow.padLeft(50);
    loadgameloadslotwindow.padRight(50);
    loadgameloadslotwindow.row().fill().expandX();
    loadgameloadslotwindow.add(loadslot1);
    loadgameloadslotwindow.row().fill().expandX();
    loadgameloadslotwindow.add(loadslot2);
    loadgameloadslotwindow.row().fill().expandX();
    loadgameloadslotwindow.add(loadslot3);
    loadgameloadslotwindow.row().fill().expandX();
    loadgameloadslotwindow.add(back);
    loadgameloadslotwindow.padBottom(25);
    loadgameloadslotwindow.pack();
    loadgameloadslotwindow.setVisible(false);


    stage.addActor(storywindow);
    stage.addActor(newgamesaveslotwindow);
    stage.addActor(loadgameloadslotwindow);
    stage.addActor(ww);

}

public static void tick() {

    time++;

    if (time > 60 * 10) {

        game.setScreen(new NewPreviewScreen(game));
        Assets.bgsound.stop();

    }


}

至于我遇到的屏幕无响应的其他问题,这是我的预览屏幕代码。

public class PreviewScreen implements Screen {

private static DugManMainClass game;
private SpriteBatch batch;
private OrthographicCamera camera;
private Texture tx1 = Assets.bgmenu;
private BitmapFont font = Assets.menufont2;
private final static List<String> lines = new ArrayList<String>(); 
private static int time = 0;
private float temp = 0;
private Sprite s;


public PreviewScreen(DugManMainClass game) {

    this.game = game;

    try
    {
        BufferedReader br = new BufferedReader(new InputStreamReader(Gdx.files.internal("previewtext.txt").read()));
        String line = "";
        while ((line = br.readLine()) != null) {
            lines.add(line);
        }
        br.close();
    } 
    catch(Exception e)
    {
        e.printStackTrace();
    }


}


@Override
public void render(float delta) {
    float w = s.getHeight();

    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    temp += Gdx.graphics.getDeltaTime();


    while(temp>1.0f/60.0f)
    {
        PreviewScreen.tick();
        temp -=1.0f/60.0f;

        s.setU(temp+1f);
        s.setU2(temp+1f);

    }





    batch.setProjectionMatrix(camera.combined);
    batch.begin();
    s.draw(batch);

    int yo = time / 4;



    for (int y = 0; y <= s.getHeight() / 12; y++) 
    {
        int yl = yo / 12 + 420 / 12 - y;
        if (yl >= 0 && yl < lines.size()) 
        {
            font.draw(batch,lines.get(yl), (800 - 30 * 12) / 2,  y * 12 + yo % 12);

        }
    }

    batch.end();



}


@Override
public void show() {

    batch = new SpriteBatch();

    float w = 800;
    float h = 420;

    camera = new OrthographicCamera();
    camera.setToOrtho(false, w, h);

    tx1.setWrap(TextureWrap.Repeat, TextureWrap.Repeat);

    s = new Sprite(tx1);
    s.setPosition(0, 0);


    Assets.bgsound3.play(1f);
    // TODO Auto-generated method stub

}


@Override
public void dispose() {

    Assets.dispose();

}

public static void tick() {
    time++;

    if (Gdx.input.isKeyPressed(Keys.ENTER) || Gdx.input.isTouched()) {
        game.setScreen(new splashscreen(game));
        Assets.bgsound3.stop();
    }

    if (time / 4 > lines.size() * 10 + 250) {


        game.setScreen(new splashscreen(game));
        Assets.bgsound3.stop();
    }

}

当它接收到输入或完成显示文本时,它会将屏幕设置为闪屏,闪屏后它将进入介绍和主菜单,反之亦然。

最佳答案

我看到了一些令人担忧的事情,但首先我会关注手头的问题:

private static int time = 0;

您在屏幕中使用了一个静态变量,并且似乎只有在您按下 MainMenuScreen 上的按钮时才将它们重置为 0。这意味着您下次显示屏幕时,该值将导致屏幕切换,并且它将永远来回翻转(并导致很多延迟)。

其他问题:

您在代码中存储了大量的静态状态,这确实令人不悦。这里有个好post (请参阅有关影响的部分)讨论与之相关的问题。大多数编程指南都会建议不要这样做。

考虑调查 better variable names ,甚至使用数组而不是编号变量。它将简化您的代码并使其更具可读性。

您还应该考虑在屏幕类之外重构/委托(delegate)代码。通过这种方式,您可以分离关注点,而不是将所有内容都放入您的类(class)中。现在这不是问题,但随着您扩展游戏,它会很快成为一个问题。

关于android - Libgdx:屏幕管理器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17808429/

相关文章:

php - PHP 命名空间的 use 语句是为了性能还是为了方便?

java - 在 Java 中有效地对图像进行颜色循环

java - Libx GDX 可滚动,带圆形覆盖

android - 在Android中获取外呼电话号码

android - 如何将 HTML5 视频嵌入到 web View 中

java - 在 fragment 中显示两个溢出菜单

java - 如何在android中添加 'java.awt.geom'类?

android - 在处理 Android 模式时 svgs 的 loadShape 失败

C++ 入门(第 5 版)和 C++14

java - 如何在多个屏幕中处理 AssetManager