Arb*_*bel 6 java windows game-engine libgdx
我正在用libgdx创建一个Java游戏.到目前为止真的很喜欢引擎,但我在拖动游戏窗口时发现了一个问题.渲染似乎停止(这是可以的)但我无法找到在此状态期间调用的任何事件.我有什么方法可以捕获它吗?因为我限制了deltaTime,所以渲染并不是什么大问题,但是对于输入,keyUp事件不会被触发,这会扰乱播放器的移动代码(如果要在拖动窗口时释放按键).有什么我能做的吗?谢谢!
您描述的问题在于LWJGL 显示的本机窗口实现:这个轻量级窗口在移动时不会失去焦点.所以打电话
Display.isActive()
Run Code Online (Sandbox Code Playgroud)
即使显示不再更新,移动窗口仍然会返回true.
我找到了适用于我自己项目的此问题的解决方法.可以通过调用将父Canvas添加到LWJGL显示中
Display.setParent(canvas);
Run Code Online (Sandbox Code Playgroud)
通过这种方法,人们可以通过监听父类来监听窗口事件.将父画布添加到显示中也是LwjglApplet所做的,因此可以在applet中运行libgdx应用程序.
我编写了一个LwjglFrame类,它基本上遵循与LwjglApplet相同的方法,不同之处在于画布被添加到JFrame中:
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Dimension;
import javax.swing.JFrame;
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
public class LwjglFrame extends JFrame{
private final Canvas canvas;
private LwjglApplication app;
public LwjglFrame(final ApplicationListener listener, final LwjglApplicationConfiguration config) {
canvas = new Canvas(){
public final void addNotify () {
super.addNotify();
app = new LwjglApplication(listener, config, canvas);
}
public final void removeNotify () {
app.stop();
super.removeNotify();
}
};
canvas.setIgnoreRepaint(true);
canvas.setFocusable(true);
setLayout(new BorderLayout());
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
add(canvas, BorderLayout.CENTER);
setPreferredSize(new Dimension(config.width, config.height));
pack();
}
public LwjglFrame(final ApplicationListener listener, final boolean useGL2) {
canvas = new Canvas(){
public final void addNotify () {
super.addNotify();
app = new LwjglApplication(listener, useGL2, canvas);
}
public final void removeNotify () {
app.stop();
super.removeNotify();
}
};
canvas.setIgnoreRepaint(true);
canvas.setFocusable(true);
setLayout(new BorderLayout());
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
add(canvas, BorderLayout.CENTER);
}
}
Run Code Online (Sandbox Code Playgroud)
使用此类,可以在JFrame中运行libgdx,然后侦听ComponentEvents.下面是一些示例代码,用于在框架移动时如何创建LwjglFrame并暂停游戏:
public static void main(String[] args) {
// create the config as usual
final LwjglApplicationConfiguration cfg = createConfig();
// create your ApplicationListener as usual
final ApplicationListener application = createApplication();
// create an LwjglFrame with your configuration and the listener
final LwjglFrame frame = new LwjglFrame(application, cfg);
// add a component listener for when the frame gets moved
frame.addComponentListener(new ComponentAdapter() {
@Override
public void componentMoved(ComponentEvent e) {
// somehow pause your game here
MyGame.getInstance().pauseGame();
}
});
// set the frame visible
frame.setVisible(true);
}
Run Code Online (Sandbox Code Playgroud)
这种方法的缺点是,需要一些专用的暂停状态,一旦窗口移动就会进入.然后,用户必须手动退出该暂停状态以继续游戏.好处是,即使一个人没有暂停游戏,屏幕也会至少得到更新,而一个人正在移动窗口(除了使用lwjgl原生帧时).
我还没有找到一种可靠的方法,只在窗口移动期间暂停游戏,并在移动完成后自动继续循环.这里的问题是,JFrame不发送用于移动帧的开/关事件,而是在窗口移动时连续通知移动事件.
编辑
你也可以让你的com.badlogic.gdx.Game实现ComponentListener:
public class MayGame extends Game implements ComponentListener{
public void componentResized(ComponentEvent e) {}
public void componentMoved(ComponentEvent e) {
System.out.println("Window moved!");
// pause the game somehow
}
public void componentShown(ComponentEvent e) {}
public void componentHidden(ComponentEvent e) {}
}
Run Code Online (Sandbox Code Playgroud)
然后你就像这样创建你的游戏:
public static void main(String[] args) {
// create the config as usual
final LwjglApplicationConfiguration cfg = createConfig();
// create your Game
final game MyGame = new MyGame();
// create an LwjglFrame with your game and the configuration
final LwjglFrame frame = new LwjglFrame(game, cfg);
// add the game as a component listener
frame.addComponentListener(game);
// set the frame visible
frame.setVisible(true);
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2672 次 |
最近记录: |