原生 JS 實現掃雷 (分析+代碼實現)

来源:https://www.cnblogs.com/kilomChou/archive/2019/04/05/10652405.html
-Advertisement-
Play Games

原生 JavaScript 實現掃雷 完整思路分析,代碼實現。 ...


閱讀這篇文章需要掌握的基礎知識:Html5、CSS、JavaScript

線上Demo:查看

掃雷規則

在寫掃雷之前,我們先瞭解下它的游戲規則

● 掃雷是一個矩陣,地雷隨機分佈在方格上。

● 方格上的數字代表著這個方格所在的九宮格內有多少個地雷。

● 方格上的旗幟為玩家所作標記。

● 踩到地雷,游戲失敗。

● 打開所有非雷方格,游戲勝利。

 

功能實現思路分析

矩陣的生成

  • 矩陣的生成有多種方式可以實現,我們這裡使用<table>+<span>標簽。
  • 通過 js 給定行數與列數在<table>的 innerHtml 寫入<span>標簽來動態生成矩陣。

方格的打開與標記

  • 通過 onmousedown 事件,傳入點擊的方格的坐標及event,判斷event為左鍵還是右鍵。
  • 左鍵打開方格,右鍵標記方格。

地雷的隨機分佈

  • 由於第一次打開的方格不能為地雷所以我們把生成地雷的函數放在第一次點擊方格時。
  • 我們通過迴圈用 Math.random() 函數來隨機生成地雷的二維坐標。
  • 判斷坐標是否不為第一次點擊方格的坐標以及沒有雷存在。
  • 是則將方格設置為地雷,當前地雷數+1,並且將九宮格內的方格的計雷數+1。
  • 否則跳過進入下個迴圈,直到地雷的數量達到設定的最大雷數,結束迴圈。

踩到地雷游戲結束

  • 打開方格為地雷時,提示游戲結束。
  • 通過遍歷矩陣來打開所有地雷

連鎖打開方格

  • 當打開的方格為計雷數為0的方格,自動打開九宮格內的非雷方格。
  • 如果打開的非雷方格九宮格內仍有非雷方格,繼續打開九宮格內的非雷方格,直到沒有為止。

游戲勝利條件

  • 當所有非雷方格被打開即為游戲勝利。
  • 在每次打開方格函數中都遍歷一遍矩陣,當找到有未打開的非雷方格時則結束遍歷。
  • 當遍歷完未找到未打開的非雷方格則提示游戲勝利。

剩餘地雷數與計時器

  • 地雷的總數減去玩家標記的方格數即為剩餘地雷數
  • 計時器可以用setInterval()函數實現

 

代碼實現

生成矩陣

我們先在<body>里寫一個<table>標簽,設定個 id='grid'

<table id='grid'></table>

然後在<script>里 定義兩個變數 row--行數 col--列數

通過兩個for迴圈把 (方格)<span> 寫入到 (矩陣)<table> 里,通過<td><tr>標簽控制行列。

var row = 10; //行數
var col = 10; //列數

//生成矩陣html  <tr>--行標簽 <td>--列標簽
let gridHtml = '';
for (let i = 0; i < row; i++) {
  gridHtml += '<tr>'
  for (let j = 0; j < col; j++) {
    gridHtml += '<td><span class="blocks"></span></td>';
  }
  gridHtml += '<tr>'
}
//寫入html
document.getElementById('grid').innerHTML = gridHtml;

 寫一下矩陣和方格的CSS樣式。

#grid {
    margin: auto;  /* 讓矩陣居中顯示於頁面 */
}

.blocks {
    width: 30px;
    height: 30px;
    line-height: 30px;
    display: block;   /* 讓span以block方式顯示 */
    text-align: center;
    border: solid 1px #000;
    user-select: none;  /* 設置不可拖拽選中 */
    cursor: pointer;  /* 設置滑鼠停留樣式 */
}

.blocks:hover {
    background: #0af;  /* 滑鼠停留時背景顏色變化 */
}

至此打開頁面,矩陣就初步顯示出來了。

把矩陣的方格放入二維數組中

我們先定義一個全局變數grid。

把剛纔寫的生成矩陣的代碼寫成一個函數 function init_grid()

document.getElementsByClassName('blocks') 返回的是一個一維數組,我們把它通過兩個for迴圈轉化為二維數組。

給每個方格定義一個屬性 count 計雷數 ---  blocks[i].count = 0;

然後把返回值賦值給grid ---  grid = init_grid();

