HTML5实现经典Windows扫雷游戏
上周末突然想嘗試著做一個掃雷游戲。掃雷游戲我是很喜歡玩的,更年輕時候,晚上晚上幾點鐘的時候都有。。。
雖然之前沒有寫過HTML5游戲,不過我感覺肯定能寫出來的。雖然對于寫H5游戲有哪些步驟什么的都不是很明了。
另外一點,寫這個游戲,所有的算法都必須是自己思考出來,不能在寫之前去參考別人的思路。?
因為一旦參考了,就會受到別人思路左右,永遠沒有機會從無到有地去思考這個自己喜歡過的游戲了。
然后上周末完成了基本雛形,上周閑的時候又斷斷續續地完善。一個功能一個功能地實現。 中間還抽空做了一個貪吃蛇。 相比掃雷而言,貪吃蛇的邏輯就相當簡單了。
先看幾個過程中的版本:
完成版本,已經像模像樣了呢!用了網上下的圖片掃雷資源,數字,旗子之類的。
實現的功能,按完成步驟。
1.根據格子數量,初始化canvas畫布。繪制格子。 初始化所需要的數組。包含格子信息的格子數組。
2.鼠標劃過每一個格子改變格子。 需要判斷鼠標在畫布上的坐標。然后根據畫布坐標判斷格子。
3.隨機生成雷。 ?do while循環,生成不重復的格子坐標保存到地雷數組和格子數組。
4.點擊打開雷。顯示周圍雷的數量。如果雷的數量為0。則用一個遞歸計算這個雷周圍8個格子里有沒有周邊雷數量為0的格子,如果有,再計算這個格子周圍。。。直到把相連的所有周邊雷數量為0的格子找出來,放入一個數組。然后再把這個數組里所有格子以及它們周圍的8個格子顯示出來,顯示每個格子周圍雷的數量 。雷的數量用不同顏色。
不過我感覺這個算法效率還不是很高。要優化。
5.被打開過的格子或被標記過的格子,沒有hover事件。
6.標記格子。用旗子或問號。 屏蔽網頁原本的右鍵事件。
7.加上時間,以及雷的數量的標記。以及點擊的時候才生成雷。避免第一次點擊 就點到雷。
8.雙鍵同擊事件。如果周邊雷的數量等于周邊標記的數量,就把周邊沒有打開沒有標記的點開。不等于就動態展現周邊剩下哪幾個沒打開的。
9.點中的雷以記錯誤的標記用不同的圖像表達出來。
10.用網上下的資源美化。增加級別選擇。高級,中級,初級,以及自定義。優化界面效果。
部分代碼:
var Mine = function (ele,panewidth,paneheight,minenum,tagele,timeele) {this.PANE_SIZE = 16;//每個格子的像素px大小。this.paneheight = paneheight;//有幾行this.panewidth = panewidth;//有幾列this.minenum = minenum;//有幾個雷this.ele = document.getElementById(ele);this.cxt = this.ele.getContext("2d");this.tagele = tagele;this.timeele = timeele; }init:function(){//畫格子this.ele.width = this.PANE_SIZE * this.panewidth;this.ele.height = this.PANE_SIZE * this.paneheight;this.oldPos = [0,0];//鼠標上一個停留的位置。默認值。用于處理hover事件。this.cellArr=[];//格子信息保存數組。保存每個格子是不是雷,當前是否有標記。this.mineArr=[];//地雷位置數組。this.time = 0;//操作時間this.notTaged = this.minenum;//未標記數量this.numToImage(this.notTaged,this.tagele);//將標記數字轉成圖片this.numToImage(this.time,this.timeele);//將時間數字轉成圖片this.mousedownArr='';//鼠標點下事件,是為了雙鍵同擊事件。this.createCells();//初始化cellArr數組,并涂上顏色。this.inited = false;//是否初始化過。clearInterval(this.timer);//時間跳動//綁定事件this.onmousemove();//鼠標在上面移動,觸發每個格子的this.onmouseout();//鼠標移出canvas的事件。this.onmousedown();//鼠標點下事件,是為了雙鍵同擊事件。this.onclick();//點擊方格事件this.preRightMenu();//阻止右鍵菜單。}
createMines:function(pos){ //生成雷的位置。保存到一個數組[[2,3],[4,6]]; var minenum = this.minenum;var mineArr = this.mineArr;var mineItem='';var cellArr = this.cellArr;for (var i = 0; i < minenum; i++) {//如果生成的重復了就重新生成。do{mineItem = [getRandom(this.panewidth),getRandom(this.paneheight)];}while(in_array(mineItem,mineArr)||pos.toString()== mineItem.toString());cellArr[mineItem[0]][mineItem[1]].isMine = true;mineArr.push(mineItem);};}
getCellArea:function(pos){//根據格子坐標返回一個格子左上角的像素坐標[32,666]; return [(pos[0]-1)*this.PANE_SIZE+1,(pos[1]-1)*this.PANE_SIZE+1];},getCellPos:function(coordinate){//根據像素坐標返回格子坐標。[3,5]; return [Math.ceil(coordinate.x/this.PANE_SIZE),Math.ceil(coordinate.y/this.PANE_SIZE)];}
drawCell:function(pos,type){//繪制不同種類的格子。var area = this.getCellArea(pos);var cxt = this.cxt;var image = new Image();var src;var srcArr = ["res/blank.bmp","res/0.bmp","res/flag.bmp","res/ask.bmp","res/mine.bmp","res/blood.bmp","res/error.bmp"];//1正常格 2mouseover格子 3旗子格 4問號格 5正常雷格 6點中雷格 7.錯誤標記var index = type -1;image.src =srcArr[index];image.onload = function(){cxt.drawImage(image,area[0],area[1],16,16);}},drawNum:function(pos,num){//繪制數字var area = this.getCellArea(pos);var cxt = this.cxt;var image = new Image();image.src = "res/"+num+".bmp";image.onload = function(){cxt.drawImage(image,area[0],area[1],16,16);}}
calZeroMine:function(pos,zeroArr){//使用遞歸求出周圍所有的全為0的區域。算法效率還不是很高。var cellArr = this.cellArr;// var aroundArr = [[pos[0]-1,pos[1]],[pos[0],pos[1]-1],[pos[0],pos[1]+1], [pos[0]+1,pos[1]]];//只保留上下左右 好像還是會有一點問題。var aroundArr = [[pos[0]-1,pos[1]-1],[pos[0]-1,pos[1]],[pos[0]-1,pos[1]+1],[pos[0],pos[1]-1],[pos[0],pos[1]+1],[pos[0]+1,pos[1]-1],[pos[0]+1,pos[1]],[pos[0]+1,pos[1]+1]];var aroundMineNum = 0;for (var i = 0; i < aroundArr.length; i++) {aroundMineNum = this.calAround(aroundArr[i]);//附近雷的數量if(aroundMineNum == 0 && this.checkCell(aroundArr[i]) && cellArr[aroundArr[i][0]][aroundArr[i][1]].isMine == false &&!in_array(aroundArr[i],zeroArr)){zeroArr.push(aroundArr[i]);this.calZeroMine(aroundArr[i],zeroArr);//調用自己,遞歸。}};return zeroArr;}
var mine1 = new Mine("mine1",30,16,99,"game-tag-images","game-time-images");mine1.init();
演示地址:http://runningls.com/demos/2016/mine/mine.html
github:https://github.com/liusaint/games/tree/master/mine
歡迎留言討論。
轉載注明出處:http://blog.csdn.net/liusaint1992/article/details/50531186
總結
以上是生活随笔為你收集整理的HTML5实现经典Windows扫雷游戏的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: sta计算机控制局麻,关于申请新增计算机
- 下一篇: js中 计算合同到期时间等