java - 如何在 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;
}
}
}
}
我很抱歉长代码:(有什么帮助,谢谢!
解决方案
您必须将所有变量重置为新游戏的初始值,最简单的方法是定义一个新方法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
应该足以满足您的所有需求。
推荐阅读
- c++ - 如何制作一个重置while循环的函数?
- javascript - 带有 HTML *和*输入字段数据的 Javascript
- r - R studio 只是停止绘图 - 反复,如何修复
- python - Python cx_oracle 错误:需要字符串或字节对象
- javascript - JSON Schema:是否有一个字段可以为字段指定元数据?
- flutter - Flutter:如何拉伸 Wrap Widget 中的最后一个元素?
- typescript - 如何在没有 cognito 的情况下使用 IAM_AUTH 调用 API Gateway 端点
- angular - Angular 10 PrimeNG 列表框项目上的条件咏叹调标签
- php - 我想知道如何对我的 php api 进行速率限制,以便 ip 或客户端无法使用 5 分钟
- azure - Azure VM 和 Visual Studio 代码