var row = 10; //行數
var col = 10; //列數
var grid = init_grid();

//初始化矩陣 (row-行數 col-列數)
function init_grid() {

    //生成矩陣html <tr>--行標簽 <td>--列標簽
    let gridHtml = '';
    for (let i = 0; i < row; i++) {
        gridHtml += '<tr>'
        for (let j = 0; j < col; j++) {
            gridHtml +=
                '<td><span class="blocks"></span></td>';
        }
        gridHtml += '<tr>'
    }
    //寫入html
    document.getElementById('grid').innerHTML = gridHtml;

    //返回矩陣二維數組
    let blocks = document.getElementsByClassName('blocks');
    let grid = new Array();
    for (let i = 0; i < blocks.length; i++) {
        if (i % col === 0) {
            grid.push(new Array());
        }
        //初始化計雷數
        blocks[i].count = 0;
        grid[parseInt(i / col)].push(blocks[i]);
    }
    return grid;
}

寫完了這段我們先寫一段代碼測試下grid有沒有賦值成功,遍歷grid把方格的值改為對應的坐標。

for (let i = 0; i < row; i++) {
    for (let j = 0; j < col; j++) {
        grid[i][j].innerHTML = i + ',' + j;
    }
}

可以看到 grid 已經賦值成功!沒成功的回去檢查下代碼。(Tip:測試完記得把測試代碼刪除)

方格的點擊事件

定義一個函數 function block_click( _i, _j, e) 的大致框架

e為傳入的滑鼠事件,e.button ( 0為左鍵,2為右鍵 )。

isOpen屬性為自定義屬性,用來判斷方格是否打開。

//方格點擊事件 _i:坐標i _j:坐標j e:滑鼠事件
function block_click(_i, _j, e) {

    //跳過已打開的方格
    if (grid[_i][_j].isOpen) {
        return;
    }

    //滑鼠左鍵打開方格
    if (e.button === 0) {

    }
    //滑鼠右鍵標記方格
    else if (e.button === 2) {

    }
}

然後修改下之前寫在 init_grid 函數里的<span>的屬性,綁定 onmousedown 事件,傳入 i,j 坐標,和滑鼠事件 event

gridHtml += '<td><span class="blocks" onmousedown="block_click(' + i + ',' + j + ',event)"></span></td>';

修改下body的屬性 加入防拖拽生成新頁面和屏蔽右鍵菜單。

<!-- ondragstart:防拖拽生成新頁面 oncontextmenu:屏蔽右鍵菜單-->
<body ondragstart='return false' oncontextmenu='self.event.returnValue=false'>

我們在滑鼠左鍵事件裡面寫下測試代碼,當左鍵方格時顯示它的坐標。

//滑鼠左鍵打開方格
if (e.button === 0) {
    grid[_i][_j].innerHTML = _i + ',' + _j;
}

 效果如下,沒成功的回去檢查下代碼。(Tip:測試完記得把測試代碼刪除)

方格的標記

在滑鼠右鍵事件寫標記代碼,這裡用 ▲ 來作為標記。

右擊一次添加標記,再次右擊刪除標記。

//滑鼠右鍵標記方格
else if (e.button === 2) {

    let block = grid[_i][_j];
    if (block.innerHTML !== '▲') {
        block.innerHTML = '▲';
    } else {
        block.innerHTML = '';
    }
}

效果如下:

隨機生成地雷

由於第一次打開的方格不能為地雷所以我們把生成地雷的函數放在第一次點擊方格時。

先定義全局變數 maxCount --- 最大地雷數  isFirstOpen --- 是否第一次打開方格。

var row = 10; //行數
var col = 10; //列數
var grid = init_grid();
var maxCount = 10; //最大地雷數量
var isFirstOpen = true; //第一次打開方格

在滑鼠左鍵事件裡面寫第一次打開方格生成地雷的代碼的大致框架。

//滑鼠左鍵打開方格
if (e.button === 0) {

    //第一次打開
    if (isFirstOpen) {

        isFirstOpen = false;
        let count = 0; //當前地雷數

        //生成地雷
        while (count < maxCount) {
            //........
        }
    }
}

完善生成地雷代碼:

生成隨機坐標 ri,rj,判斷該坐標不等於第一次點擊方格的坐標以及該坐標表方格不為地雷。

條件成立,將坐標對應方格的 isMine 設置為true,當前地雷數+1,並使九宮格內非雷方格的計雷數 count +1

自定義屬性isMine代表方格為地雷。

自定義屬性count為計雷數。

