首页 > 解决方案 > 如何在 Java 的“游戏结束”屏幕上添加重启鼠标输入

问题描述

我正在学习如何在 Java 中创建蛇游戏的教程,我遵循它并开始在其中添加一些功能,例如菜单系统、游戏结束屏幕。现在在这个 Game Over 屏幕上,我想添加一个重启按钮,为此我使用了“MouseListener”。我还为菜单、游戏、GameOver 添加了不同的状态。

这是我的 MouseListener 代码:

public class MouseInput implements MouseListener {

    ...

    // Game Over Screen
    if (GamePanel.state == GamePanel.STATE.GAMEOVER) {
        if (mx >= 250 && mx <= 340) {
            if (my >= 350 && my <= 400) {
                // to quit the game
                System.exit(1);

            }
        }
        if (mx >= 250 && mx <= 340) {
            if (my >= 150 && my <= 200) {
                // to restart the game
                // dont know what to put here 
             }   
        }
      ...

我不知道这是否相关,但这是我制作游戏的游戏面板类(警告:代码块):

public class GamePanel extends JPanel implements ActionListener {

static final int SCREEN_WIDTH =  600;
static final int SCREEN_HEIGHT = 600;
static final int OBJECT_SIZE = 25;
static final int GAME_UNITS = (SCREEN_WIDTH*SCREEN_HEIGHT)/OBJECT_SIZE;
static final int DELAY = 75;
final int x[] = new int[GAME_UNITS];
final int y[] = new int[GAME_UNITS];
int size = 5;
int applesEaten;
int appleX;
int appleY;
char direction = 'D';
boolean running = false;
Timer timer;
Random random;

private Menu menu;
public static enum STATE{
    MENU,
    GAME,
    GAMEOVER
};
public static STATE state = STATE.MENU;

GamePanel() {
        random = new Random();
        this.setPreferredSize(new Dimension(SCREEN_WIDTH, SCREEN_HEIGHT));
        this.setBackground(Color.BLACK);
        this.setFocusable(true);
        this.addKeyListener(new keyAdapter());
        this.addMouseListener(new MouseInput()); 
        menu = new Menu(); 
        startGame();
    }

public void startGame(){
    newApple();
    running = true;
    timer = new Timer(DELAY,this);
    timer.start();
}

public void paintComponent(Graphics g){
    super.paintComponent(g);
    draw(g);
}
public void draw(Graphics g) {
    if (state == STATE.GAME) {//******
        if (running) {              
            g.setColor(Color.GREEN);
            g.fillOval(appleX, appleY, OBJECT_SIZE, OBJECT_SIZE);

            for (int i = 0; i < size; i++) {
                if (i == 0) {
                    g.setColor(Color.blue);
                    g.fillOval(x[i], y[i], OBJECT_SIZE, OBJECT_SIZE);
                } else {
                    g.setColor(Color.CYAN);
                    g.fillOval(x[i], y[i], OBJECT_SIZE, OBJECT_SIZE);
                }
            }
            g.setColor(Color.GREEN);
            g.setFont(new Font("Ink Free", Font.BOLD, 35));
            FontMetrics metrics = getFontMetrics(g.getFont());
            g.drawString("Score: "+applesEaten, (SCREEN_WIDTH - metrics.stringWidth("Score: "+applesEaten))/2, g.getFont().getSize());
        }
        else {
            gameOver(g);
        }
    } else if(state == STATE.MENU){ //*****
            menu.render(g);
    }
}
public void newApple(){
    appleX = random.nextInt((int)(SCREEN_WIDTH/OBJECT_SIZE))*OBJECT_SIZE;
    appleY = random.nextInt((int)(SCREEN_HEIGHT/OBJECT_SIZE))*OBJECT_SIZE;

}
public void movement() {
    if (state == STATE.GAME) {
        for (int i = size; i > 0; i--) {
            x[i] = x[i - 1];
            y[i] = y[i - 1];
        }
        switch (direction) {
            case 'U':
                y[0] = y[0] - OBJECT_SIZE;
                break;
            case 'D':
                y[0] = y[0] + OBJECT_SIZE;
                break;
            case 'L':
                x[0] = x[0] - OBJECT_SIZE;
                break;
            case 'R':
                x[0] = x[0] + OBJECT_SIZE;
                break;
        }
    }
}
public void checkApple() {
    if (state == STATE.GAME) { //*******
        if ((x[0] == appleX) && (y[0] == appleY)) {
            size++;
            applesEaten++;
            newApple();
        }

    }
}
public void checkCollisions() {
    if (state == STATE.GAME) { //*******
        //checks if head collides with body
        for (int i = size; i > 0; i--) {
            if ((x[0] == x[i]) && (y[0] == y[i])) {
                running = false;
            }
        }
        //check if head touches left border
        if (x[0] < 0) {
            running = false;
        }
        //check if head touches right border
        if (x[0] > SCREEN_WIDTH) {
            running = false;
        }
        //check if head touches top border
        if (y[0] < 0) {
            running = false;
        }
        //check if head touches bottom border
        if (y[0] > SCREEN_HEIGHT) {
            running = false;
        }

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

    }
}
public void gameOver(Graphics g) {
    Graphics2D g2d = (Graphics2D) g;
    if (!running) {
        state = STATE.GAMEOVER;
        Rectangle play = new Rectangle(250, 150, 100, 50);
        Rectangle quit = new Rectangle(250, 350, 100, 50);

        Font fnt = new Font("arial", Font.BOLD, 70);
        Font fnt1 = new Font("arial", Font.BOLD, 30);
        g.setFont(fnt);
        g.setColor(Color.RED);
        g.drawString("GAME OVER", 90, 100);

        g.setFont(fnt1);
        g.drawString("Play", play.x + 20, play.y + 30);
        g2d.draw(play);
        g.drawString("Quit", quit.x + 20, quit.y + 30);
        g2d.draw(quit);

        g.setColor(Color.GREEN);
        g.setFont(new Font("Ink Free", Font.BOLD, 35));
        FontMetrics metrics2 = getFontMetrics(g.getFont());
        g.drawString("Score: " + applesEaten, (SCREEN_WIDTH - metrics2.stringWidth("Score: " + applesEaten)) / 2, g.getFont().getSize());
    }

}
    public void actionPerformed(ActionEvent a) {

    if (running) {
        movement();
        checkApple();
        checkCollisions();
    }


    repaint();
}
public class keyAdapter extends KeyAdapter{

    public void keyPressed(KeyEvent e){
        if(state == STATE.GAME) { //******
            switch (e.getKeyCode()) {
                case KeyEvent.VK_LEFT:
                    if (direction != 'R') {
                        direction = 'L';
                    }
                    break;
                case KeyEvent.VK_RIGHT:
                    if (direction != 'L') {
                        direction = 'R';
                    }
                    break;
                case KeyEvent.VK_UP:
                    if (direction != 'D') {
                        direction = 'U';
                    }
                    break;
                case KeyEvent.VK_DOWN:
                    if (direction != 'U') {
                        direction = 'D';
                    }
                    break;
            }
        }
    }
}

我很抱歉长代码:(有什么帮助,谢谢!

标签: javaswing

解决方案


您必须将所有变量重置为新游戏的初始值,最简单的方法是定义一个新方法newGame(),在 MouseListener 中调用此方法(我假设您的 MouseInput 类是 GamePanel 的内部类)。

public void newGame() {
    applesEaten=0;
    size=INITIAL_SIZE;
    newApple();
    state=STATE.GAME;
    running=true;
    Arrays.fill(x, 0);
    Arrays.fill(y, 0);
    direction = 'D';
    timer.start();
}

话虽如此,您应该重新考虑一下状态的变化,因为您在计时器停止时设置了 GAMEOVER,而不是立即停止计时器并设置 GAMEOVER,您应该摆脱running变量,因为state应该足以满足您的所有需求。


推荐阅读