遊戲試玩git
前言github
這個小遊戲主要思路是canvas與數組的映射,每個小網格對應二維數組的一個元素,利用數組來存儲網格的信息,如 某網格是否有雷,周圍九宮格雷的個數,是否已經被打開canvas
這裏定義了三個數組數組
let gridStatus_arr = []; //存儲格子身份狀態,狀態1爲雷
let mineNum_arr = []; //存儲格子周圍八個格子雷的數量
let click_arr = []; //存儲格子點擊狀態,點擊過的爲1
複製代碼
先添加三個難度的按鈕dom
<button class="type" data-row="9" data-col="9" data-mine="10">簡單</button>
<button class="type" data-row="14" data-col="14" data-mine="36">中級</button>
<button class="type" data-row="14" data-col="22" data-mine="56">高級</button>
複製代碼
點擊相應按鈕經過 js 獲取對應的 data 屬性, 而後動態的生成相應的方格, 而後動態計算包裹全部小方格的寬度和高度佈局
而後建立一個canvas元素this
<canvas id="canvas"></canvas>
複製代碼
canvas畫布的大小屬性width和height先不設置,後面經過js動態設置spa
點擊難度按鈕,動態初始化畫布code
//獲取canvas元素
context = $("#canvas")[0].getContext("2d");
$(".type").click(function(){
row = $(this).data('row');
col = $(this).data('col');
mine = $(this).data('mine');
init(mine);
})
//初始化
function init(mine){
createGrid(); //建立網格
createMine(mine); //隨機生成雷
countArountMine(); //計算每一個格子周圍八個格子雷的數量
createClickEvent(); //添加點擊事件
}
複製代碼
3.canvas建立網格對象
利用canvas畫網格,先畫一個相應大小的矩形,而後在矩形內畫線造成網格
function createGrid(){
//計算畫布寬高
let width = GAID_WIDTH*col;
let height = GAID_HEIGHT*row;
//設置畫布寬高
canvas.setAttribute("width",width)
canvas.setAttribute("height",height)
//描繪邊框
context.beginPath();
context.linewidth = 1;
context.rect(0,0,width,height);
context.stroke();
context.fillStyle = '#909090';
context.fill();
//準備畫橫線
for(let row_i = 1; row_i<row; row_i++){
var y = row_i*GAID_HEIGHT;
context.strokeStyle = 'white';
context.moveTo(0,y);
context.lineTo(width,y);
}
//準備畫豎線
for(let col_i = 1; col_i<col; col_i++){
var x = col_i*GAID_WIDTH;
context.strokeStyle = 'white';
context.moveTo(x,0);
context.lineTo(x,height);
}
//完成描繪
context.stroke();
}
複製代碼
添加雷,改變格子身份狀態 ,1表明雷區
這裏是利用二維數組和網格的映射來實現的
function createMine(mine){
$('#mine').text(mine);
//將數組變爲二維
for(let i=0; i<row; i++){
gridStatus_arr[i] = [];
mineNum_arr[i] = [];
click_arr[i] = [];
}
//初始化二維數組
for(let i=0; i<row; i++){
for(let j=0; j<col; j++){
gridStatus_arr[i][j] = 0;
mineNum_arr[i][j] = 0;
click_arr[i][j] = 0;
}
}
//添加雷,改變格子身份狀態
while(mine!=0){
let mine_row = Math.floor(Math.random() * row);
let mine_col = Math.floor(Math.random() * col);
mine--;
//預防生成位置相同
if(gridStatus_arr[mine_row][mine_col] == 1){
mine++;
continue;
}
gridStatus_arr[mine_row][mine_col] = 1;
}
}
複製代碼
5.計算每一個格子周圍八個格子雷的數量
利用對象來取當前格子周圍九宮格的範圍,遍歷查看對應數組的身份狀態
function countArountMine(){
for(let i=0; i<row; i++){
for(let j=0; j<col; j++){
let around = aroundGrid(i,j);
let nx = around.nx,
sx = around.sx,
wy = around.wy,
ey = around.ey;
let mineNum = 0;
for(let x=nx; x<=sx; x++){
for(let y=wy; y<ey; y++){
if(gridStatus_arr[x][y]==1){
mineNum++;
}
}
}
mineNum_arr[i][j] = mineNum;
}
}
}
複製代碼
要先去掉默認的contextmenu事件,不然會和默認右鍵事件同時出現。
document.oncontextmenu = function (e) {
e.preventDefault();
};
複製代碼
再添加鼠標點擊事件,e.which = 1爲鼠標左鍵 ,e.which = 3爲鼠標右鍵
function createClickEvent(){
$("#canvas").off();
$("#canvas").mousedown(function(e){
//由於canvas的X,Y座標和數組的行列相反,這裏直接轉換了一下
let x = Math.floor(e.offsetY / GAID_HEIGHT);
let y = Math.floor(e.offsetX / GAID_WIDTH);
if(e.which == 1){
judgeGridStatus(x,y);
}else if(e.which == 3){
signMine(x,y);
}
})
}
複製代碼
對比身份狀態是否爲1 來判斷是否點擊到雷。
經過 已打開的格子個數 和 row*col - mine 對比判斷是否掃雷成功
這裏就不貼代碼了,詳細可參考個人GitHub倉庫
最後
在canvas的用法上可能有一些不規範,由於花的時間比較短, 可能裏面還存在一些問題,還請大佬們多多包涵,也歡迎大佬們來指正。本小白感激涕零。