當地雷數大於最大地雷數,結束迴圈。

//生成地雷
while (count < maxCount) {

    //生成隨機坐標
    let ri = Math.floor(Math.random() * row);
    let rj = Math.floor(Math.random() * col);

    //坐標不等於第一次點擊方格的坐標 && 非雷方格
    if (!(ri === _i && rj === _j) && !grid[ri][rj].isMine) {
        grid[ri][rj].isMine = true; //自定義屬性isMine代表方格為地雷
        count++; //當前地雷數+1

        //更新九宮格內非雷方格的計雷數
        for (let i = ri - 1; i < ri + 2; i++) {
            for (let j = rj - 1; j < rj + 2; j++) {
                //判斷坐標防越界
                if (i > -1 && j > -1 && i < row && j < col) {
                    //計雷數+1
                    grid[i][j].count++;
                }
            }
        }
    }
}

寫個測試代碼在生成地雷後顯示所有方格的狀態。(Tip:測試完記得把測試代碼刪除)

for (let i = 0; i < row; i++) {
    for (let j = 0; j < col; j++) {
        //判斷方格是否為雷
        if (grid[i][j].isMine) {
            //顯示為雷
            grid[i][j].innerHTML = '雷';
        } else {
            //否則顯示計雷數
            grid[i][j].innerHTML = grid[i][j].count;
        }
    }
}

效果如下:可以看到已經隨機生成了雷,計雷數也正確顯示了。

方格的打開事件

在生成地雷的代碼下,加入方格打開代碼函數 block_open(_i,_j) 的大致框架。

定義 function op(block) 函數設定打開方格的狀態與樣式。

判定打開的方格的類型

block.isMine 為打開地雷方格 --> 游戲結束

block.count === 0 為打開計雷數為0的方格 --> 連鎖打開非雷方格

else 為打開計雷數大於0的方格 --> 顯示方格計雷數

//滑鼠左鍵打開方格
if (e.button === 0) {

    //第一次打開
    if (isFirstOpen) {
        //.......
    }

    //執行打開方格函數
    block_open(_i, _j);

    //打開方格函數
    function block_open(_i, _j) {

        let block = grid[_i][_j];
        op(block);

        //設定打開方格的狀態與樣式
        function op(block) {
            block.isOpen = true; //isOpen為自定義屬性,設置為true代表已打開
            block.style.background = '#ccc'; //將背景設置為灰色
            block.style.cursor = 'default'; //將滑鼠停留樣式設置為預設
        }

        if (block.isMine) {
            //踩雷
        } else if (block.count === 0) {
            //打開計雷數為0的方格
        } else {
            //打開計雷數不為0的方格
        }
    }
}

打開非雷方格顯示計雷數

 我們先把最簡單的顯示方格計雷數搞定。

else {
    //打開計雷數不為0的方格
    block.innerHTML = block.count;  //顯示計雷數
}

效果如下:

踩雷游戲結束

接下來寫踩雷代碼,當打開的方格為雷時,將其顯示為'雷',並打開所有的地雷,提示游戲結束。

if (block.isMine) {
    //踩雷
    block.innerHTML = '雷'; //顯示為 '雷'
    //遍歷矩陣打開所有的地雷方格
    for (let i = 0; i < row; i++) {
        for (let j = 0; j < col; j++) {
            //找到地雷
            block = grid[i][j];
            if (!block.isOpen && block.isMine) {
                op(block); //設置打開狀態和樣式
                block.innerHTML = '雷'; //顯示為 '雷'
            }
        }
    }
    //提示游戲結束
    alert("游戲結束");
}

效果如下:

連鎖打開方格

打開的方格為計雷數為0的方格,自動打開九宮格內的非雷方格,迴圈遞歸到沒有為止。

計雷數為0就沒必要讓innerHtml顯示0了,保持空白就行。

else if (block.count === 0) {
    //打開計雷數為0的方格
    //遍歷九宮格內的方格
    for (let i = _i - 1; i < _i + 2; i++) {
        for (let j = _j - 1; j < _j + 2; j++) {
            //判斷是否越界&&跳過已打開的方格&&非雷
            if (i > -1 && j > -1 && i < row && j < col && !grid[i][j].isOpen && !grid[i][j].ismine) {
                //遞歸打開方格函數
                block_open(i, j);
            }
        }
    }
}

效果如下:

游戲勝利條件

掃雷大體框架已經出來了,我們現在做勝利條件的判定。

在方格點擊函數最後寫判斷代碼。

