Libgdx pause / resume is not called when dragging a window (Windows)

I am creating a Java game with libgdx. I actually like the engine so far, but I noticed a problem when dragging the game window. Rendering seems to stop (this is normal), but I cannot find any events that are fired during this state. Is there any way to capture it? This is not very important for rendering, since I close deltaTime, but keyUp does not start for event input, which clogs my motion code for the player (if you want to release the keys when dragging the window). Can i do something? Thanks!

+6
source share
1 answer

The problem you are describing is implementing your own LWJGL Display window: this lightweight window does not lose focus while it moves. Therefore challenge

Display.isActive() 

when moving the window will still return true, even if the display is no longer updated.

I found a workaround for this problem that works for my own project. You can add a parent Canvas to the LWJGL display by calling

 Display.setParent(canvas); 

With this approach, you can listen to window events while listening to the parent class. Adding a parent canvas to the display is also that of LwjglApplet , so you can run libgdx applications inside the applet.

I wrote the LwjglFrame class, which essentially follows the same approach as LwjglApplet, with the difference that the canvas is added to the 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); } } 

With this class, you can run libgdx inside a JFrame, and then listen to ComponentEvents. Here is a sample code to create an LwjglFrame and pause the game each time the frame is moved:

 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); } 

The disadvantage of this approach is that it requires some highlighted pause state, which is entered after moving the window. This pause state must be manually displayed by the user to continue the game. The good news is that even if you do not pause the game, the screen will at least refresh, while one moves the window (except for using the lwjgl native frame).

I have not yet found a reliable way to pause the game only while the window is moving and automatically continue the cycle after the movement is completed. The problem here is that the JFrame does not send on / off events to move the frame, but instead constantly notifies you of motion events when the window moves around.

EDIT

You can also make your com.badlogic.gdx.Game implemented by 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) {} } 

Then you create your game as follows:

 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); } 
+5
source

All Articles