上一篇
java扫雷游戏编程怎么自定义雷区
- 后端开发
- 2025-09-01
- 7
Java扫雷游戏中,自定义雷区可通过创建二维数组表示格子,随机
Java 中实现扫雷游戏并自定义雷区,需要从多个方面入手,包括游戏界面的设计、雷区数据的生成与存储、以及雷区相关的逻辑处理等,以下是一个详细的实现方案:
游戏界面设计
扫雷游戏通常有一个二维的网格来表示雷区,每个网格可以是一个按钮或者一个可绘制的区域,用于显示数字、雷或者空白等信息,可以使用 Java 的 Swing 或 JavaFX 库来创建图形用户界面(GUI)。
使用 Swing 创建基本界面
import javax.swing.; import java.awt.; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class Minesweeper extends JFrame { private JPanel panel; private int rows = 10; // 默认行数 private int cols = 10; // 默认列数 private JButton[][] buttons; public Minesweeper() { setTitle("扫雷游戏"); setSize(400, 400); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); panel = new JPanel(new GridLayout(rows, cols)); buttons = new JButton[rows][cols]; for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { buttons[i][j] = new JButton(); buttons[i][j].addActionListener(new ButtonClickListener(i, j)); panel.add(buttons[i][j]); } } add(panel); setVisible(true); } private class ButtonClickListener implements ActionListener { int row; int col; public ButtonClickListener(int row, int col) { this.row = row; this.col = col; } @Override public void actionPerformed(ActionEvent e) { // 处理按钮点击事件,如揭示雷区、判断胜负等 // 这里可以根据自定义雷区的数据来进行相应的处理 } } public static void main(String[] args) { new Minesweeper(); } }
雷区数据生成与存储
为了自定义雷区,我们需要一个数据结构来存储雷区的信息,例如哪些格子是雷,每个格子周围的雷数等,可以使用一个二维数组来表示雷区,其中每个元素可以是布尔值(表示是否是雷)或者整数(表示周围雷的数量)。
定义雷区数据结构
boolean[][] mines; // 存储雷的位置,true 表示有雷,false 表示无雷 int[][] numbers; // 存储每个格子周围的雷数
初始化雷区数据
在游戏开始时,根据自定义的参数(如雷区大小、雷的数量等)来初始化 mines
和 numbers
数组。
public void initializeMinefield(int rows, int cols, int numMines) { this.rows = rows; this.cols = cols; mines = new boolean[rows][cols]; numbers = new int[rows][cols]; // 随机放置雷 Random random = new Random(); int minesPlaced = 0; while (minesPlaced < numMines) { int r = random.nextInt(rows); int c = random.nextInt(cols); if (!mines[r][c]) { mines[r][c] = true; minesPlaced++; } } // 计算每个格子周围的雷数 for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { if (!mines[i][j]) { int count = 0; for (int dr = -1; dr <= 1; dr++) { for (int dc = -1; dc <= 1; dc++) { int ni = i + dr; int nj = j + dc; if (ni >= 0 && ni < rows && nj >= 0 && nj < cols && mines[ni][nj]) { count++; } } } numbers[i][j] = count; } } } }
自定义雷区参数
为了让用户能够自定义雷区,可以在游戏界面上添加一些输入控件,如文本框或下拉菜单,让用户输入雷区的行数、列数和雷的数量等参数。
添加自定义参数输入控件
private JTextField rowsField; private JTextField colsField; private JTextField minesField; private JButton customizeButton; public Minesweeper() { // ... 之前的代码 JPanel configPanel = new JPanel(); configPanel.add(new JLabel("行数:")); rowsField = new JTextField("10", 3); configPanel.add(rowsField); configPanel.add(new JLabel("列数:")); colsField = new JTextField("10", 3); configPanel.add(colsField); configPanel.add(new JLabel("雷数:")); minesField = new JTextField("15", 3); configPanel.add(minesField); customizeButton = new JButton("自定义雷区"); customizeButton.addActionListener(new CustomizeButtonListener()); configPanel.add(customizeButton); add(configPanel, BorderLayout.NORTH); } private class CustomizeButtonListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { try { int rows = Integer.parseInt(rowsField.getText()); int cols = Integer.parseInt(colsField.getText()); int mines = Integer.parseInt(minesField.getText()); if (rows > 0 && cols > 0 && mines >= 0 && mines <= rows cols) { initializeMinefield(rows, cols, mines); // 更新界面上的按钮数量以匹配新的雷区大小 panel.removeAll(); buttons = new JButton[rows][cols]; for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { buttons[i][j] = new JButton(); buttons[i][j].addActionListener(new ButtonClickListener(i, j)); panel.add(buttons[i][j]); } } panel.revalidate(); panel.repaint(); } else { JOptionPane.showMessageDialog(null, "请输入有效的参数!"); } } catch (NumberFormatException ex) { JOptionPane.showMessageDialog(null, "请输入数字!"); } } }
处理按钮点击事件
当用户点击一个按钮时,需要根据雷区数据来判断该位置是否是雷,或者是周围有多少雷,并在按钮上显示相应的信息,还需要处理游戏的胜负逻辑。
揭示雷区信息
@Override public void actionPerformed(ActionEvent e) { int row = this.row; int col = this.col; if (!mines[row][col]) { buttons[row][col].setText(String.valueOf(numbers[row][col])); buttons[row][col].setEnabled(false); // 递归揭示周围没有雷且周围雷数为 0 的格子 revealEmptyCells(row, col); } else { // 点击到雷,游戏结束 buttons[row][col].setText("雷"); revealAllMines(); JOptionPane.showMessageDialog(null, "你输了!"); } } private void revealEmptyCells(int row, int col) { if (row < 0 || row >= rows || col < 0 || col >= cols || !buttons[row][col].isEnabled()) { return; } if (numbers[row][col] == 0) { buttons[row][col].setText(""); buttons[row][col].setEnabled(false); for (int dr = -1; dr <= 1; dr++) { for (int dc = -1; dc <= 1; dc++) { revealEmptyCells(row + dr, col + dc); } } } else if (numbers[row][col] > 0) { buttons[row][col].setText(String.valueOf(numbers[row][col])); buttons[row][col].setEnabled(false); } }
揭示所有雷(用于游戏结束显示)
private void revealAllMines() { for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { if (mines[i][j]) { buttons[i][j].setText("雷"); } else if (buttons[i][j].isEnabled()) { buttons[i][j].setText(String.valueOf(numbers[i][j])); buttons[i][j].setEnabled(false); } } } }
判断游戏胜利
当用户成功揭示所有非雷的格子时,游戏胜利,可以通过一个计数器来记录已经揭示的非雷格子数量,当这个数量等于总非雷格子数量时,判断为胜利。
private int revealedCells = 0; private int totalNonMineCells = rows cols numMines; private void checkWin() { if (revealedCells == totalNonMineCells) { JOptionPane.showMessageDialog(null, "你赢了!"); // 可以在这里添加重置游戏或其他操作的代码 } }
在 actionPerformed
方法中,每次成功揭示一个非雷格子后,增加 revealedCells
计数器,并调用 checkWin
方法检查是否胜利,如果是点击到雷导致游戏结束,则不需要增加计数器。
@Override public void actionPerformed(ActionEvent e) { int row = this.row; int col = this.col; if (!mines[row][col]) { revealedCells++; buttons[row][col].setText(String.valueOf(numbers[row][col])); buttons[row][col].setEnabled(false); if (numbers[row][col] == 0) { revealEmptyCells(row, col); } checkWin(); } else { buttons[row][col].setText("雷"); revealAllMines(); JOptionPane.showMessageDialog(null, "你输了!"); } } ```这样,就实现了一个基本的可以自定义雷区的 Java 扫雷游戏,你可以进一步优化界面、添加更多功能,如计时、排行榜等,提升游戏的趣味性和完整性,以下是一个简单的相关问答FAQs:问题1:如何改变雷区的大小?答:在游戏界面的输入框中分别输入想要的行数、列数和雷数,然后点击“自定义雷区”按钮,程序会根据输入的参数重新初始化雷区并更新界面上的按钮布局。问题2:游戏中的数字代表什么意思?答:游戏中的数字表示该格子周围8个相邻格子中雷的数量,数字“3”表示该格子周围有3个雷,通过点击格子来揭示这些数字,从而帮助玩家判断雷的位置,避免踩雷,如果点击到雷,游戏结束;