我们正在使用libgdx为Android设备制作游戏原型。对于屏幕管理,我们使用带有屏幕名称的枚举来获取ScreenManager类的抽象层。所以你可以做这样的事情来显示一个新的屏幕并隐藏旧屏幕:ScreenManager.getInstance().show( Screens.LOGIN );
现在我们要使用设备的后退按钮跳回屏幕或退出应用程序。所以我们想在每个枚举值中创建一个字段来声明parentScreen并在按下后退按钮时使用它。不幸的是,它本身不能使用enum自己的字段,我们在Cannot refer to the static enum field Screens.LOGIN within an initializer
上收到以下错误:protected Screens parentScreen = Screens.LOGIN;
。也许任何人都知道如何解决这个问题。
这是实际的枚举:
/**
* Used to hide actual implementations of Screen interface and expose only "pointer objects".
* All of them are declared with package-private class modifier.
*/
public enum Screens {
SPLASH {
@Override
protected Screen getScreenInstance( MyGdxGame game ) {
return new SplashScreen( game );
}
},
LOGIN {
@Override
protected Screen getScreenInstance( MyGdxGame game ) {
return new LoginScreen( game );
}
},
GAME {
protected Screens parentScreen = Screens.LOGIN;
@Override
protected Screen getScreenInstance( MyGdxGame game ) {
return new GameScreen( game );
}
},
CREDITS {
protected Screens parentScreen = Screens.LOGIN;
@Override
protected Screen getScreenInstance( MyGdxGame game ) {
return new CreditsScreen( game );
}
};
protected Screens parentScreen = null;
/** Every enum member musts override this method and it will be visible only inside the package */
protected abstract Screen getScreenInstance( MyGdxGame game );
}
此功能应显示父屏幕:
/**
* Execute when the user clicks the back button
* Default called by the AbstractScreen Class
*/
public void backButton() {
this.show( this.currentScreen.parentScreen );
}
提前感谢您的建议!
答案 0 :(得分:2)
有多种可能性。我最喜欢的是使用构造函数,因为它的文本较少,但更容易理解:
public enum Screens {
SPLASH(Screens.LOGIN) {
@Override
protected Screen getScreenInstance( MyGdxGame game ) {
return new SplashScreen( game );
}
},
LOGIN(null) {//...}
;//this semi-colon is expected after the enum values
private final Screens parentScreen;
Screens(Screens parent){//Constructor
parentScreen = parent;
}
public Screens getParentScreen(){
return parentScreen;
}
protected abstract Screen getScreenInstance( MyGdxGame game );
另一个解决方案是声明一个抽象方法getParentScreen():
public enum Screens {
SPLASH {
@Override
protected Screen getScreenInstance( MyGdxGame game ) {
return new SplashScreen( game );
}
@Override
protected Screen getParentScreen() {
return Screens.LOGIN;
}
},
//...
;
protected abstract Screen getScreenInstance( MyGdxGame game );
protected abstract Screen getParentScreen();
答案 1 :(得分:1)
你可以试试这个:
/**
* Used to hide actual implementations of Screen interface and expose only "pointer objects".
* All of them are declared with package-private class modifier.
*/
public enum Screens {
SPLASH {
@Override
protected Screen getScreenInstance( MyGdxGame game ) {
return new SplashScreen( game );
}
},
LOGIN {
@Override
protected Screen getScreenInstance( MyGdxGame game ) {
return new LoginScreen( game );
}
},
GAME {
@Override
protected Screen getParentScreen() {
return Screens.LOGIN;
}
@Override
protected Screen getScreenInstance( MyGdxGame game ) {
return new GameScreen( game );
}
},
CREDITS {
@Override
protected Screen getParentScreen() {
return Screens.LOGIN;
}
@Override
protected Screen getScreenInstance( MyGdxGame game ) {
return new CreditsScreen( game );
}
};
protected Screen getParentScreen() {
return null;
}
/** Every enum member musts override this method and it will be visible only inside the package */
protected abstract Screen getScreenInstance( MyGdxGame game );
}
通过使用方法(而不是字段),您可以克服限制。
注意强> 此外,做一些事情:
public enum X {
VALUE1 {
protected String fieldYYY = ...;
}
protected String fieldYYY = ...;
}
不是一件好事。当编译枚举时,它们大致转换为具有子类X.VALUE1,X.VALUE2,X.VALUEN的抽象超类X ...如果在超类(X)中声明一个字段,然后在子类中再次声明它你并没有真正覆盖它,但你最终得到了2个字段,具有相同的名称......第一个(X中的一个,超类)被范围隐藏......但它就在那里!如果这些字段是可变的 - 不是枚举的情况 - 你可能会释放混乱(某些代码引用你的超类中的那些,其他代码就是你拥有的代码)!