21xrx.com
2024-11-05 19:36:48 Tuesday
登录
文章检索 我的文章 写文章
Java编程入门:实现简单贪吃蛇游戏
2023-06-16 15:33:46 深夜i     --     --
Java编程 贪吃蛇游戏 入门练习

贪吃蛇游戏是许多人童年时代的经典回忆,在现代社会中仍然备受欢迎。如果你正在学习Java编程,那么编写一个简单的贪吃蛇游戏项目是一个不错的入门练习,可以让你熟悉Java的语法和基本数据结构。下面是一个简单的Java代码示例:


import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

public class SnakeGame extends JFrame implements ActionListener {

  private static final long serialVersionUID = -4274021636695594826L;

  private static final int ROWS = 30;

  private static final int COLS = 30;

  private static final int BLOCK_SIZE = 20;

  private static final int GAME_WIDTH = ROWS * BLOCK_SIZE;

  private static final int GAME_HEIGHT = COLS * BLOCK_SIZE;

  private int[][] map = new int[ROWS][COLS];

  private ImageIcon bodyIcon = new ImageIcon("body.png");

  private ImageIcon foodIcon = new ImageIcon("food.png");

  private JLabel[][] labelMap = new JLabel[ROWS][COLS];

  private JButton startButton = new JButton("Start");

  private JButton stopButton = new JButton("Stop");

  private Timer timer = null;

  private int snakeLength = 3;

  private SnakeGame() {

    this.setTitle("Snake Game");

    this.setSize(GAME_WIDTH + 200, GAME_HEIGHT + 100);

    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    this.setLocationRelativeTo(null);

    this.setResizable(false);

    JPanel gamePanel = new JPanel();

    gamePanel.setLayout(null);

    gamePanel.setBounds(0, 0, GAME_WIDTH, GAME_HEIGHT);

    for (int i = 0; i < ROWS; i++) {

      for (int j = 0; j < COLS; j++) {

        map[i][j] = 0;

        labelMap[i][j] = new JLabel();

        labelMap[i][j].setBackground(Color.white);

        labelMap[i][j].setBounds(BLOCK_SIZE * i, BLOCK_SIZE * j, BLOCK_SIZE, BLOCK_SIZE);

        gamePanel.add(labelMap[i][j]);

      }

    }

    map[10][10] = map[10][11] = map[10][12] = 1;

    labelMap[10][10].setIcon(bodyIcon);

    labelMap[10][11].setIcon(bodyIcon);

    labelMap[10][12].setIcon(bodyIcon);

    this.add(gamePanel, BorderLayout.CENTER);

    JPanel controlPanel = new JPanel();

    controlPanel.setLayout(null);

    controlPanel.setBounds(GAME_WIDTH, 0, 200, GAME_HEIGHT + 100);

    startButton.setBounds(50, 50, 100, 30);

    startButton.addActionListener(this);

    controlPanel.add(startButton);

    stopButton.setBounds(50, 100, 100, 30);

    stopButton.addActionListener(this);

    controlPanel.add(stopButton);

    this.add(controlPanel, BorderLayout.EAST);

  }

  @Override

  public void actionPerformed(ActionEvent e) {

    if (e.getSource() == startButton) {

      timer = new Timer(500, new TimerListener());

      timer.start();

    } else if (e.getSource() == stopButton) {

      timer.stop();

    }

  }

  private class TimerListener implements ActionListener {

    @Override

