Anonymous
Java Snake Game случайно запускается showGameOverDialog
Сообщение
Anonymous » 31 май 2024, 23:18
Я работал над этим целый день, учась по ходу дела. Это мой первый довольно сложный фрагмент кода.
Это простая игра-змейка с рекордами и довольно рабочим меню. целый день смотрел обучающие материалы и собирал это вместе.
В игре есть проблема с 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
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, но ничего не понял.
Подробнее здесь:
https://stackoverflow.com/questions/785 ... overdialog
1717186733
Anonymous
Я работал над этим целый день, учась по ходу дела. Это мой первый довольно сложный фрагмент кода. Это простая игра-змейка с рекордами и довольно рабочим меню. целый день смотрел обучающие материалы и собирал это вместе. В игре есть проблема с showGameOverDialog: кажется, что она запускается случайным образом, независимо от того, что игра в данный момент делает, даже в меню, а также когда собираю яблоко (смеется). Я знаю, что это не так уж и важно, но может ли кто-нибудь мне помочь с этим? хочу этого быть моим маленьким хобби и иметь много идей по его продолжению. Заранее спасибо :) [code]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 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(); } } [/code] Пытался поиграться с кодом, связанным с showGameOverDialog, но ничего не понял. Подробнее здесь: [url]https://stackoverflow.com/questions/78561626/java-snake-game-randomly-starts-showgameoverdialog[/url]