我正在开发一个LibGdx游戏,我会切换屏幕很多,所以我想我会做自己的小屏幕管理器。但是,要设置屏幕,我需要引用LibGdx Game
。我不满意经理现在看起来如何,必须有某种方式我可以实现这一点,而无需两次发送游戏对象。
我的代码:
public static void setScreen(Screen screen, Game game){
if(currentScreen != null){
currentScreen.dispose();
System.out.println("Screen disposed");
}
currentScreen = screen;
game.setScreen(currentScreen);
}
现在从另一个屏幕设置一个屏幕(例如从menuScreen设置gameScreen)我需要将游戏对象发送到屏幕的构造函数,如下所示:
ScreenManager.setScreen(new GameScreen(game), game);
我的完美主义者希望能够像这样称呼它:
ScreenManager.setScreen(new GameScreen(), game
或
ScreenManager.setScreen(new GameScreen(game)
有人能想到办法吗?或者我只是迷恋一些我可能会成为的东西?
答案 0 :(得分:4)
您可以创建自己的屏幕类型,该类型将返回游戏并将实现屏幕方法。
package ***;
import com.badlogic.gdx.Screen;
import ***.GameCore;
public class MyScreen implements Screen {
GameCore game;
public MyScreen(GameCore game) {
this.game = game;
}
public GameCore getGameCore(){
return this.game;
}
/*
Methods implemented from Screen (render , hide , dispose etc...)
*/
}
然后创建将扩展MyScreen的屏幕类型。
package ***;
import ***.GameCore;
public class MenuScreen extends MyScreen{
public MenuScreen (GameCore game) {
super(game);
}
/*
Methods implemented from Screen (render , hide , dispose etc...)
*/
}
在GameCore中创建MenuScreen的实例。
MenuScreen menuScreen = new MenuScreen(this);
之后你可以做你想要的技巧。
public static void setScreen(Screen screen){
if(currentScreen != null){
currentScreen.dispose();
System.out.println("Screen disposed");
}
currentScreen = screen;
currentScreen.getGameCore().setScreen(currentScreen);
}
然后您可以自由设置屏幕
ScreenManager.setScreen(new MenuScreen(game));
或
ScreenManager.setScreen(menuScreen);//if you have already created an instance of menu
答案 1 :(得分:2)
我已经实现了自己的ScreenManager
,并实现了我自己的Screen
扩展Group
。我使用的协议是为最小化对象实例化而设计的:
Screen
个对象都应该是单身。我使他们的构造函数包私有,只有ScreenManager
可以直接实例化它们。它们存储在哈希映射中。Screen
个对象进行一次实例化,然后将其添加到Screen
(因此我的所有组件也都在扩展Actor
)。getInputProcessors()
,该方法返回自定义Screen
使用的任何自定义处理程序,这些处理程序不会被阶段隐式触发。 (实际上我为其他对象设置了一组类似的功能,但为了清楚起见,这里删除了。)ScreenManager
调用show
和hide
当需要换出屏幕时,实际上不需要做任何事情,但可以覆盖自定义行为。这下面的工作方式是我的ScreenManager有一个Stage
。管理员只需清除屏幕之间的舞台对象并添加新舞台,因为它是Group
(可以包含更多演员的Actor
)。
如果不涉及太多细节,这将涉及在我的框架中解释许多内部类,这里是抽象的功能的一般过程,可能与您无关(并允许传入外部Screen对象):
private final AtomicReference<Screen> curScreen = ...;
...
public static boolean set(Screen nextScreen)
{
mutex.lock(); // prevent multi-threading issues
try
{
// ensure the provided screen is valid
final Screen cur = curScreen.get();
if (null == nextScreen || nextScreen.equals(cur)) return false;
// atomically update the current screen reference
if (!curScreen.compareAndSet(cur, nextScreen)) return false;
// record the screen for back() operations and add it to the stage
if (null != cur) screenStack.push(cur);
stage.clear();
stage.add(nextScreen);
// grab any custom input processors from the stage and build an input handler
final inputProcessors = nextScreen.getInputProcessors();
final InputProcessor[] processors = inputProcessors.toArray(new InputProcessor[inputProcessors.size()+1]);
processors [inputProcessors.length-1] = stage;
// inform gdx of our new input target
Gdx.input.setInputProcessor(new InputMultiplexer(processors));
return true;
}
catch (Throwable t) { Log.error(t); return false; }
finally { mutex.unlock(); }
}
请注意使用AtomicReference
和自定义Mutex
对象,这是由于可以获得效率的更复杂情况。您可以将Mutex
替换为ReentrantLock
,并将AtomicReference
直接转换为Screen
以获得更简单的应用。
答案 2 :(得分:0)
您可以查看此项目:https://github.com/edesdan/libgdx-playground。检查一下,看看你是否可以用它来解决你的问题。
答案 3 :(得分:0)
您可以使用Gdx.app.getApplicationListener()将其投射到游戏中来获取游戏实例。此外,您的代码可以变得更清晰,将setScreen方法更改为:
public static void setScreen(Screen screen){
if(currentScreen != null){
currentScreen.dispose();
System.out.println("Screen disposed");
}
currentScreen = screen;
Game game = (Game)Gdx.app.getApplicationListener();
game.setScreen(currentScreen);
}