掃雷小游戲作為windows自帶的一個小游戲,受到很多人的喜愛,今天我們就來嘗試使用h5的canvas結合js來實現這個小游戲。
要寫游戲,首先要明確游戲的規則,掃雷游戲是一個用鼠標操作的游戲,通過點擊方塊,根據方塊的數字推算雷的位置,標記出所有的雷,打開所有的方塊,即游戲成功,若點錯雷的位置或標記雷錯誤,則游戲失敗。
具體的游戲操作如下
1.可以通過鼠標左鍵打開隱藏的方塊,打開后若不是雷,則會向四個方向擴展
2.可以通過鼠標右鍵點擊未打開的方塊來標記雷,第二次點擊取消標記
3.可以通過鼠標右鍵點擊已打開且有數字的方塊來檢查當前方塊四周的標記是否正確
接下來開始編寫代碼
首先寫好HTML的結構,這里我簡單地使用一個canvas標簽,其他內容的擴展在之后實現(游戲的規則,游戲的難度設置)
<!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> #canvas { display: block; margin: 0 auto; } </style></head> <body> <div id="play"> <canvas id="canvas"></canvas> </div> <script src="js/game.js"></script></body> </html>接下來我們來初始化一些內容。包括canvas畫布的寬高,游戲共有幾行幾列,幾個雷,每個格子的大小。
//獲取canvas畫布var canvas = document.getElementById('canvas');var context = canvas.getContext('2d');canvas.width = 480;canvas.height = 480; //定義各屬性let R = 3; //格子圓角半徑let L = 15; //每個格子實際長let P = 16; //每個格子占長let row = 30; //行數let col = 30; //列數let N = 50; //雷數為了后面的操作,我要用幾個數組來儲存一些位置,一個方塊是否為雷的數組,該數組用于描繪出整個畫面每個方塊對應的內容;一個數組用于描述方塊狀態,即是否打開或者被標記;一個數組用來記載生成的雷的位置;一個數組用來記載標記的位置。
var wholeArr = drawInitialize(row, col, N, R, L, P);var gameArr = wholeArr[0] //位置數組var bombArr = wholeArr[1] //雷的位置數組var statusArr = zoneInitialize(row, col); //狀態數組 0為未打開且未標記 1為打開 2為標記var signArr = []; //標記數組 //畫出初始界面function drawInitialize(row, col, n, R, L, P) { let arr = initialize(row, col, n); for (let r = 0; r < row; r++) { for (let c = 0; c < col; c++) { drawRct(r * P, c * P, L, R, 'rgb(102,102,102)', context);//該方法用于繪制整個畫面,下面會寫出聲明 } } return arr;} //初始化function initialize(row, col, n) { let gameArr = zoneInitialize(row, col); //生成沒有標記雷的矩陣 let bomb = bombProduce(n, gameArr, row, col); gameArr = signArrNum(bomb[0], bomb[1], n, row, col); return [gameArr, bomb[1]];} //界面矩陣初始化function zoneInitialize(row, col) { //生成row行col列的矩陣 let cArr = new Array(col); let rArr = new Array(row); cArr = cArr.fill(0); //將行的每個位置用0填充 for (let i = 0; i < row; i++) rArr[i] = [...cArr]; return rArr;} //隨機生成雷function bombProduce(n, arr, row, col) { //隨機生成n個雷 let count = 0; let bombArr = []; while (true) { if (count === n) break; let r = Math.floor(Math.random() * row); let c = Math.floor(Math.random() * col); if (arr[c][r] === 0) { arr[c][r] = -1; bombArr[count] = strProduce(c, r); count++; } } return [arr, bombArr];} //標記數字function signArrNum(gArr, bArr, n, row, col) { for (let i = 0; i < n; i++) { //為每個雷的四周的非雷的數字標記加一 let r = parseInt(analyseStr(bArr[i]).row); let c = parseInt(analyseStr(bArr[i]).col); if (r > 0 && gArr[c][r - 1] != -1)//判斷該位置是否為雷,是則不進行操作 gArr[c][r - 1]++; if (r < row - 1 && gArr[c][r + 1] !== -1) gArr[c][r + 1]++; if (c > 0 && gArr[c - 1][r] !== -1) gArr[c - 1][r]++; if (c < col - 1 && gArr[c + 1][r] !== -1) gArr[c + 1][r]++; if (r > 0 && c > 0 && gArr[c - 1][r - 1] != -1) gArr[c - 1][r - 1]++; if (r < row - 1 && c < col - 1 && gArr[c + 1][r + 1] != -1) gArr[c + 1][r + 1]++; if (r > 0 && c < col - 1 && gArr[c + 1][r - 1] != -1) gArr[c + 1][r - 1]++; if (r < row - 1 && c > 0 && gArr[c - 1][r + 1] != -1) gArr[c - 1][r + 1]++; } return gArr;} //生成字符串function strProduce(r, c) { return `row:${c}|col:${r}`;} //解析雷數組字符串function analyseStr(str) { str = str.split('|'); str[0] = str[0].split(':'); str[1] = str[1].split(':'); return { row: str[0][1], col: str[1][1] };}
新聞熱點
疑難解答
圖片精選