java-扫雷游戏程序
statusLabel.setText("扫雷游戏 - 剩余地雷: " + minesLeft + " - 用时: " + secondsElapsed + "秒");resetButton.setFont(new Font("微软雅黑", Font.PLAIN, 14));statusLabel.setFont(new Font("微软雅黑", Font.BOLD, 16));// 找到点击的按
下面是一个完整的扫雷游戏实现,包含图形界面和游戏逻辑。这个程序使用了Java Swing来创建用户界面,实现了经典扫雷游戏的所有核心功能。
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
public class Minesweeper extends JFrame {
// 游戏常量
private static final int ROWS = 16;
private static final int COLS = 16;
private static final int MINES = 40;
private static final int CELL_SIZE = 30;
// 游戏状态
private JButton[][] buttons;
private int[][] board;
private boolean[][] revealed;
private boolean[][] flagged;
private int minesLeft;
private boolean gameOver;
private boolean firstClick;
// UI组件
private JPanel gamePanel;
private JLabel statusLabel;
private JButton resetButton;
private Timer gameTimer;
private int secondsElapsed;
public Minesweeper() {
super("扫雷游戏");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(COLS * CELL_SIZE + 20, ROWS * CELL_SIZE + 100);
setLayout(new BorderLayout());
setResizable(false);
// 初始化游戏状态
initializeGame();
// 创建顶部面板
JPanel topPanel = new JPanel();
topPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 20, 10));
topPanel.setBackground(new Color(230, 230, 230));
// 状态标签
statusLabel = new JLabel("扫雷游戏 - 剩余地雷: " + minesLeft);
statusLabel.setFont(new Font("微软雅黑", Font.BOLD, 16));
topPanel.add(statusLabel);
// 重置按钮
resetButton = new JButton("重新开始");
resetButton.setFont(new Font("微软雅黑", Font.PLAIN, 14));
resetButton.addActionListener(e -> resetGame());
topPanel.add(resetButton);
add(topPanel, BorderLayout.NORTH);
// 创建游戏面板
gamePanel = new JPanel();
gamePanel.setLayout(new GridLayout(ROWS, COLS));
gamePanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
// 创建按钮网格
buttons = new JButton[ROWS][COLS];
for (int row = 0; row < ROWS; row++) {
for (int col = 0; col < COLS; col++) {
JButton button = new JButton();
button.setFont(new Font("Arial", Font.BOLD, 14));
button.setFocusPainted(false);
button.setMargin(new Insets(0, 0, 0, 0));
button.setPreferredSize(new Dimension(CELL_SIZE, CELL_SIZE));
// 添加鼠标监听器
button.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
if (gameOver) return;
int r = -1, c = -1;
// 找到点击的按钮位置
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
if (buttons[i][j] == e.getSource()) {
r = i;
c = j;
break;
}
}
}
if (r != -1 && c != -1) {
if (SwingUtilities.isRightMouseButton(e)) {
// 右键:标记/取消标记旗帜
if (!revealed[r][c]) {
flagged[r][c] = !flagged[r][c];
minesLeft += flagged[r][c] ? -1 : 1;
updateStatus();
buttons[r][c].setText(flagged[r][c] ? "🚩" : "");
buttons[r][c].setBackground(flagged[r][c] ? new Color(255, 200, 200) : new Color(200, 200, 255));
}
} else {
// 左键:揭示格子
if (!flagged[r][c]) {
revealCell(r, c);
}
}
}
}
});
buttons[row][col] = button;
gamePanel.add(button);
}
}
add(gamePanel, BorderLayout.CENTER);
// 初始化计时器
gameTimer = new Timer(1000, e -> {
secondsElapsed++;
updateStatus();
});
// 显示窗口
setLocationRelativeTo(null);
setVisible(true);
}
private void initializeGame() {
board = new int[ROWS][COLS];
revealed = new boolean[ROWS][COLS];
flagged = new boolean[ROWS][COLS];
minesLeft = MINES;
gameOver = false;
firstClick = true;
secondsElapsed = 0;
}
private void resetGame() {
initializeGame();
// 重置UI
for (int row = 0; row < ROWS; row++) {
for (int col = 0; col < COLS; col++) {
buttons[row][col].setText("");
buttons[row][col].setEnabled(true);
buttons[row][col].setBackground(new Color(200, 200, 255));
}
}
gameTimer.stop();
updateStatus();
}
private void placeMines(int firstRow, int firstCol) {
Random random = new Random();
int minesPlaced = 0;
while (minesPlaced < MINES) {
int row = random.nextInt(ROWS);
int col = random.nextInt(COLS);
// 确保第一个点击的位置不是地雷
if ((row != firstRow || col != firstCol) && board[row][col] != -1) {
board[row][col] = -1; // -1表示地雷
minesPlaced++;
// 更新周围格子的计数
for (int r = Math.max(0, row - 1); r <= Math.min(ROWS - 1, row + 1); r++) {
for (int c = Math.max(0, col - 1); c <= Math.min(COLS - 1, col + 1); c++) {
if (board[r][c] != -1) {
board[r][c]++;
}
}
}
}
}
}
private void revealCell(int row, int col) {
if (revealed[row][col] || flagged[row][col] || gameOver) {
return;
}
// 第一次点击时放置地雷(确保第一次点击不是地雷)
if (firstClick) {
placeMines(row, col);
firstClick = false;
gameTimer.start();
}
revealed[row][col] = true;
buttons[row][col].setEnabled(false);
if (board[row][col] == -1) {
// 踩到地雷,游戏结束
gameOver(row, col);
return;
}
// 更新按钮文本
if (board[row][col] > 0) {
buttons[row][col].setText(String.valueOf(board[row][col]));
setNumberColor(buttons[row][col], board[row][col]);
} else {
buttons[row][col].setText("");
buttons[row][col].setBackground(new Color(220, 220, 220));
// 如果是空白格子,递归揭示周围的格子
for (int r = Math.max(0, row - 1); r <= Math.min(ROWS - 1, row + 1); r++) {
for (int c = Math.max(0, col - 1); c <= Math.min(COLS - 1, col + 1); c++) {
if (!revealed[r][c]) {
revealCell(r, c);
}
}
}
}
// 检查胜利条件
checkWin();
}
private void setNumberColor(JButton button, int number) {
switch (number) {
case 1: button.setForeground(Color.BLUE); break;
case 2: button.setForeground(new Color(0, 150, 0)); break; // 深绿色
case 3: button.setForeground(Color.RED); break;
case 4: button.setForeground(new Color(0, 0, 128)); break; // 深蓝色
case 5: button.setForeground(new Color(128, 0, 0)); break; // 深红色
case 6: button.setForeground(new Color(0, 128, 128)); break; // 青色
case 7: button.setForeground(Color.BLACK); break;
case 8: button.setForeground(Color.GRAY); break;
}
}
private void gameOver(int row, int col) {
gameOver = true;
gameTimer.stop();
// 显示所有地雷
for (int r = 0; r < ROWS; r++) {
for (int c = 0; c < COLS; c++) {
if (board[r][c] == -1) {
buttons[r][c].setText("💣");
buttons[r][c].setBackground(Color.RED);
}
}
}
// 标记踩中的地雷
buttons[row][col].setText("💥");
buttons[row][col].setBackground(Color.ORANGE);
statusLabel.setText("游戏结束!点击重新开始按钮再试一次");
}
private void checkWin() {
int unrevealedCount = 0;
for (int row = 0; row < ROWS; row++) {
for (int col = 0; col < COLS; col++) {
if (!revealed[row][col] && board[row][col] != -1) {
unrevealedCount++;
}
}
}
if (unrevealedCount == 0) {
gameOver = true;
gameTimer.stop();
// 标记所有地雷
for (int row = 0; row < ROWS; row++) {
for (int col = 0; col < COLS; col++) {
if (board[row][col] == -1 && !flagged[row][col]) {
buttons[row][col].setText("🚩");
}
}
}
statusLabel.setText("恭喜你赢了!用时: " + secondsElapsed + "秒");
}
}
private void updateStatus() {
statusLabel.setText("扫雷游戏 - 剩余地雷: " + minesLeft + " - 用时: " + secondsElapsed + "秒");
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
new Minesweeper();
});
}
}
如何运行
1. 将代码复制到名为 Minesweeper.java 的文件中
2. 编译程序:javac Minesweeper.java
3. 运行程序:java Minesweeper
更多推荐



所有评论(0)