Java贪吃蛇游戏showGameOverDialog随机触发问题求助
Java贪吃蛇游戏随机触发Game Over对话框问题求助
我花了一整天开发了这个Java贪吃蛇游戏,这是我第一个稍复杂的编程项目。游戏包含高分系统和可用菜单,是跟随教程逐步完成的。但当前存在一个异常问题:showGameOverDialog会随机触发,无论游戏处于何种状态——比如在菜单界面、吃苹果时都会弹出。我尝试调整该对话框相关代码,但未能找到解决方法,希望有人能帮忙排查修复。
以下是完整代码:
import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.io.*; import java.util.ArrayList; import java.util.List; public class SnakeGame extends JFrame { private CardLayout cardLayout; private JPanel mainPanel; private GamePanel gamePanel; private MainMenuPanel mainMenuPanel; private HighScorePanel highScorePanel; private OptionsPanel optionsPanel; private boolean fullscreen = false; public SnakeGame() { setTitle("Snake Game"); setSize(800, 800); setResizable(false); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); cardLayout = new CardLayout(); mainPanel = new JPanel(cardLayout); gamePanel = new GamePanel(this); mainMenuPanel = new MainMenuPanel(this); highScorePanel = new HighScorePanel(this); optionsPanel = new OptionsPanel(this); mainPanel.add(mainMenuPanel, "MainMenu"); mainPanel.add(gamePanel, "Game"); mainPanel.add(highScorePanel, "HighScores"); mainPanel.add(optionsPanel, "Options"); add(mainPanel); cardLayout.show(mainPanel, "MainMenu"); setLocationRelativeTo(null); setVisible(true); } public void showCard(String card) { cardLayout.show(mainPanel, card); } public void toggleFullscreen() { dispose(); if (fullscreen) { setUndecorated(false); setExtendedState(JFrame.NORMAL); setSize(800, 800); } else { setUndecorated(true); setExtendedState(JFrame.MAXIMIZED_BOTH); } fullscreen = !fullscreen; setVisible(true); } public static void main(String[] args) { new SnakeGame(); } } class MainMenuPanel extends JPanel { public MainMenuPanel(SnakeGame frame) { setLayout(new GridLayout(4, 1)); JButton startButton = new JButton("Spiel starten"); JButton highScoreButton = new JButton("Highscores"); JButton optionsButton = new JButton("Optionen"); JButton exitButton = new JButton("Spiel beenden"); startButton.addActionListener(e -> frame.showCard("Game")); highScoreButton.addActionListener(e -> frame.showCard("HighScores")); optionsButton.addActionListener(e -> frame.showCard("Options")); exitButton.addActionListener(e -> System.exit(0)); add(startButton); add(highScoreButton); add(optionsButton); add(exitButton); } } class OptionsPanel extends JPanel { public OptionsPanel(SnakeGame frame) { setLayout(new GridLayout(2, 1)); JButton toggleFullscreenButton = new JButton("Vollbild / Fenster"); JButton backButton = new JButton("Zurück zum Hauptmenü"); toggleFullscreenButton.addActionListener(e -> frame.toggleFullscreen()); backButton.addActionListener(e -> frame.showCard("MainMenu")); add(toggleFullscreenButton); add(backButton); } } class HighScorePanel extends JPanel { private SnakeGame frame; private JTextArea highScoreArea; private static final String HIGHSCORE_FILE = "highscore.txt"; public HighScorePanel(SnakeGame frame) { this.frame = frame; setLayout(new BorderLayout()); highScoreArea = new JTextArea(); highScoreArea.setEditable(false); JButton backButton = new JButton("Zurück zum Hauptmenü"); backButton.addActionListener(e -> frame.showCard("MainMenu")); add(new JScrollPane(highScoreArea), BorderLayout.CENTER); add(backButton, BorderLayout.SOUTH); loadHighScores(); } private void loadHighScores() { try (BufferedReader reader = new BufferedReader(new FileReader(HIGHSCORE_FILE))) { highScoreArea.read(reader, null); } catch (IOException e) { highScoreArea.setText("Keine Highscores gefunden."); } } } class GamePanel extends JPanel implements ActionListener { private static final int TILE_SIZE = 25; private static final int BOARD_WIDTH = 30; private static final int BOARD_HEIGHT = 30; private static final int DELAY = 140; private static final String HIGHSCORE_FILE = "highscore.txt"; private final List<Point> snake = new ArrayList<>(); private Point food; private char direction = 'R'; private Timer timer; private int score = 0; private int highScore = 0; private SnakeGame frame; public GamePanel(SnakeGame frame) { this.frame = frame; setPreferredSize(new Dimension(TILE_SIZE * BOARD_WIDTH, TILE_SIZE * BOARD_HEIGHT)); setBackground(Color.BLACK); setFocusable(true); loadHighScore(); initGame(); addKeyListener(new KeyAdapter() { @Override public void keyPressed(KeyEvent e) { int key = e.getKeyCode(); if (key == KeyEvent.VK_LEFT && direction != 'R') { direction = 'L'; } else if (key == KeyEvent.VK_RIGHT && direction != 'L') { direction = 'R'; } else if (key == KeyEvent.VK_UP && direction != 'D') { direction = 'U'; } else if (key == KeyEvent.VK_DOWN && direction != 'U') { direction = 'D'; } } }); timer = new Timer(DELAY, this); timer.start(); } private void loadHighScore() { try (BufferedReader reader = new BufferedReader(new FileReader(HIGHSCORE_FILE))) { highScore = Integer.parseInt(reader.readLine()); } catch (IOException | NumberFormatException e) { highScore = 0; } } private void saveHighScore() { try (BufferedWriter writer = new BufferedWriter(new FileWriter(HIGHSCORE_FILE))) { writer.write(String.valueOf(highScore)); } catch (IOException e) { e.printStackTrace(); } } private void initGame() { snake.clear(); snake.add(new Point(5, 5)); snake.add(new Point(4, 5)); snake.add(new Point(3, 5)); score = 0; placeFood(); } private void placeFood() { int x = (int) (Math.random() * BOARD_WIDTH); int y = (int) (Math.random() * BOARD_HEIGHT); food = new Point(x, y); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); drawBoard(g); drawSnake(g); drawFood(g); drawScore(g); } private void drawBoard(Graphics g) { g.setColor(Color.GREEN); for (int x = 0; x < BOARD_WIDTH; x++) { for (int y = 0; y < BOARD_HEIGHT; y++) { g.drawRect(x * TILE_SIZE, y * TILE_SIZE, TILE_SIZE, TILE_SIZE); } } } private void drawSnake(Graphics g) { g.setColor(Color.RED); for (Point point : snake) { g.fillRect(point.x * TILE_SIZE, point.y * TILE_SIZE, TILE_SIZE, TILE_SIZE); } } private void drawFood(Graphics g) { g.setColor(Color.YELLOW); g.fillRect(food.x * TILE_SIZE, food.y * TILE_SIZE, TILE_SIZE, TILE_SIZE); } private void drawScore(Graphics g) { g.setColor(Color.WHITE); g.setFont(new Font("Helvetica", Font.BOLD, 20)); g.drawString("Score: " + score, 10, getHeight() - 10); g.drawString("Highscore: " + highScore, 10, getHeight() - 40); } @Override public void actionPerformed(ActionEvent e) { moveSnake(); checkCollision(); repaint(); } private void moveSnake() { Point head = new Point(snake.get(0)); switch (direction) { case 'L': head.x--; break; case 'R': head.x++; break; case 'U': head.y--; break; case 'D': head.y++; break; } snake.add(0, head); snake.remove(snake.size() - 1); } private void checkCollision() { Point head = snake.get(0); if (head.equals(food)) { snake.add(food); placeFood(); score++; if (score > highScore) { highScore = score; saveHighScore(); } } if (head.x < 0 || head.x >= BOARD_WIDTH || head.y < 0 || head.y >= BOARD_HEIGHT) { timer.stop(); showGameOverDialog(); } for (int i = 1; i < snake.size(); i++) { if (head.equals(snake.get(i))) { timer.stop(); showGameOverDialog(); } } } private void showGameOverDialog() { String message = String.format("Game Over\nScore: %d\nHighscore: %d", score, highScore); int option = JOptionPane.showOptionDialog(this, message, "Game Over", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null, new String[]{"Zurück zum Hauptmenü", "Spiel beenden"}, "Zurück zum Hauptmenü"); if (option == 0) { frame.showCard("MainMenu"); } else { System.exit(0); } initGame(); timer.start(); } }
我已尝试修改showGameOverDialog相关代码,但仍未找到问题所在。
内容的提问来源于stack exchange,提问作者Maurice
相关产品推荐
相关产品推荐

