Как я могу запустить метод с несколькими потоками из слушателя действия - PullRequest
0 голосов
/ 08 января 2020

JFrame с прослушивателем действий при нажатии кнопки GUI зависает и открывает пустой белый экран вместо моей шахматной игры

private static void createAndShowGui() {
frame = new JFrame();
frame.getContentPane().setForeground(new Color(153, 153, 153));
frame.getContentPane().setBackground(new Color(51, 51, 51));
frame.setBounds(100, 100, 450, 600);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().setLayout(null);

// при нажатии кнопки gui frezze и вызываемый метод не работает

btnSingle = new JButton("Single Player");
        btnSingle.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                GamePlay.play(1);
            }
        });
}

// метод из другого класса, который запускает игру в шахматы, работает нормально при обычном вызове, но не при вызове из GUI

public static void startGame(ChessPlayer p1, ChessPlayer p2,Board board) {


        p1.update(board);
        p2.update(board);

        ChessPlayer[] players = new ChessPlayer[2];
        players[1] = p1.getColor() == 1 ? p1 : p2;
        players[0] = p2.getColor() == 0 ? p2 : p1;

// бесконечный l oop никогда выходит, пока (true) {

            if(board.getCurrentColor() ==1)
                p1.start();
            else
                p2.start();

            if(board.getCurrentColor() ==0)
                p1.stop();
            else 
                p2.stop();

//waits for player to make move before executing
            PieceMove m = players[board.getCurrentColor()].makePieceMove(board);

            board.apply(m);
            p1.update(board);
            p2.update(board);

            if (board.checkMate(players[board.getCurrentColor()].getColor()) || p1.isTimeOut()) {
                if(players[board.getCurrentColor()].getColor()==1){
                    if(board.checkMate(players[board.getCurrentColor()].getColor())) {
                        JOptionPane.showMessageDialog(null, "Checkmate, you Lose!  Player 2 - Black Wins!");

                    }
                    else {
                        JOptionPane.showMessageDialog(null, "Player 2's timer ran out, You Win!!!");

                    }

                    p1.close();
                    p2.close();
                }
                else {
                    if(board.checkMate(players[board.getCurrentColor()].getColor())) {
                        JOptionPane.showMessageDialog(null, "Checkmate, you Win!!! Player 2 - Black Loses!");

                    }
                    else {
                        JOptionPane.showMessageDialog(null, "Your Timer ran out you lose!!  Player 2 - Black Wins!");

                    }
                    p1.close();
                    p2.close();
                }
            }


        }
    }

1 Ответ

0 голосов
/ 10 января 2020

Проблема в том, что GamePlay не был запущен как отдельный поток.

Вы должны извлечь игровой процесс из Runnable и переписать метод run.

Выглядит это так:

public class GamePlay implements Runnable {
   public GamePlay(int param){
      // init your settings here
   }

   public void play(){
      // start Game here
   }

   @Override
   public void run() {
      play();
   }
}

Чтобы начать игру, необходимо создать новую тему.

public void actionPerformed(ActionEvent e) {
   // generate Game
   GamePlay game = new GamePlay(1);
   // generate Thread
   Thread thread = new Thread(game);
   // run thread
   thread.run();
}
...