📄 sweepbomb.java
字号:
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
//本程序实现了扫雷游戏的基本操作,包括中键打开周围8个格,但还有待不断完善
class MyButton extends JButton{ // 按钮类继承自 JButton
public int x, y; //坐标
private boolean isBomb = false; //是否是雷
private boolean isFlaged = false; //是否设置为旗帜
private boolean isOpened = false; //是否作键打开
private int bombNumber = 0; //周围8个格的地雷数量
MyButton(int x, int y) {
this.x = x;
this.y = y;
}
public void Init() { //初始化
isBomb = false;
isFlaged = false;
isOpened = false;
}
public void setBomb() { isBomb = true; }
public void setFlaged() { isFlaged = true; }
public void deleteFlag() { isFlaged = false; }
public void setOpened() { isOpened = true; }
public void setBombNumber(int bombNumber) { this.bombNumber = bombNumber;}
public boolean isBomb() { return isBomb; }
public boolean isFlaged() { return isFlaged; }
public boolean isOpened() { return isOpened; }
public int getBombNumber() { return bombNumber; }
public String getBombNumber(int i) {
Integer bNumber = new Integer(bombNumber);
return bNumber.toString();
}
}
public class SweepBomb extends MouseAdapter{
final int Rows = 10, Columns = 10, TotalBomb = 20; //设置大小和地雷数
int bombNow; //当前地雷数量
private boolean gameOver = false; //游戏失败标记
private static Random rand = new Random(); //随机数埋雷
JFrame sweepFrame; //以下为界面设计
JPanel panel1, panel2;
JButton start;
JLabel label;
JTextField textl1, textl2;
MyButton[][] sweepBombButton = new MyButton[Rows][Columns];
SweepBomb() {
sweepFrame = new JFrame("扫雷游戏");
sweepFrame.setBounds(100, 0, 60*Columns, 60*Rows);
panel1 = new JPanel();
panel2 = new JPanel();
start = new JButton("重新开始");
start.addMouseListener(this);
label = new JLabel("雷数");
textl1 = new JTextField(new Integer(TotalBomb).toString());
textl2 = new JTextField("小心地雷");
panel1.setLayout(new FlowLayout());
panel2.setLayout(new GridLayout(Rows, Columns, 0, 0));
panel1.add(start);
panel1.add(label);
panel1.add(textl1);
panel1.add(textl2);
for(int i = 0; i < Rows; i++) {
for(int j = 0; j < Columns; j++) {
sweepBombButton[i][j] = new MyButton(i, j);
sweepBombButton[i][j].addMouseListener(this);
panel2.add(sweepBombButton[i][j]);
}
}
sweepFrame.setLayout(new BorderLayout(0,0));
sweepFrame.add(panel1,BorderLayout.NORTH);
sweepFrame.add(panel2,BorderLayout.CENTER);
sweepFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
sweepFrame.setVisible(true);
startGame(); //开始游戏
}
public void Init() { //将每个按键初始化
for(int i = 0; i < Rows; i++) {
for(int j = 0; j < Columns; j++) {
sweepBombButton[i][j].Init();
sweepBombButton[i][j].setForeground(Color.black);
sweepBombButton[i][j].setText("");
}
}
}
public void berryBomb() { //随机埋地雷,地雷数指定
bombNow = TotalBomb;
for(int beryBomb = TotalBomb; beryBomb > 0; beryBomb--){
int i,j;
do {
i = rand.nextInt(Rows);
j = rand.nextInt(Columns);
} while(sweepBombButton[i][j].isBomb());
sweepBombButton[i][j].setBomb();
}
}
public int getBombNumber(int x, int y) { //查找周围的地雷总数
int sum = 0;
if(x - 1 >= 0 && y - 1 >= 0 && (sweepBombButton[x-1][y-1].isBomb()))
sum++;
if(x - 1 >= 0 && (sweepBombButton[x-1][y].isBomb()))
sum++;
if(x - 1 >= 0 && y + 1 < Columns && (sweepBombButton[x-1][y+1].isBomb()))
sum++;
if(y - 1 >= 0 && (sweepBombButton[x][y-1].isBomb()))
sum++;
if(y + 1 < Columns && (sweepBombButton[x][y+1].isBomb()))
sum++;
if(x + 1 < Columns && y - 1 >= 0 && (sweepBombButton[x+1][y-1].isBomb()))
sum++;
if(x + 1 < Columns && (sweepBombButton[x+1][y].isBomb()))
sum++;
if(x + 1 < Columns && y + 1 < Columns && (sweepBombButton[x+1][y+1].isBomb()))
sum++;
return sum;
}
public void startGame() { //开始游戏
gameOver = false;
berryBomb(); //重新埋地雷
label.setText("雷数");
textl1.setText(new Integer(TotalBomb).toString());
textl2.setText("小心地雷");
for(int i = 0; i < Rows; i++) {
for(int j = 0; j < Columns; j++) {
if(!sweepBombButton[i][j].isBomb())
sweepBombButton[i][j].setBombNumber(this.getBombNumber(i, j));
}
}
}
public void blankAera(int x, int y) { //左键按到0,打开一片为0的区域,采用递归法
if(sweepBombButton[x][y].getBombNumber() == 0 &&
(!sweepBombButton[x][y].isFlaged()) &&(!sweepBombButton[x][y].isOpened())) {
sweepBombButton[x][y].setForeground(Color.blue);
sweepBombButton[x][y].setText("0");
sweepBombButton[x][y].setOpened();
if(x-1 >= 0) blankAera(x-1, y);
if(x+1 < Columns) blankAera(x+1, y);
if(y - 1 >=0) blankAera(x, y-1);
if(y + 1 < Rows) blankAera(x, y+1);
}
}
//以下两个函数用于实现中键操作
public boolean aroundEqual(int x, int y) { //查找周围8个格的红旗数量
int sum = 0;
if(x - 1 >= 0 && y - 1 >= 0 && (sweepBombButton[x-1][y-1].isFlaged()))
sum++;
if(x - 1 >= 0 && (sweepBombButton[x-1][y].isFlaged()))
sum++;
if(x - 1 >= 0 && y + 1 < Columns && (sweepBombButton[x-1][y+1].isFlaged()))
sum++;
if(y - 1 >= 0 && (sweepBombButton[x][y-1].isFlaged()))
sum++;
if(y + 1 < Columns && (sweepBombButton[x][y+1].isFlaged()))
sum++;
if(x + 1 < Columns && y - 1 >= 0 && (sweepBombButton[x+1][y-1].isFlaged()))
sum++;
if(x + 1 < Columns && (sweepBombButton[x+1][y].isFlaged()))
sum++;
if(x + 1 < Columns && y + 1 < Columns && (sweepBombButton[x+1][y+1].isFlaged()))
sum++;
return sum == sweepBombButton[x][y].getBombNumber();
}
public void openAround(int x, int y) {
//打开周围8个格,遇到是地雷但没有标记红旗则游戏结束
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 < Columns) {
if(sweepBombButton[i][j].isBomb()) {
if(!sweepBombButton[i][j].isFlaged()) {
sweepBombButton[i][j].setForeground(Color.black);
sweepBombButton[i][j].setText("*");
gameOver();
gameOver = true;
}
}
else {
sweepBombButton[i][j].setOpened();
sweepBombButton[i][j].setForeground(Color.blue);
sweepBombButton[i][j].setText(sweepBombButton[i][j].getBombNumber(1));
}
}
}
}
}
public void gameOver() { //游戏结束,显示所有地雷
textl2.setText("很遗憾,你输了!");
for(int i = 0; i < Rows; i++) {
for(int j = 0; j < Columns; j++) {
if(sweepBombButton[i][j].isBomb()) {
sweepBombButton[i][j].setForeground(Color.black);
sweepBombButton[i][j].setText("*");
}
}
}
}
public boolean isWin() { //所有按键都打开则获胜,地雷扫出获胜
if(bombNow != 0)
return false;
for(int i = 0; i < Rows; i++) {
for(int j = 0; j < Columns; j++) {
if((!sweepBombButton[i][j].isOpened()) && (!sweepBombButton[i][j].isFlaged()))
return false;
}
}
return true;
}
public void mouseClicked(MouseEvent e) { //鼠标操作响应
if(e.getSource() == start){ //按动重新开始按钮则重新开始游戏
Init();
startGame();
}
else {
if(!gameOver && !isWin()){ //没赢也没输的情况下
int i = ((MyButton)e.getSource()).x; //找到对应按键
int j = ((MyButton)e.getSource()).y;
if(e.getButton() == e.BUTTON1) { //如果按下左键
if(sweepBombButton[i][j].isBomb()){ //踩雷的话结束游戏
gameOver();
gameOver = true;
}
else { //否则打开按键
int bombAround = sweepBombButton[i][j].getBombNumber();
if(bombAround == 0){ //按键数为0打开一片为0的区域
blankAera(i, j);
}
else {
Integer bombNumber = new Integer(bombAround);
sweepBombButton[i][j].setForeground(Color.blue);
sweepBombButton[i][j].setText(bombNumber.toString());
sweepBombButton[i][j].setOpened();
}
}
}
else if(e.getButton() == e.BUTTON3) { //如果按下右键
if(!sweepBombButton[i][j].isOpened()){ //已经打开的话没反应
if(sweepBombButton[i][j].isFlaged()){//已经插红旗的话变成问号
sweepBombButton[i][j].deleteFlag();//取消设置红旗
sweepBombButton[i][j].setForeground(Color.green);
sweepBombButton[i][j].setText("?");
bombNow++; //当前地雷数增加
textl1.setText((new Integer(bombNow).toString()));
}
else {
sweepBombButton[i][j].setFlaged(); //没有插红旗则插上红旗
sweepBombButton[i][j].setForeground(Color.red);
sweepBombButton[i][j].setText("旗");
bombNow--; //当前地雷数减小
textl1.setText((new Integer(bombNow).toString()));
}
}
}
else if(e.getButton() == e.BUTTON2) { //如果在打开的按键上按下中键
if(sweepBombButton[i][j].isOpened()) {
if(aroundEqual(i, j)) { //周围标出地雷数等于实际地雷数
openAround(i, j); //打开周围8个
}
}
}
if(isWin()) {
textl2.setText("恭喜你赢了!");
}
}
}
}
public static void main(String[] args) {
SweepBomb sweepBomb = new SweepBomb();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -