Best way to implement game loop without freezing UI thread

前端 未结 3 1907
余生分开走
余生分开走 2021-01-12 01:10

I\'m trying to make a simple 2D game in Java.

So far I have a JFrame, with a menubar, and a class which extends JPanel and overrides it\'s

3条回答
  •  时光说笑
    2021-01-12 01:26

    You need one thread for you game loop and one thread to handle Swing UI events like mouse clicks and keypresses.

    When you use the Swing API, you automatically get an additional thread for your UI called the event dispatch thread. Your callbacks are executed on this thread, not the main thread.

    Your main thread is fine for your game loop if you want the game to start automatically when the programs runs. If you want to start and stop the game with a Swing GUI, then have then main thread start a GUI, then the GUI can create a new thread for the game loop when the user wants to start the game.

    No, your menu bar will not freeze up if you put your game loop in the main thread. Your menu bar will freeze up if your Swing callbacks take a long time to finish.

    Data that is shared between the threads will need to be protected with locks.

    I suggest you factor your Swing code into its own class and only put your game loop inside your main class. If you're using the main thread for your game loop, this is a rough idea of how you could design it.

    import javax.swing.JFrame;
    import javax.swing.JMenu;
    import javax.swing.JMenuBar;
    import javax.swing.JMenuItem;
    
    class GUI extends JFrame {
        GameCanvas canvas = new GameCanvas();
        final int FRAME_HEIGHT = 400;
        final int FRAME_WIDTH = 400;
    
    
        public GUI() {
            // build and display your GUI
            super("Game");
    
            JMenuBar menuBar = new JMenuBar();
            JMenu fileMenu = new JMenu("File");
            JMenuItem startMenuItem = new JMenuItem("Pause");
            menuBar.add(fileMenu);
            fileMenu.add(startMenuItem);
    
            super.add(canvas);
            super.setVisible(true);
            super.setSize(FRAME_WIDTH, FRAME_WIDTH);
            super.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            super.setJMenuBar(menuBar);
        }
    }
    
    public class Main {
    
        public static void main(String args[]) {
            GUI ui = new GUI(); // create and display GUI        
    
            gameLoop(); // start the game loop
        }
    
        static void gameLoop() {
            // game loop    
        }
    }
    

提交回复
热议问题