모두 다시 그리기 및 이벤트 파견 (The Event Dispatch Thread 수행한다 : 즉 더 도움이된다면
public class Main {
public static Game game = new Game();
private static JFrame mainFrame = new JFrame("Snake");
private static MenuPanel menuPanel = new MenuPanel();
public static void main(String[] args) {
mainFrame.setLayout(new BorderLayout());
mainFrame.add(menuPanel, BorderLayout.SOUTH);
mainFrame.pack();
mainFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
mainFrame.setVisible(true);
}
static void playGame(){
mainFrame.setVisible(false);
mainFrame.remove(menuPanel);
menuPanel.setEnabled(false);
ScoreboardPanel scoreboardPanel = new ScoreboardPanel();
mainFrame.add(scoreboardPanel, BorderLayout.NORTH);
game.addPanel(scoreboardPanel);
mainFrame.add(game, BorderLayout.CENTER);
mainFrame.pack();
mainFrame.setVisible(true);
// ANYTHING here stops the frame's rendering until playGame() returns (like game.play() or sleep(x)
}
}
public class MenuPanel extends JPanel {
private class MenuActionListener implements ActionListener {
public void actionPerformed(ActionEvent actionEvent){
switch (actionEvent.getActionCommand()){
case "play":
// TODO This somehow breaks everything. The game loop runs but the window freezes.
Main.playGame();
break;
case "highscore":
break;
case "leveleditor":
break;
case "exit":
System.exit(0);
break;
}
}
}
그리고 여기에 전체 코드입니다 : 여기
는 관련 부분입니다 EDT).
Game.play
메서드는 이벤트 리스너에서 호출되어
sleep
을 사용하여 EDT를 차단하므로 Swing에서 프레임을 다시 칠할 기회가 없습니다.
가장 손쉬운 방법은 Game.play
의 수제 타이머를 javax.swing.Timer으로 대체하는 것입니다. 타이머의 각 진드기에서 게임의 진드기를 에뮬레이트해야합니다. 이렇게하면 Swing이 필요에 따라 다시 칠할 수 있습니다. 미리 타이머를 준비하면 메뉴 청취자가 타이머를 시작하고 중지 할 수 있습니다.
사이드 노트 : 아마도 special menu components 메뉴를 사용하는 것이 좋습니다.
감사합니다. EDT에 대한 정보를 링크하고 설명해 주셔서 감사합니다. 이것은 모든 것들이 스윙에 도움이 될 것입니다! –