用java做一个扫雷小游戏源代码带注释
时间: 2023-12-30 07:04:40 浏览: 74
基于java的扫雷游戏-源代码.zip
好的,下面是一个简单的扫雷小游戏的源代码,带有注释解释每个功能的实现。
```java
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class Minesweeper extends JFrame {
private final int ROWS = 10; // 行数
private final int COLS = 10; // 列数
private final int NUM_OF_MINES = 10; // 雷的数量
private final int CELL_SIZE = 30; // 每个格子的大小
private final int PANEL_WIDTH = COLS * CELL_SIZE; // 面板宽度
private final int PANEL_HEIGHT = ROWS * CELL_SIZE; // 面板高度
private final int FRAME_WIDTH = PANEL_WIDTH + 20; // 窗口宽度
private final int FRAME_HEIGHT = PANEL_HEIGHT + 80; // 窗口高度
private int[][] board = new int[ROWS][COLS]; // 存储雷区的信息
private boolean[][] opened = new boolean[ROWS][COLS]; // 标记每个格子是否已经被打开
private boolean[][] flagged = new boolean[ROWS][COLS]; // 标记每个格子是否被标记为雷
private JLabel statusbar; // 状态栏
private JPanel panel; // 面板
public Minesweeper() {
initBoard(); // 初始化雷区
initUI(); // 初始化用户界面
initGame(); // 开始游戏
}
private void initBoard() {
// 雷区初始化,将每个位置的值都设为0
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
board[i][j] = 0;
opened[i][j] = false;
flagged[i][j] = false;
}
}
// 随机生成雷,将雷的位置信息存储到数组中
int count = 0;
while (count < NUM_OF_MINES) {
int x = (int) (Math.random() * ROWS);
int y = (int) (Math.random() * COLS);
if (board[x][y] != -1) {
board[x][y] = -1;
count++;
}
}
// 计算每个位置周围的雷的数量
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
if (board[i][j] != -1) {
int countMines = 0;
for (int x = i - 1; x <= i + 1; x++) {
for (int y = j - 1; y <= j + 1; y++) {
if (x >= 0 && x < ROWS && y >= 0 && y < COLS && board[x][y] == -1) {
countMines++;
}
}
}
board[i][j] = countMines;
}
}
}
}
private void initUI() {
setTitle("Minesweeper");
setSize(FRAME_WIDTH, FRAME_HEIGHT);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
statusbar = new JLabel(" ");
add(statusbar, BorderLayout.SOUTH);
panel = new JPanel();
panel.setLayout(new GridLayout(ROWS, COLS));
add(panel, BorderLayout.CENTER);
// 绘制每个格子
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
JButton button = new JButton();
button.setPreferredSize(new Dimension(CELL_SIZE, CELL_SIZE));
button.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
int button = e.getButton();
if (button == MouseEvent.BUTTON1) {
// 左键点击,打开格子
openCell(i, j);
} else if (button == MouseEvent.BUTTON3) {
// 右键点击,标记格子
flagCell(i, j);
}
checkGameStatus();
}
});
panel.add(button);
}
}
setVisible(true);
}
private void initGame() {
// 打开第一个格子
openCell(0, 0);
}
private void openCell(int x, int y) {
// 如果该格子已经被打开或标记为雷,则直接返回
if (opened[x][y] || flagged[x][y]) {
return;
}
opened[x][y] = true;
JButton button = (JButton) panel.getComponent(x * COLS + y);
button.setEnabled(false); // 禁用按钮
// 如果点击到的是雷,游戏结束
if (board[x][y] == -1) {
button.setText("*");
gameOver();
return;
}
// 如果点击到的是数字,则显示该数字
if (board[x][y] > 0) {
button.setText(String.valueOf(board[x][y]));
return;
}
// 如果点击到的是空白格子,则递归打开周围的格子
button.setText("");
for (int i = x - 1; i <= x + 1; i++) {
for (int j = y - 1; j <= y + 1; j++) {
if (i >= 0 && i < ROWS && j >= 0 && j < COLS) {
openCell(i, j);
}
}
}
}
private void flagCell(int x, int y) {
// 如果该格子已经被打开,则直接返回
if (opened[x][y]) {
return;
}
flagged[x][y] = !flagged[x][y];
JButton button = (JButton) panel.getComponent(x * COLS + y);
if (flagged[x][y]) {
button.setText("F");
} else {
button.setText("");
}
}
private void checkGameStatus() {
boolean win = true;
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
if (!opened[i][j] && board[i][j] != -1) {
win = false;
break;
}
}
}
if (win) {
statusbar.setText("You won!");
disableAllCells();
}
}
private void gameOver() {
statusbar.setText("Game over!");
showAllMines();
disableAllCells();
}
private void showAllMines() {
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
if (board[i][j] == -1) {
JButton button = (JButton) panel.getComponent(i * COLS + j);
button.setText("*");
}
}
}
}
private void disableAllCells() {
for (int i = 0; i < ROWS * COLS; i++) {
JButton button = (JButton) panel.getComponent(i);
button.setEnabled(false);
}
}
public static void main(String[] args) {
new Minesweeper();
}
}
```
以上是一个简单的扫雷小游戏的源代码,其中包含了雷区的初始化、用户界面的绘制、鼠标监听器的添加、格子的打开和标记、游戏胜负的判断等功能。代码中也有注释来解释每个功能的实现。
阅读全文