如何为Java Snake游戏创建一个简单的菜单?

如何为Java Snake游戏创建一个简单的菜单?,java,menu,state,Java,Menu,State,我想为我的Java Snake游戏添加一个简单的菜单,其中包含三个按钮(新游戏、难度和退出)。我为菜单和鼠标输入创建了一个类。我使用了一个枚举来存储游戏的状态(主菜单、难度菜单和游戏)和一个名为STATE的变量来存储当前状态 主要的问题是,当按下“新游戏”按钮时,虽然游戏的状态发生了变化,但游戏不会启动。我尝试在设置游戏性所涉及的方法中添加游戏状态检查,也尝试从MouseInput类的mousePressed()方法调用这些方法,但这些方法都不起作用 如果您能就如何解决这个问题给我一些建议,我将

我想为我的Java Snake游戏添加一个简单的菜单,其中包含三个按钮(新游戏、难度和退出)。我为菜单和鼠标输入创建了一个类。我使用了一个枚举来存储游戏的状态(主菜单、难度菜单和游戏)和一个名为STATE的变量来存储当前状态

主要的问题是,当按下“新游戏”按钮时,虽然游戏的状态发生了变化,但游戏不会启动。我尝试在设置游戏性所涉及的方法中添加游戏状态检查,也尝试从MouseInput类的mousePressed()方法调用这些方法,但这些方法都不起作用

