?? 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 + -