Java Libgdx屏幕管理器
我正在用LibGdx做一个游戏,我会经常切换屏幕,所以我想我应该做一个自己的小屏幕管理器。不过,要设置屏幕,我需要参考Java Libgdx屏幕管理器,java,libgdx,Java,Libgdx,我正在用LibGdx做一个游戏,我会经常切换屏幕,所以我想我应该做一个自己的小屏幕管理器。不过,要设置屏幕,我需要参考LibGdx游戏。我对经理现在的样子不满意,我一定有办法做到这一点,而不必发送两次游戏对象 我的代码: public static void setScreen(Screen screen, Game game){ if(currentScreen != null){ currentScreen.dispose();
LibGdx游戏
。我对经理现在的样子不满意,我一定有办法做到这一点,而不必发送两次游戏对象
我的代码:
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),Id需要向屏幕的构造函数发送一个游戏对象,如下所示:
ScreenManager.setScreen(新游戏屏幕(游戏),游戏)代码>
我内心的完美主义者希望能够这样称呼它:
ScreenManager.setScreen(新游戏屏幕(),游戏
或
ScreenManager.setScreen(新游戏屏幕(游戏)
有人能想出一个方法来实现这一点吗?或者我只是在痴迷于一些我可以让它成为现实的东西?你可以创建自己的屏幕类型,它将返回游戏并实现屏幕方法
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));
或
您可以创建自己的屏幕类型,该类型将返回游戏并实现屏幕方法
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));
或
您可以查看此项目:。检查它,看看您是否可以使用它来解决问题。您可以查看此项目:。检查它,看看您是否可以使用它来解决问题。您可以使用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);
}
您可以使用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);
}
我已经实现了我自己的ScreenManager
,也实现了我自己的Screen
,它扩展了Group
。我使用的协议是为最小化对象实例化而设计的:
- 所有
Screen
对象都应该是单例对象。我将它们的构造函数包设置为私有,只有ScreenManager
可以直接实例化它们。它们存储在哈希映射中
- 在实例化时只实例化一次
屏幕
的对象,并将它们添加到屏幕
(因此,我的所有组件也在扩展参与者
)
- 实现一个方法
getInputProcessors()
,该方法返回自定义屏幕使用的、不会被后台隐式触发的任何自定义处理程序。(实际上,我为其他对象提供了一组类似的函数,但为了清晰起见,这里将其删除。)
- 我的
ScreenManager
在需要调出屏幕时调用show
和hide
,这实际上不需要做任何事情,但可以为自定义行为覆盖
下面的工作方式是,我的屏幕管理器有一个阶段
。管理器只需清除屏幕之间的阶段对象并添加新阶段,因为它是一个组
(这是一个参与者
,可以包含更多参与者)
在不深入太多细节的情况下,这将涉及到解释我的框架中的许多内部类,下面是一个一般过程,其中抽象出的功能可能与您无关(并允许传入外部屏幕对象):
private final AtomicReference curScreen=。。。;
...
公共静态布尔集(屏幕下一个屏幕)
{
mutex.lock();//防止多线程问题
尝试
{
//确保提供的屏幕有效
最终屏幕cur=curScreen.get();
if(null==nextScreen | | nextScreen.equals(cur))返回false;
//自动更新当前屏幕参考
如果(!curScreen.compareAndSet(cur,nextScreen))返回false;
//记录back()操作的屏幕并将其添加到后台
if(null!=cur)screenStack.push(cur);
stage.clear();
stage.add(nextScreen);
//从后台抓取任何自定义输入处理器并构建输入处理程序
final inputProcessors=nextScreen.getInputProcessors();
最终InputProcessor[]processors=inputProcessors.toArray(新的InputProcessor[inputProcessors.size()+1]);
处理器[inputProcessors.length-1]=阶段;
//通知gdx我们的新输入目标
setInputProcessor(新的输入多路复用器(处理器));
返回true;
}
catch(Throwable t){Log.error(t);返回false;}
最后{mutex.unlock();}
}
请注意使用了AtomicReference
和自定义Mutex
对象,这是由于更复杂的情况可以提高效率。您可以将Mutex
交换为ReentrantLock
,并将AtomicReference
直接转换为屏幕
,以实现更简单的应用程序。<>我已经实现了我自己的ScreenManager
,也实现了我自己的Screen
,它扩展了Group
。我使用的协议是为最小化对象实例化而设计的:
- 所有
Screen
对象都应该是单例对象。我将它们的构造函数包设置为私有,只有ScreenManager
可以直接实例化它们。它们存储在哈希映射中
- 在实例化时只实例化一次
屏幕
的对象,并将它们添加到屏幕
(因此,我的所有组件也在扩展参与者
)
- 实现一个方法
getInputProce