如果您能就如何解决这个问题给我一些建议,我将不胜感激。 这是我的密码:

    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.*;


    public class SnakeGame extends JFrame{

        public SnakeGame() {
            initGUI();
        }

        public void initGUI() {
            add(new GamePlay());
            setResizable(false);
            pack();

            setTitle("The Snake");
            setLocationRelativeTo(null);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

          }

        public static void main(String[] args) {
            EventQueue.invokeLater(() ->  {
            JFrame frame = new SnakeGame();
            frame.setVisible(true);

            }); 
        }


import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.*;

public class GamePlay extends JPanel implements ActionListener {

    public static final int HEIGHT = 600;
    public static final int WIDTH = 600;
    private final int TOTAL_DOTS = 3600;
    private final int DOT_SIZE = 10;
    private final int RAND_POSITION = 29;
    //private final int DELAY = 140;


    private final int[] X = new int[TOTAL_DOTS];// the dots on X axis
    private final int[] Y = new int[TOTAL_DOTS];//the dots on Y axis

    private int dots;
    private int apple_X;
    private int apple_Y;
    private int score = 0;
    private int DELAY = 140;

    private boolean leftDirection = false;
    private boolean rightDirection = true;
    private boolean upDirection = false;
    private boolean downDirection = false;
    private boolean inGame = true;

    private Timer timer;
    private Image bodyPart;
    private Image snakeHead;
    private Image apple;

    private Menu menu;
    public static GameState STATE = GameState.MAIN_MENU;//current game state(it changes when menu buttons are pressed)


    public static enum GameState{
        MAIN_MENU,
        DIFFICULTY_MENU,
        GAME

    }

    public GamePlay() {

        setGamePlay();

    }


    public void setGamePlay() {

        addKeyListener(new KeyboardEvent());
        addMouseListener(new MouseInput());
        setBackground(Color.BLACK);
        setFocusable(true);

        setPreferredSize(new Dimension(WIDTH, HEIGHT));

        if(STATE == GameState.GAME) {
        loadImages();
        startGame();

        } 
    }

    private void loadImages() {

        ImageIcon img2 = new ImageIcon("src/images/dot.png");
        bodyPart = img2.getImage();

        ImageIcon img1 = new ImageIcon("src/images/head.png");
        snakeHead = img1.getImage();

        ImageIcon img3 = new ImageIcon("src/images/apple.png");
        apple = img3.getImage();

    }

    //setting the starting snake length and the apple position on the board
    public void startGame() {
        dots = 3;

        for(int i = 0 ; i < dots; i++) {
            X[i] = 50 - i * 10;
            Y[i] = 50;
          }

        locateApple();

        timer = new Timer(DELAY,this);
        //timer.start();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        if(STATE == GameState.GAME) {

        draw(g);

        }else if(STATE == GameState.MAIN_MENU) {

            new Menu().displayMainMenu(g);

        }else if(STATE == GameState.DIFFICULTY_MENU) {

            new Menu().displayDifficultyMenu(g);
        }
        System.out.println("End of paint component method");
    }

    public void draw(Graphics g) {

        scoreDisplay(g);

        if(inGame) {
            g.drawImage(apple, apple_X, apple_Y,this);


            for(int i = 0 ; i < dots; i++) {
                if(i == 0) {
                    g.drawImage(snakeHead,X[i], Y[i], this);
                }else {
                    g.drawImage(bodyPart, X[i], Y[i], this);
                }
            }

            Toolkit.getDefaultToolkit().sync();

        }else {

            gameOver(g);
        }

    }

    public void gameOver(Graphics g) {
        String msg = "Game Over!";
        String msg2 = "Score: " + score + " " + "Length: " + dots;
        Font small = new Font("Comic Sans",Font.BOLD,14 );
        FontMetrics messageSize = getFontMetrics(small);

        g.setColor(Color.WHITE);
        g.setFont(small);
        g.drawString(msg, (WIDTH - messageSize.stringWidth(msg)) / 2, HEIGHT / 2);

        g.drawString(msg2, (WIDTH - messageSize.stringWidth(msg2)) / 2, (HEIGHT / 2) + 20);

        restartMessageDisplay(g);
    }


    public void scoreDisplay(Graphics g) {
        String gameScore = "Score: " + score;
        String snakeLength = "Snake length: " + dots;
        Font small = new Font("Arial", Font.BOLD, 14);

        g.setColor(Color.WHITE);
        g.setFont(small);
        g.drawString(gameScore,480, 20);
        g.drawString(snakeLength, 480, 40);

    }


    public void restartMessageDisplay(Graphics g) {
        String restartMessage = " Press Enter to restart";
        Font small = new Font("Arial", Font.BOLD, 14);
        FontMetrics metrics = getFontMetrics(small); 
        g.drawString(restartMessage, (WIDTH - metrics.stringWidth(restartMessage)) / 2, (HEIGHT / 2) + 40);

    }


    private void checkApple() {

        if((X[0] == apple_X) && (Y[0] == apple_Y)) {
            dots++;

            locateApple();

            score += 5;//score update
            DELAY -= 5;// speed increase when snake eats the apple


            if(DELAY >= 40) {
                timer.setDelay(DELAY);
            }   
        }       
    }

    //snake move logic
    private void move() {

        for(int i = dots; i > 0; i--) {
            X[i] = X[(i-1)];
            Y[i] = Y[(i-1)];
        }

        if(leftDirection) {
            X[0] -= DOT_SIZE;  
        }

        if(rightDirection) {
            X[0] += DOT_SIZE;
        }

        if(upDirection) {
            Y[0] -= DOT_SIZE;               
        }

        if(downDirection) {
            Y[0] += DOT_SIZE;
        }
    }
        //checking for collision with the walls or the snake itself
        private void checkCollision() {

         for(int i = dots; i > 0; i--) {

             if((i > 4) && (X[0] == X[i]) && (Y[0] == Y[i])) {
                 inGame = false;
             }
         }


         if(X[0] < 0) {
             inGame = false;
         }

         if(X[0] > WIDTH) {
             inGame = false;
         }

         if(Y[0] < 0) {
             inGame = false;
         }

         if(Y[0] > HEIGHT) {
             inGame = false;
         }

         if(!inGame) {
             timer.stop();
         }

        }


        //setting apple position on the board
        public void locateApple() {
            int random = (int) (Math.random() * RAND_POSITION);
            apple_X = random * DOT_SIZE;

            random = (int) (Math.random()* RAND_POSITION);
            apple_Y = random * DOT_SIZE;


        }


    @Override
    public void actionPerformed(ActionEvent e) {
        if(inGame) {

            checkApple();
            checkCollision();
            move();

        }

        repaint();

    }

    private class KeyboardEvent extends KeyAdapter {

        public void keyPressed(KeyEvent e) {
            int keyCode = e.getKeyCode();

            if((keyCode == KeyEvent.VK_LEFT) && (!rightDirection)) {
                leftDirection = true;
                upDirection = false;
                downDirection = false;
            }

            if((keyCode == KeyEvent.VK_RIGHT) && (!leftDirection)) {
                rightDirection = true;
                upDirection = false;
                downDirection = false;

            }

            if((keyCode == KeyEvent.VK_UP) && (!downDirection)) {
                upDirection = true;
                leftDirection = false;
                rightDirection = false;
            }

            if((keyCode == KeyEvent.VK_DOWN) && (!upDirection)) {
                downDirection = true;
                leftDirection = false;
                rightDirection = false;

            }


            if(keyCode == KeyEvent.VK_PAUSE) {
                timer.stop();
            }

            if(keyCode == KeyEvent.VK_SPACE) {
                timer.start();
            }

            //game restart
            if(keyCode == KeyEvent.VK_ENTER) {

             if(!inGame) {
                inGame = true;
                leftDirection = false;
                rightDirection = true;
                upDirection = false;
                downDirection = false;
                score = 0;
                DELAY = 140;
                setGamePlay();
                repaint();

              }
           }
        } 
    }
}


