日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > HTML >内容正文

HTML

HTML5实现经典Windows扫雷游戏

發布時間:2024/3/26 HTML 60 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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)];}


//獲取坐標: function?getEventPosition(ev){???var?x,?y;???if?(ev.layerX?||?ev.layerX?==?0)?{???x?=?ev.layerX;???y?=?ev.layerY;???}else?if?(ev.offsetX?||?ev.offsetX?==?0)?{?//?Opera???x?=?ev.offsetX;???y?=?ev.offsetY;???}???return?{x:?x,?y:?y};??? }
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扫雷游戏的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。