    public void actionPerformed(ActionEvent e) {

      int headX = 0, headY = 0;

      boolean isHeadFound = false;

      for (int i = 0; i < ROWS; i++) {

        for (int j = 0; j < COLS; j++) {

          if (map[i][j] == 1) {

            if (isHeadFound) {

              map[i][j] = 0;

              labelMap[i][j].setIcon(null);

            } else

              headX = i;

              headY = j;

              isHeadFound = true;

            

          }

        }

      }

      if (headX == ROWS - 1 || headY == COLS - 1 || headX == 0 || headY == 0) {

        timer.stop();

        JOptionPane.showMessageDialog(null, "Game over.");

        return;

      }

      if (map[headX + 1][headY] == 2 ||

        map[headX - 1][headY] == 2 ||

        map[headX][headY + 1] == 2 ||

        map[headX][headY - 1] == 2) {

        timer.stop();

        JOptionPane.showMessageDialog(null, "Game over.");

        return;

      }

      int oldHeadX = headX, oldHeadY = headY;

      if (map[headX + 1][headY] == 3) {

        snakeLength++;

        generateFood();

      } else if (map[headX - 1][headY] == 3) {

        snakeLength++;

        generateFood();

      } else if (map[headX][headY + 1] == 3) {

        snakeLength++;

        generateFood();

      } else if (map[headX][headY - 1] == 3) {

        snakeLength++;

        generateFood();

      } else {

        for (int i = 0; i < ROWS; i++) {

          for (int j = 0; j < COLS; j++) {

            if (map[i][j] > 0) {

              map[i][j]++;

              labelMap[i][j].setIcon(bodyIcon);

              if (map[i][j] == snakeLength) {

                map[i][j] = 1;

                labelMap[i][j].setIcon(bodyIcon);

              }

            }

          }

        }

      }

      if (map[oldHeadX + 1][oldHeadY] == 1) {

        map[oldHeadX + 1][oldHeadY] = 0;

        labelMap[oldHeadX + 1][oldHeadY].setIcon(null);

      }

      if (map[oldHeadX - 1][oldHeadY] == 1) {

        map[oldHeadX - 1][oldHeadY] = 0;

        labelMap[oldHeadX - 1][oldHeadY].setIcon(null);

      }

      if (map[oldHeadX][oldHeadY + 1] == 1) {

        map[oldHeadX][oldHeadY + 1] = 0;

        labelMap[oldHeadX][oldHeadY + 1].setIcon(null);

      }

      if (map[oldHeadX][oldHeadY - 1] == 1) {

        map[oldHeadX][oldHeadY - 1] = 0;

        labelMap[oldHeadX][oldHeadY - 1].setIcon(null);

      }

      map[oldHeadX + 1][oldHeadY] = 1;

      labelMap[oldHeadX + 1][oldHeadY].setIcon(bodyIcon);

    }

    private void generateFood() {

      int x = (int)(Math.random() * ROWS);

      int y = (int)(Math.random() * COLS);

      if (map[x][y] == 0) {

        map[x][y] = 3;

        labelMap[x][y].setIcon(foodIcon);

      } else {

        generateFood();

      }

    }

  }

  public static void main(String[] args) {

    new SnakeGame().setVisible(true);

  }

}

在这个示例代码中,我们定义了一个`SnakeGame`类,并在其中实现了`ActionListener`接口。程序入口函数(`main`)首先创建一个`SnakeGame`对象并将其设置为可见状态。接着,程序生成了一个游戏界面,包含一个`30 x 30`个格子的方格地图以及游戏控制按钮。

贪吃蛇的核心逻辑实现在`TimerListener`内部类中。这个类实现了`ActionListener`接口,每隔`500ms`执行一次。在每次执行时,程序会首先遍历地图,找到蛇头的位置以及是否吃到了食物。然后,程序会根据当前蛇头的位置计算出下一个蛇头的位置,并判断是否满足游戏失败的条件(撞墙或撞到自己),如果满足,则弹出游戏结束的提示框;如果不满足,则更新蛇的位置,同时更新地图上的显示。如果蛇头吃到了食物,则会增加蛇的长度,并在随机位置生成下一个食物。

这个示例代码仅实现了一个简单的贪吃蛇游戏,你可以尝试在此基础上进行扩展,增加更多的游戏元素。注意,这只是一个示例代码,请勿用于商业用途。

  
  
下一篇: Java开发平台

评论区

{{item['qq_nickname']}}
()
回复
回复