//方塊點擊事件 _i:坐標i _j:坐標j e:滑鼠事件
function block_click(_i, _j, e) {

    //跳過已打開的方塊
    if (grid[_i][_j].isOpen) {
        //...
    }
    //滑鼠左鍵打開方塊
    if (e.button === 0) {
        //...
    }
    //滑鼠右鍵標記方塊
    else if (e.button === 2) {
        //...
    }

    //遍歷矩陣
    let isWin = true;
    for (let i = 0; i < row; i++) {
        for (let j = 0; j < col; j++) {
       let block = grid[i][j];
//判斷游戲勝利條件(所有的非雷方格已打開) if (!block.isMine && !block.isOpen) { //如果有未打開的非雷方塊 條件不成立 isWin = false; } } } if (isWin) { alert("游戲勝利"); } }

效果如下:(還專門玩了一遍^ ^)

游戲部分到這裡就完成了!

剩餘地雷數與計時器

最後,我們做一下剩餘地雷數和計時器的顯示。

我們寫個 <div> 在 <table> 的上面,放兩個 <span> 來做顯示框,<label> 用來給 js 計數。

<div id='bar'>
    <span class='bar'>剩餘雷數:<label id='count'>0</label></span>
    <span class='bar'>計時:<label id='time'>0</label>s</span>
</div>

<table id='grid'></table>

再寫下CSS樣式:

#bar {
    text-align: center;
    margin-bottom: 20px;
}

.bar {
    height: 25px;
    width: 150px;
    line-height: 25px;
    display: inline-block;
    border: solid 1px #000;
    margin-left: 20px;
    margin-right: 20px;
}

效果如下:

在 js 中定義兩個全局變數拿到 <lable> count 和 time

然後讓地雷數量等於最大地雷數,設置個100ms定時器,每次+0.1s,保留一位小數。

var count = document.getElementById('count'); //剩餘地雷數
count.innerHTML = maxCount; //初始化剩餘雷數

var time = document.getElementById('time'); //計時器
var timer = setInterval(function () {
  let seconds = (parseFloat(time.innerHTML) + 0.1).toFixed(1); //保留一位小數
  time.innerHTML = seconds;
}, 100) //定時器 100ms執行一次

我們修改下方格點擊事件中遍歷矩陣的代碼,更新剩餘地雷數,勝利時結束計時。

//遍歷矩陣
let isWin = true;
count.innerHTML = maxCount; //重置剩餘地雷數
for (let i = 0; i < row; i++) {
    for (let j = 0; j < col; j++) {
        let block = grid[i][j];

        //找到標記
        if (block.innerHTML === '▲') {
            count.innerHTML = parseInt(count.innerHTML) - 1; //剩餘地雷數-1
        }

        //判斷游戲勝利條件(所有的非雷方格已打開)
        if (!block.isMine && !block.isOpen) {
            //如果有未打開的非雷方塊 條件不成立
            isWin = false;
        }
    }
}
if (isWin) {
    clearInterval(timer); //游戲勝利結束計時,清除定時器
    alert("游戲勝利");
}

再修改踩雷的代碼,結束計時。

if (block.isMine) {
    //踩雷
    block.innerHTML = '雷'; //顯示為 '雷'
    //遍歷矩陣打開所有的地雷方格
    for (let i = 0; i < row; i++) {
        for (let j = 0; j < col; j++) {
            //找到地雷
            block = grid[i][j];
            if (!block.isOpen && block.isMine) {
                op(block); //設置打開狀態和樣式
                block.innerHTML = '雷'; //顯示為 '雷'
            }
        }
    }
    clearInterval(timer); //游戲結束停止計時,清除定時器
    //提示游戲結束
    alert("游戲結束");
}

OK,大功告成!!!後續還可以加入選擇難度的功能,重新開始按鈕,動畫效果等等,這個就看你們發揮了!!

 

 

完整代碼

<!DOCTYPE html>
<html>

<head>
  <title>掃雷</title>
  <style>
    #bar {
      text-align: center;
      margin-bottom:20px;
    }

    .bar {
      height: 25px;
      width: 150px;
      line-height: 25px;
      display: inline-block;
      border: solid 1px #000;
      margin-left: 20px;
      margin-right: 20px;
    }

    #grid {
      margin: auto;
    }

    .blocks {
      width: 30px;
      height: 30px;
      line-height: 30px;
      display: block;
      text-align: center;
      border: solid 1px #000;
      user-select: none;
      cursor: pointer;
    }

    .blocks:hover {
      background: #0af;
    }
  </style>
