package src.am.demo02;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MineSweeper extends JFrame implements ActionListener, MouseListener {
private static final long serialVersionUID = 1L;
private int row = 10; // 行数
private int col = 10; // 列数
private int mineNum = 10; // 雷数
private int[][] mineMap = new int[row][col]; // 雷区地图
private JButton[][] btns = new JButton[row][col]; // 按钮数组
private boolean[][] mineFlag = new boolean[row][col]; // 标记数组
private boolean[][] openFlag = new boolean[row][col]; // 打开标记数组
private int leftMineNum = mineNum; // 剩余雷数
private JLabel leftMineLabel = new JLabel("剩余雷数:" + leftMineNum); // 剩余雷数标签
private JPanel minePanel = new JPanel(new GridLayout(row, col)); // 雷区面板
private JPanel topPanel = new JPanel(); // 顶部面板
private boolean gameOver = false; // 游戏是否结束
public MineSweeper() {
setTitle("扫雷");
setSize(600, 600);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
initMineMap();
initBtns();
initTopPanel();
add(minePanel, BorderLayout.CENTER);
add(topPanel, BorderLayout.NORTH);
setVisible(true);
}
// 初始化雷区地图
private void initMineMap() {
int count = 0;
while (count < mineNum) {
int x = (int) (Math.random() * row);
int y = (int) (Math.random() * col);
if (mineMap[x][y] != -1) {
mineMap[x][y] = -1;
count++;
}
}
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (mineMap[i][j] != -1) {
int countMine = 0;
if (i > 0 && j > 0 && mineMap[i - 1][j - 1] == -1)
countMine++;
if (i > 0 && mineMap[i - 1][j] == -1)
countMine++;
if (i > 0 && j < col - 1 && mineMap[i - 1][j + 1] == -1)
countMine++;
if (j > 0 && mineMap[i][j - 1] == -1)
countMine++;
if (j < col - 1 && mineMap[i][j + 1] == -1)
countMine++;
if (i < row - 1 && j > 0 && mineMap[i + 1][j - 1] == -1)
countMine++;
if (i < row - 1 && mineMap[i + 1][j] == -1)
countMine++;
if (i < row - 1 && j < col - 1 && mineMap[i + 1][j + 1] == -1)
countMine++;
mineMap[i][j] = countMine;
}
}
}
}
// 初始化按钮数组
private void initBtns() {
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
btns[i][j] = new JButton();
btns[i][j].addActionListener(this);
btns[i][j].addMouseListener(this);
minePanel.add(btns[i][j]);
}
}
}
// 初始化顶部面板
private void initTopPanel() {
JButton restartBtn = new JButton("重新开始");
restartBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
restart();
}
});
topPanel.add(leftMineLabel);
topPanel.add(restartBtn);
}
// 重新开始
private void restart() {
gameOver = false;
leftMineNum = mineNum;
leftMineLabel.setText("剩余雷数:" + leftMineNum);
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
mineMap[i][j] = 0;
mineFlag[i][j] = false;
openFlag[i][j] = false;
btns[i][j].setText("");
btns[i][j].setEnabled(true);
btns[i][j].setBackground(null);
}
}
initMineMap();
}
// 点击按钮
public void actionPerformed(ActionEvent e) {
if (gameOver)
return;
JButton btn = (JButton) e.getSource();
int x = -1, y = -1;
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (btn == btns[i][j]) {
x = i;
y = j;
break;
}
}
}
if (mineFlag[x][y])
return;
if (mineMap[x][y] == -1) {
gameOver();
} else if (mineMap[x][y] == 0) {
open(x, y);
} else {
btn.setText(mineMap[x][y] + "");
btn.setEnabled(false);
openFlag[x][y] = true;
checkWin();
}
}
// 右键标记
public void mouseClicked(MouseEvent e) {
if (gameOver)
return;
JButton btn = (JButton) e.getSource();
int x = -1, y = -1;
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (btn == btns[i][j]) {
x = i;
y = j;
break;
}
}
}
if (e.getButton() == MouseEvent.BUTTON3) {
if (btn.getText().equals("")) {
btn.setText("▲");
mineFlag[x][y] = true;
leftMineNum--;
} else {
btn.setText("");
mineFlag[x][y] = false;
leftMineNum++;
}
leftMineLabel.setText("剩余雷数:" + leftMineNum);
}
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
// 打开空白区域
private void open(int x, int y) {
if (x < 0 || x >= row || y < 0 || y >= col || openFlag[x][y])
return;
JButton btn = btns[x][y];
if (mineFlag[x][y])
return;
if (mineMap[x][y] == -1) {
gameOver();
} else if (mineMap[x][y] == 0) {
btn.setEnabled(false);
openFlag[x][y] = true;
open(x - 1, y - 1);
open(x - 1, y);
open(x - 1, y + 1);
open(x, y - 1);
open(x, y + 1);
open(x + 1, y - 1);
open(x + 1, y);
open(x + 1, y + 1);
} else {
btn.setText(mineMap[x][y] + "");
btn.setEnabled(false);
openFlag[x][y] = true;
checkWin();
}
}
// 游戏结束
private void gameOver() {
gameOver = true;
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
JButton btn = btns[i][j];
if (mineMap[i][j] == -1) {
btn.setText("●");
btn.setBackground(Color.RED);
}
btn.setEnabled(false);
}
}
JOptionPane.showMessageDialog(this, "游戏结束!");
}
// 检查是否胜利
private void checkWin() {
int count = 0;
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (openFlag[i][j])
count++;
}
}
if (count == row * col - mineNum) {
gameOver = true;
JOptionPane.showMessageDialog(this, "恭喜你,游戏胜利!");
}
}
public static void main(String[] args) {
new MineSweeper();
}
}
Java分享扫雷小游戏源码
于 2023-11-03 15:17:10 首次发布