我正在使用最新版本的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)
答案 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();
}
}