</head>

<!-- ondragstart:防拖拽生成新頁面 oncontextmenu:屏蔽右鍵菜單-->

<body ondragstart='return false' oncontextmenu='self.event.returnValue=false'>

  <div id='bar'>
    <span class='bar'>剩餘雷數:<label id='count'>0</label></span>
    <span class='bar'>計時:<label id='time'>0</label>s</span>
  </div>
  <table id='grid'></table>

  <script>
    var row = 10; //行數
    var col = 10; //列數
    var maxCount = 10; //最大地雷數量
    var isFirstOpen = true; //第一次打開方格
    var grid = init_grid(); //初始化
    var count = document.getElementById('count'); //剩餘雷數
    var time = document.getElementById('time'); //計時

    //初始化矩陣 (row-行數 col-列數)
    function init_grid() {

      //生成矩陣html <tr>--行標簽 <td>--列標簽
      let gridHtml = '';
      for (let i = 0; i < row; i++) {
        gridHtml += '<tr>'
        for (let j = 0; j < col; j++) {
          gridHtml +=
            '<td><span class="blocks" onmousedown="block_click(' + i + ',' + j + ',event)"></span></td>';
        }
        gridHtml += '<tr>'
      }
      //寫入html
      document.getElementById('grid').innerHTML = gridHtml;

      //返回矩陣二維數組
      let blocks = document.getElementsByClassName('blocks');
      let grid = new Array();
      for (let i = 0; i < blocks.length; i++) {
        if (i % col === 0) {
          grid.push(new Array());
        }
        //初始化計雷數
        blocks[i].count = 0;
        grid[parseInt(i / col)].push(blocks[i]);
      }
      return grid;
    }

    //方格點擊事件 _i:坐標i _j:坐標j e:滑鼠事件
    function block_click(_i, _j, e) {

      //跳過已打開的方格
      if (grid[_i][_j].isOpen) {
        return;
      }

      //滑鼠左鍵打開方格
      if (e.button === 	   

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 簡介: 倒計時秒殺組件在電商網站中層出不窮 不過思路萬變不離其蹤,我自己根據其他資料設計了一個vue版的 核心思路:1、時間不能是本地客戶端的時間 必須是伺服器的時間這裡用一個settimeout代替 以為時間必須統一 2、開始時間,結束時間通過父組件傳入,當伺服器時間在這個開始時間和結束時間的範圍 ...
  • 不要慌!下麵開始幫你找到,很簡單! ...
  • emmmmm.....標題我就覺得起的很變態。閑話不多說,先說出現的背景吧~~。 因為業務上的需求,跟一個硬體對接,要做大屏展示大廳客流熱力圖分佈(背景圖是客戶那邊給的)。然後這個機子傳過來的數據就可能20來條。如果用最新的echarts4來做,但是數據太小不足以畫出圖來,但是如果數據太大傳輸也是一 ...
  • "官方文檔" 前言 所謂視頻上傳,是指開發者或其用戶將視頻文件上傳到點播的視頻存儲中,以便進行視頻處理、分發等。 一、簡介 騰訊雲點播支持如下幾種視頻上傳方式: 1. 控制臺上傳:在點播控制臺上進行操作,將本地視頻上傳到雲點播,適用於直接管理少量視頻的場景,具有方便快捷、無技術門檻的優點; 2. 服 ...
  • 數組方法: 1、Array.join([param]) 方法:將數組中所有的元素都轉換為字元串並連接起來,通過字元 param 連接,預設使用逗號,返回最後生成的字元串 2、Array.reverse() 方法:將數組中的元素顛倒順序(在原數組中重新排列它們),返回逆序數組 3、Array.sort ...
  • 一、HTML5簡介 HTML 5 的第一份正式草案已於2008年1月22日公佈。HTML5 仍處於完善之中。然而,大部分現代瀏覽器已經具備了某些 HTML5 支持。 2014年10月29日,萬維網聯盟宣佈,經過幾乎8年的艱辛努力,HTML5標準規範終於最終制定完成了,並已公開發佈。 HTML5不僅僅 ...
  • 一. 提前準備工作 1.Node.js環境 2.Windows10 3.npm(前端包管理工具) 4.webpack(前端資源載入/打包工具) 二. 開始安裝 1.。下載並安裝Node.js 下載地址:https://nodejs.org/en/download/ 2.在cmd中查看node.js是 ...
  • 基本實現: 解析GET參數: 解析POST: ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...