天天看點

“精品”JAVA完美之作掃雷完整版

ava類庫中提供了用于GUI的swing開發工具包,我們可以利用swing設計出一些簡單的經典小遊戲,如掃雷,推箱子,俄羅斯方塊等.接下來我就簡單分享一下用Java設計掃雷遊戲的思路與過程.

首先,我們要設計出掃雷的視窗界面,說白了,也就是在視窗上繪制出指定行數和列數的小方格.要在窗體上繪制方格,我們需要一個JPanel面闆,是以我們定義類GamePanel讓它繼承自JPanel,然後我們在就可以這個類上繪制我們所要的資訊了.然後,在類中,我們定義一些基本的變量,如行數,列數,雷的數量等等,友善後面使用

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
 
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JPanel;
 
public class GamePanel extends JPanel {
 private static final long serialVersionUID = 1L;
 // 界面行數
 private int rows;
 // 界面列數
 private int cols;
 // 炸彈數
 private int bombCount;
 // 每個方格寬度
 private final int BLOCKWIDTH = 20;
 // 每個方格長度
 private final int BLOCKHEIGHT = 20;
 // 存儲界面中每一個方格的繪制資訊
 private JLabel[][] labels;
}
           

(JLabel标簽用于短文本字元串或圖像或二者的顯示區,我們用它來顯示方格邊界,數字,或者雷等資訊)

接下來我們在構造方法中初始化這些類變量

// 構造方法,初始化參數
 public GamePanel(int rows, int cols) {
 this.rows = rows;
 this.cols = cols;
 this.bombCount = rows * cols / 10;
 this.labels = new JLabel[rows][cols];
 this.setLayout(null);
 }
           

然後,我們就可以在這個JPanel面闆上繪制小方格了.我們先建立一個名為initLabels()的方法,在這個方法中根據行數和列數循環産生JLabel标簽,并将每個标簽的邊界繪制出來,填充背景并将它們存儲到類二維數組變量 labels中,這樣,我們就得到了一個充滿小方格的掃雷窗體

// 界面初始化,繪制掃雷的邊框
 private void initLabels(){
 for (int i = 0; i < this.rows; i++) {
 for (int j = 0; j < this.cols; j++) {
 JLabel l = new JLabel("", JLabel.CENTER);
 // 設定每個小方格的邊界
 l.setBounds(j * BLOCKWIDTH, i * BLOCKHEIGHT, BLOCKWIDTH, BLOCKHEIGHT);
 // 繪制方格邊框
 l.setBorder(BorderFactory.createLineBorder(Color.GRAY));
 // 設定方格為透明,便于我們填充顔色
 l.setOpaque(true);
 // 背景填充為黃色
 l.setBackground(Color.YELLOW);
 // 将方格加入到容器中(即面闆JPanel)
 this.add(l);
 // 将方格存到類變量中,友善公用
 labels[i][j] = l;
 }
 }
 
 }
           

然後在構造方法中調用這個初始化方法

當我們将這個JPanel面闆繪制完後,我們還要将它放在一個JFrame容器中它才能顯示出來,這樣我們就需要将JPanel的大小作為參數傳出去,友善設定容器的大小,是以我們再定義一個public的方法,計算寬和高,并以數組的形式傳遞出去

import java.awt.Container; 
import javax.swing.JFrame;
 
public class Game {
 public static void main(String[] args) {
 // 建立JFrame對象作為容器
 JFrame w = new JFrame();
 // 建立mainPanel對象,初始化一個20*30的方格窗體
 GamePanel mainPanel = new GamePanel(20, 30);
 // 擷取JFrame應給設定的寬度和高度
 int[] a = mainPanel.returnSize();
 // 設定JFame寬和高
 w.setSize(a[0], a[1]);
 Container c = w.getContentPane();
 c.add(mainPanel);
 
 w.setVisible(true);
 }
}
           

運作程式,結果如下

“精品”JAVA完美之作掃雷完整版

這樣,我們第一階段的工作就完成了.接下來,我們要在上面這個圖中産生bombCount個炸彈,也就是在我們生成的labels中随機挑選出bombCount個炸彈,并用"*"顯示出來

// 産生bombCount個炸彈,并在labels中用"*"标注出來
 private void randomBomb() {
 for (int i = 0; i < this.bombCount; i++) {
 // 生成一個随機數表示行坐标
 int rRow = (int) (Math.random() * this.rows);
 // 生成一個随機數表示列坐标
 int rCol = (int) (Math.random() * this.cols);
 // 根據坐标确定JLabel的位置,并顯示*
 this.labels[rRow][rCol].setText("*");
 // 設定背景顔色
 this.labels[rRow][rCol].setBackground(Color.DARK_GRAY);
 // 設定*的顔色
 this.labels[rRow][rCol].setForeground(Color.RED);
 }
 }
           

