Libgdx - 当我使用.isPressed()时stackOverFlow

时间:2017-02-01 13:43:37

标签: java android libgdx touch-event

我正在使用最新版本的Libgdx对菜单进行编码。每个屏幕(MainMenuScreen,OptionsMenuScreen,CreditsMenuScreen)都包含一些按钮。每个按钮都应该改变屏幕。 如果我在MainMenuScreen上并按“信用”,我会获得CreeditsMenuScreen。但是当我使用“后退按钮”返回主菜单时,我收到stackOverflow错误。

以下是代码的一些部分:

//In the MainMenuScreen.java: 
    if( creditsButton.isPressed() )  {
      menuManager.setScreen("credits");
    }

//In the CreditsMenuScreen.java I have
    if( backButton.isPressed() )  {
                menuManager.setScreen("main");
            }

这是错误。我认为它与touchevent相关但我不知道如何解决它..

Exception in thread "LWJGL Application" com.badlogic.gdx.utils.GdxRuntimeException: java.lang.StackOverflowError
    at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:133)
Caused by: java.lang.StackOverflowError
    at org.lwjgl.BufferChecks.checkDirect(BufferChecks.java:138)
    at org.lwjgl.opengl.GL20.glVertexAttribPointer(GL20.java:856)
    at com.badlogic.gdx.backends.lwjgl.LwjglGL20.glVertexAttribPointer(LwjglGL20.java:829)
    at com.badlogic.gdx.graphics.glutils.ShaderProgram.setVertexAttribute(ShaderProgram.java:657)
    at com.badlogic.gdx.graphics.glutils.VertexArray.bind(VertexArray.java:115)
    at com.badlogic.gdx.graphics.Mesh.bind(Mesh.java:380)
    at com.badlogic.gdx.graphics.Mesh.bind(Mesh.java:371)
    at com.badlogic.gdx.graphics.Mesh.render(Mesh.java:479)
    at com.badlogic.gdx.graphics.Mesh.render(Mesh.java:449)
    at com.badlogic.gdx.graphics.g2d.SpriteBatch.flush(SpriteBatch.java:975)
    at com.badlogic.gdx.graphics.g2d.SpriteBatch.setTransformMatrix(SpriteBatch.java:1037)
    at com.badlogic.gdx.scenes.scene2d.Group.resetTransform(Group.java:210)
    at com.badlogic.gdx.scenes.scene2d.Group.draw(Group.java:58)
    at com.badlogic.gdx.scenes.scene2d.Stage.draw(Stage.java:128)
    at com.rander.GameMenu.MainMenuScreen.show(MainMenuScreen.java:86)
    at com.badlogic.gdx.Game.setScreen(Game.java:61)
    at com.rander.GameMenu.MenuManager.setScreen(MenuManager.java:44)
    at com.rander.GameMenu.CreditsMenuScreen.show(CreditsMenuScreen.java:74)

2 个答案:

答案 0 :(得分:3)

当你从一个屏幕切换回另一个屏幕时,另一个屏幕上没有调用update()因为它上次调用setScreen()以响应其按下按钮,所以它的按钮仍然是按下。因此,屏幕将继续来回切换,因为两个按钮都处于按下状态,并且永远不会有机会释放。

不是使用isPressed(),而是在每个按钮上添加ChangeListener,并在侦听器中覆盖public void changed (ChangeEvent event, Actor actor)并在那里更改屏幕。像这样:

/// in screen constructor
creditsButton.addListener(new ChangeListener(){
    public void changed (ChangeEvent event, Actor actor){
        menuManager.setScreen("credits");
    }
});

答案 1 :(得分:0)

我解决了这个问题(我在渲染方法中添加了super.render())但现在,当鼠标在窗口中移动时,每个屏幕都会轻弹。

这是MenuManager类:

public class MenuManager {
    private static MenuManager uniqueInstance;
    HashMap<String, Screen> menuMap;
    Game game;

    private MenuManager(Game game) {
        this.game = game;
        menuMap = new HashMap<String, Screen>();

    }

    public static MenuManager getInstance(Game game) {
        if(uniqueInstance == null) {
            uniqueInstance = new MenuManager(game);
        }
        return uniqueInstance;
    }

    public void addMenuItem(String type, Screen screen) {
        menuMap.put(type, screen);
    }
    public void removeMenuItem(String type) {
        Screen remove = menuMap.remove(type);
    }

    public Screen getScreen(String type) {
        return menuMap.get(type);
    }

    public void setScreen(String type) {
        game.setScreen(getScreen(type));

    }

}

以下是主要课程:

public class TestGame extends Game {
    MenuManager menuManager;
    Screen mainMenuScreen;
    Screen creditsMenuScreen;
    Screen optionsMenuScreen;


    @Override
    public void create() {
        Gdx.graphics.setContinuousRendering(false);
        menuManager = MenuManager.getInstance(this);
        mainMenuScreen = new MainMenuScreen(menuManager);
        creditsMenuScreen = new CreditsMenuScreen(menuManager);
        optionsMenuScreen = new OptionsMenuScreen(menuManager);
        menuManager.addMenuItem("main", mainMenuScreen);
        menuManager.addMenuItem("credits", creditsMenuScreen);
        menuManager.addMenuItem("options", optionsMenuScreen);
        //Gdx.gl.glClearColor(0, 0, 0, 0);
        //Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        setScreen(menuManager.getScreen("main"));
    }

    @Override
    public void resize(int width, int height) {
        super.resize(width, height);

    }

    @Override
    public void render () {
        super.render(); //important!

    }


    @Override
    public void pause() {
        //super.pause();
    }

    @Override
    public void resume() {
        //super.resume();
    }

    @Override
    public void dispose () {
        super.dispose();
    }


}