Java实现扫雷游戏详细代码讲解
前言
扫雷是经典的小游戏之一,本文将详细讲解如何使用Java实现扫雷游戏,并提供完整的代码示例。
实现思路
- 界面设计:使用Swing开发GUI界面,布置扫雷棋盘、计时和雷数量显示。
- 地图生成:随机生成地图,并根据雷的数量给出提示。
- 扫雷逻辑:根据用户点击的位置判断是否为雷,显示相应的数字或“game over”等提示信息。
- 雷的标记:支持用户通过右键标记可能为雷的格子。
- 统计胜利:根据用户的相应操作,在必要时提示并计算胜利。
代码实现
界面
// 初始化窗口并设置大小
JFrame frame = new JFrame("扫雷");
frame.setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 初始化棋盘等控件
MineBoard board = new MineBoard(BOARD_SIZE, MINE_NUM);
TimeLabel timer = new TimeLabel();
MineCounter mineCounter = new MineCounter(MINE_NUM);
// 将控件加入布局
frame.getContentPane().add(BorderLayout.NORTH, timer);
frame.getContentPane().add(BorderLayout.CENTER, board);
frame.getContentPane().add(BorderLayout.SOUTH, mineCounter);
// 显示窗口
frame.setVisible(true);
地图生成
public class MineBoard extends JPanel {
private int[][] mineCount;
private boolean[][] isMine;
private boolean[][] isOpen;
// 生成地图
private void generateMap(int size, int num) {
Random rand = new Random();
isMine = new boolean[size][size];
isOpen = new boolean[size][size];
// 随机生成地雷位置
for (int i = 0; i < num; i++) {
int x = rand.nextInt(size);
int y = rand.nextInt(size);
if (isMine[x][y]) {
// 若当前位置已有地雷,则重新随机生成
i--;
} else {
isMine[x][y] = true;
}
}
// 根据地雷判断周围格子的数字
mineCount = new int[size][size];
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (!isMine[i][j]) {
int count = getMineCount(i, j);
mineCount[i][j] = count;
}
}
}
}
// 获取周围地雷数量
private int getMineCount(int x, int y) {
int count = 0;
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
int newX = x + i;
int newY = y + j;
if (newX >= 0 && newX < size && newY >= 0 && newY < size && isMine[newX][newY]) {
count++;
}
}
}
return count;
}
}
扫雷逻辑
public class MineBoard extends JPanel {
// ...
// 单击事件处理
private void handleLeftClick(MouseEvent e) {
int x = e.getX() / cellSize;
int y = e.getY() / cellSize;
if (isOpen[x][y]) {
// 若该位置已经打开,则跳过此次操作
return;
}
if (isMine[x][y]) {
// 点到地雷,游戏结束
gameOver();
} else if (mineCount[x][y] > 0) {
// 显示周边地雷数量
isOpen[x][y] = true;
repaint();
} else {
// 扩散周边空白区域
openAround(x, y);
}
}
// 右击事件处理
private void handleRightClick(MouseEvent e) {
int x = e.getX() / cellSize;
int y = e.getY() / cellSize;
if (isOpen[x][y]) {
// 若该位置已经打开,则跳过此次操作
return;
}
if (isMarked[x][y]) {
// 取消标记
isMarked[x][y] = false;
mineCounter.increase();
} else {
// 标记可能的地雷
isMarked[x][y] = true;
mineCounter.decrease();
}
repaint();
}
// 扩散周边空白区域
private void openAround(int x, int y) {
// ...
}
// 游戏结束
private void gameOver() {
// ...
}
}
示例
示例1:选择难度
用户可以通过下拉框选择难度,即不同的游戏地图大小和地雷数量。根据用户选择的难度,动态生成地图并在开始游戏时显示。
// 初始化下拉框
JComboBox difficultySelector = new JComboBox<String>(new String[] {
"Easy (9x9, 10 mines)", "Medium (16x16, 40 mines)", "Hard (22x22, 99 mines)"
});
frame.getContentPane().add(BorderLayout.NORTH, difficultySelector);
// ...
// 点击开始按钮时,获取用户选择的难度,并生成地图
startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String difficulty = (String)difficultySelector.getSelectedItem();
if (difficulty.equals("Easy (9x9, 10 mines)")) {
board.generateMap(9, 10);
} else if (difficulty.equals("Medium (16x16, 40 mines)")) {
board.generateMap(16, 40);
} else if (difficulty.equals("Hard (22x22, 99 mines)")) {
board.generateMap(22, 99);
}
// ...
}
});
示例2:显示周边数字或雷
用户单击某个格子后,在格子上显示相应的数字或“X”表示该位置为雷。为了实现这个功能,需要根据地图数据分别判断用户点击的位置是否为雷、是否为数字。
@Override
public void paintComponent(Graphics g) {
// ...
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (isOpen[i][j]) {
// 显示周边地雷数量或图标
if (isMine[i][j]) {
g.drawImage(mineImage, i * cellSize, j * cellSize, cellSize, cellSize, this);
} else {
g.drawString("" + mineCount[i][j], i * cellSize + cellSize / 2, j * cellSize + cellSize / 2);
}
} else if (isMarked[i][j]) {
// 标记可能为地雷
g.drawImage(flagImage, i * cellSize, j * cellSize, cellSize, cellSize, this);
}
}
}
// ...
}
总结
本文介绍了如何使用Java实现扫雷游戏,并提供了完整的代码示例。使用Java开发GUI程序比较方便,尤其是借助Swing等库,程序员可快速开发出大量的小工具和小游戏。除了UI外,本文还重点介绍了扫雷游戏逻辑的实现。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java实现扫雷游戏详细代码讲解 - Python技术站