然後我們在initLabels()方法中調用randomBomb()這個方法,運作程式,顯示如下:

“精品”JAVA完美之作掃雷完整版

至此,我們已經完成了掃雷遊戲的一半程式,隻剩下填充按鈕和點選按鈕後發生的邏輯判斷了,我們已經将掃雷的繪制了方格陣列并随機配置設定了炸彈的位置,接下來我們要将陣列全部覆寫上按鈕.因為我們要通過按鈕來獲知目前方格的坐标,是以簡單的Button按鈕還無法滿足我們的要求,是以,我們就自定義一個按鈕的類,讓它繼承自Button類,但要給他加上行号和列号,這樣我們就能直接通過按鈕讀取它的位置了

import javax.swing.JButton;
 
public class MyButton extends JButton {
 private static final long serialVersionUID = 1L;
 protected int row;
 protected int col;
}
           

然後我們就可以在GamePanel類中添加按鈕了

// 初始化按鈕,将JLabel覆寫住
 private void initButtons() {
 // 循環生成按鈕
 for (int i = 0; i < rows; i++) {
 for (int j = 0; j < cols; j++) {
 MyButton btn = new MyButton();
 // 根據JLabel大小設定按鈕的大小邊界
 btn.setBounds(j * BLOCKWIDTH, i * BLOCKHEIGHT, BLOCKWIDTH, BLOCKHEIGHT);
 this.add(btn);
 // 将按鈕存在類變量中(當然,實際上存的是對象的引用位址)
 buttons[i][j] = btn;
 btn.row = i;
 btn.col = j;
 // 給按鈕添加監聽器,注冊點選事件
 // (單機按鈕時,将執行内部類ActionListener()中的actionPerformed(ActionEvent e)方法)
 btn.addActionListener(new ActionListener() {
 
 @Override
 public void actionPerformed(ActionEvent e) {
 // TODO Auto-generated method stub
 
 }});
 }
 }
 }
           

按鈕全部覆寫以後,顯示如下:

“精品”JAVA完美之作掃雷完整版

最後,我們就差單擊按鈕後判斷按鈕底下是炸彈,空白,還是數字,如果下面是數字的話,我們就打開按鈕(也就是将按鈕設定為不可見,就可以看見JLabel了); 如果單擊的按鈕下面是空白的話先要将它打開,并且判斷它周圍的八個方塊是否為空的,進入遞歸調用.

首先,要判斷每個小方塊周圍的八個方塊,就要先判斷它是否越界,我們設為一個類變量作為坐标偏移量

判斷是否越界:

// 判斷位置是否越界
 private boolean verify(int row, int col) {
 return row >= 0 && row < this.rows && col >= 0 && col < this.cols;
 }
           

然後我們寫單擊按鈕時的邏輯方法

// 單擊按鈕時打開或成片打開
 private void open(MyButton btn) {
 // 先将當期按鈕設定為不可見,即打開了按鈕
 btn.setVisible(false);
 // 判斷按鈕中 是否為數字還是空
 switch (labels[btn.row][btn.col].getText()) {
 // 如果是炸彈則将全部按鈕都打開,遊戲結束
 case "*" :
 for (int i = 0; i < rows; i++) {
 for (int j = 0; j < cols; j++) {
 buttons[i][j].setVisible(false);
 }
 }
 break;
 // 如果是空的則将他周圍空的按鈕都打開,進入遞歸
 case "" :
 for (int[] off: offset) {
 int newRow = btn.row + off[0];
 int newCol = btn.col + off[1];
 if (verify(newRow, newCol)) {
 MyButton sButton = buttons[newRow][newCol];
 if (sButton.isVisible()) {
 open(sButton);
 }
 }
 }
 default:
 }
 }
           

最後,我們在initButtons方法的單擊事件中引用這個方法

btn.addActionListener(new ActionListener() {
 
 @Override
 public void actionPerformed(ActionEvent e) {
 // TODO Auto-generated method stub
 open((MyButton) e.getSource());
 }});
           

大功告成,我們的簡易掃雷遊戲正式完成了!

“精品”JAVA完美之作掃雷完整版

總結

篇幅有限!篇幅有限!關于AVA完美之作掃雷完整版,就聊到這兒啦…啦…啦…

以上小編所介紹的全部相關的筆記資料都已整理成冊,不論是Redis面試+Redis實戰pdf,還是MongDB快速上手+MongDB叢集安全等手寫pdf筆記,想白嫖都很so easy!!

——如果你get到了,那就點個贊轉發支援一波吧!

——整理不易,白嫖私信我擷取資料,100%回複分享!

——也可以加小助手vx:xcw18874131605擷取資料哦

——祝前程似錦,offer不斷,好好學習,天天向上!