import java.awt.*;
import javax.swing.*;

public class Menu {
    public Rectangle newGameButton;
    public Rectangle gameDifficultyButton;
    public Rectangle quitButton;
    public Rectangle easyDifficultyButton;
    public Rectangle mediumDifficultyButton;
    public Rectangle hardDifficultyButton;
    public Button button1;

    public Menu() {
        int buttonWidth = 150;
        int buttonHeight = 50;

        newGameButton = new Rectangle((GamePlay.WIDTH - buttonWidth) / 2, (GamePlay.HEIGHT / 2) - 50, buttonWidth, buttonHeight); 
        gameDifficultyButton = new Rectangle((GamePlay.WIDTH - buttonWidth) / 2, (GamePlay.HEIGHT / 2) + 50, buttonWidth, buttonHeight);
        quitButton = new Rectangle((GamePlay.WIDTH - buttonWidth) / 2, (GamePlay.HEIGHT / 2) + 150, buttonWidth, buttonHeight);

        easyDifficultyButton = new Rectangle((GamePlay.WIDTH - buttonWidth) / 2, (GamePlay.HEIGHT / 2) - 50, buttonWidth, buttonHeight);
        mediumDifficultyButton = new Rectangle((GamePlay.WIDTH - buttonWidth) / 2, (GamePlay.HEIGHT / 2) + 50, buttonWidth, buttonHeight);
        hardDifficultyButton = new Rectangle((GamePlay.WIDTH - buttonWidth) / 2, (GamePlay.HEIGHT / 2) + 150, buttonWidth, buttonHeight);

        }


    public void displayMainMenu(Graphics g) {
        Graphics2D  buttonGraphics =(Graphics2D) g;

        String title = "THE SNAKE GAME";
        Font font = new Font("Arial", Font.BOLD, 50);
        FontMetrics size = g.getFontMetrics(font);

        g.setFont(font);
        g.setColor(Color.WHITE);
        g.drawString(title,(GamePlay.WIDTH-size.stringWidth(title)) / 2, (GamePlay.HEIGHT / 2) - 130);


        Font buttonFont = new Font("Arial", Font.BOLD, 28);
        g.setFont(buttonFont);

        g.drawString("New Game",newGameButton.x + 2, newGameButton.y + 35);
        buttonGraphics.draw(newGameButton);

        g.drawString("Difficulty",gameDifficultyButton.x + 15,gameDifficultyButton.y + 35);
        buttonGraphics.draw(gameDifficultyButton);

        g.drawString("Quit", quitButton.x + 45, quitButton.y + 35);
        buttonGraphics.draw(quitButton);    
    }   


    public void displayDifficultyMenu(Graphics g) {
        Graphics2D difficultyMenuGraphics = (Graphics2D) g;

        String title = "Difficulty level";
        Font difficultyMenuTitleFont = new Font("Arial", Font.BOLD,40);
        FontMetrics size = g.getFontMetrics(difficultyMenuTitleFont);

        g.setFont(difficultyMenuTitleFont);
        g.setColor(Color.WHITE);
        g.drawString(title, (GamePlay.WIDTH - size.stringWidth(title)) / 2, (GamePlay.HEIGHT / 2) - 100);

        Font difficultyButtonFont = new Font("Arial", Font.BOLD, 28);
        g.setFont(difficultyButtonFont);

        g.drawString("Easy", easyDifficultyButton.x + 40 , easyDifficultyButton.y + 35);
        difficultyMenuGraphics.draw(easyDifficultyButton);

        g.drawString("Medium",mediumDifficultyButton.x + 20, mediumDifficultyButton.y + 35);
        difficultyMenuGraphics.draw(mediumDifficultyButton);

        g.drawString("Hard", hardDifficultyButton.x + 40, hardDifficultyButton.y + 35);
        difficultyMenuGraphics.draw(hardDifficultyButton);
    }   
}


import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.lang.Thread.State;


public class MouseInput extends MouseAdapter {
    public Rectangle newGameButton;
    public Rectangle gameDifficultyButton;
    public Rectangle quitButton;
    public Rectangle easyDifficultyButton;
    public Rectangle mediumDifficultyButton;
    public Rectangle hardDifficultyButton;
    Graphics g;


    public void mousePressed(MouseEvent e) {
        int mouseX = e.getX();
        int mouseY = e.getY();


        //NewGame button
        if(mouseX >= (GamePlay.WIDTH - 150) / 2 && mouseX <=  ((GamePlay.WIDTH - 150) / 2) + 150) {
            if(mouseY >= (GamePlay.HEIGHT / 2) - 50  && mouseY <= (GamePlay.HEIGHT/ 2)) {
                GamePlay.STATE = GamePlay.GameState.GAME;
                System.out.println(GamePlay.STATE);

          }
         }

        //Difficulty button
        if(mouseX >= (GamePlay.WIDTH - 150) / 2 && mouseX <= ((GamePlay.WIDTH - 150)/ 2 ) + 150) {
            if(mouseY >= (GamePlay.HEIGHT / 2) + 50  && mouseY <= (GamePlay.HEIGHT/ 2) + 100) {
                GamePlay.STATE = GamePlay.STATE.DIFFICULTY_MENU;
                System.out.println("Game state = " + GamePlay.STATE)
          }
        }

        //Quit button
        if(mouseX >= (GamePlay.WIDTH - 150) / 2 && mouseX <= ((GamePlay.WIDTH - 150)/ 2 ) + 150) {
            if(mouseY >= (GamePlay.HEIGHT / 2) + 150  && mouseY <= (GamePlay.HEIGHT/ 2) + 200) { 

                System.exit(0);

          }
        }
    }
}
import java.awt.*;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入javax.swing.*;
公共类蛇形游戏扩展JFrame{
公众蛇类游戏(){
initGUI();
}
public void initGUI(){
添加(新游戏玩法());
可设置大小(假);
包装();
片名(“蛇”);
setLocationRelativeTo(空);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
公共静态void main(字符串[]args){
EventQueue.invokeLater(()->{
JFrame=新的蛇形游戏();
frame.setVisible(true);
}); 
}
导入java.awt.*;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.awt.event.KeyAdapter;
导入java.awt.event.KeyEvent;
导入javax.swing.*;
公共类游戏扩展JPanel实现ActionListener{
公共静态最终内部高度=600;
公共静态最终整数宽度=600;
私人最终整数总计=3600;
私人最终整数点_大小=10;
私人最终积分和位置=29;
//专用最终整数延迟=140;
private final int[]X=new int[TOTAL_DOTS];//X轴上的点
private final int[]Y=new int[TOTAL_DOTS];//Y轴上的点
私有整数点;
私人苹果公司;
私人国际苹果公司;
私人智力得分=0;
专用整数延迟=140;
私有布尔leftDirection=false;
私有布尔rightDirection=true;
私有布尔向上方向=false;
私有布尔向下方向=false;
私有布尔inGame=true;
私人定时器;
私人形象部分;
私人形象蛇头;
私人形象苹果;
私人菜单;
public static GameState=GameState.MAIN_MENU;//当前游戏状态(当按下菜单按钮时会改变)
公共静态枚举游戏状态{
主菜单,
难度菜单,
游戏
}
公共游戏{
设置游戏性();
}
公共游戏性(){
addKeyListener(新KeyboardEvent());
添加MouseListener(新的MouseInput());
挫折背景(颜色:黑色);
设置聚焦(真);
setPreferredSize(新尺寸(宽度、高度));
if(STATE==GameState.GAME){
loadImages();
startGame();
} 
}
私有void loadImages(){
ImageIcon img2=新的ImageIcon(“src/images/dot.png”);
bodyPart=img2.getImage();
ImageIcon img1=新的ImageIcon(“src/images/head.png”);
snakeHead=img1.getImage();
ImageIcon img3=新的ImageIcon(“src/images/apple.png”);
apple=img3.getImage();
}
//设置起始蛇长度和板上的苹果位置
公共无效StartName(){
点=3;
对于(int i=0;i