摘要:初學,寫了一個掃雷程序練練手掃雷規則及功能掃雷想必大家都不陌生,就是上點擊排雷的小游戲,它的主要規則有左鍵點擊顯示當前格子是否為雷,如果為雷的話,啦,如果不是雷的話,這個格子會顯示周圍八個格子內的雷數量。
初學javascript,寫了一個掃雷程序練練手!
掃雷規則及功能掃雷想必大家都不陌生,就是windows上點擊排雷的小游戲,它的主要規則有
1.左鍵點擊顯示當前格子是否為雷,如果為雷的話,GameOver啦,如果不是雷的話,這個格子會顯示周圍八個格子內的雷數量。 2.鼠標右鍵標記,標記可能的雷,標記了之后取消需要再次右鍵點擊該格子,左鍵無效果。 3.鼠標中鍵(滾輪)按下后,快捷掃雷(如果周圍雷數和未被標記且未被翻開的格子相等,會將這些格子一并翻開) 主要功能基本完全復刻了windows7掃雷的功能
掃雷github地址:
掃雷github地址
1.首先我定義了一個構造函數,里面是一系列的屬性:
var mineCraft = function(num1,num2,mine_num,obj,type){ this.num1 = num1; //整個掃雷的行數 this.num2 = num2; //整個掃雷的列數 this.mine_num = mine_num; //雷的個數 this.tiles = []; //數組里面存放的是每個小格子 this.obj = obj; //掃雷放置的對象 this.flag = true; this.arr = []; this.arr_2 = []; this.time_dsq = null; this.time_dc =""; this.time_arr = [[],[],[]]; //時間統計信息 this.details = [[],[],[]]; // 游戲統計詳情 this.type = type; //游戲類型:初級/中級/高級/自定義 this.buildTiles(); //創建游戲函數 };
2.在頁面上創建掃雷的界面 函數buildTiles
buildTiles:function(){ this.obj.style.width = 51*this.num1+"px"; //在傳進來的對象上畫整體格子,每個小格子51px大小,總大小就為個數*單個大小 this.obj.style.height = 51*this.num2+"px"; var indexOfdiv = 0; for(var i = 0;i3.綁事件函數:
event : function(){ var _this = this; this.obj.onmouseover = function(e){ //鼠標懸停事件--- if(e.target.className == "tile"){ e.target.className = "tile current"; } } this.obj.onmouseout = function(e){ //鼠標移出事件-- if(e.target.className == "tile current"){ e.target.className = "tile"; } } this.obj.onmousedown = function(e){ //鼠標按下事件 var index = e.target.index; if(e.button == 1){ //e.button屬性 左鍵0/中鍵1/右鍵2 event.preventDefault(); //取消默認 } _this.changeStyle(e.button,e.target,index); } this.obj.onmouseup = function(e){ //鼠標彈起事件 if(e.button == 1){ _this.changeStyle(3,e.target); } } },4.點擊調用的函數:
changeStyle:function(num1,obj,num_index){ if(num1 == 0){ //是左鍵的話 if(this.flag){ //this.flag 是之前定義的用于判斷是否為第一次點擊 this.store(num_index); //store函數,存放被點擊的格子周圍的8個格子 this.setMineCraft(this.mine_num,this.arr,num_index); //如果是第一次點擊 即調用布雷函數 更改flag狀態 this.flag = false; this.detail_statistics(0,false); //開始信息統計函數 } if(obj.className != "tile"&&obj.className !="tile current"){//如果不是第一次點擊,被點擊的格子不是未點擊狀態,無效 return false; } if(obj.getAttribute("val") == 0){ //如果不是雷。改為翻開狀態 obj.className = "showed"; obj.innerHTML = obj.getAttribute("value") == 0?"":obj.getAttribute("value"); //顯示周圍雷數 this.showAll(obj.index); //遞歸函數判斷周圍格子的情況,就是掃雷游戲上一點開會出現一片的那種 } if(this.over(obj)){ //判斷游戲是否結束 this.last(); } } if(num1 == 2){ //右鍵標記事件 if(obj.className == "biaoji"){ obj.className = "tile"; }else if(obj.className !="biaoji"&&obj.className != "showed"){ obj.className = "biaoji"; } } if(num1 == 1){ // 中鍵事件 if(obj.className =="showed"){ this.show_zj1(obj.index); } } if(num1 == 3){ //鼠標彈起事件 if (obj.className == "showed") { var flag1 = this.show_zj2(obj.index,0); }else{ this.show_zj2(obj.index,1) return false; } if(flag1&&this.over()){ //彈起判斷是否結束 this.last(); } } },5.布雷:我之前的布雷是在頁面加載在buildTiles()的時候布雷的,但是這樣會導致有可能你電機的第一個格子就是雷(游戲性不強),后來修改到第一次點擊完成之后布雷(確保第一下點的不是雷),避開直接炸死的現象.所以把調用放在后面的event后觸發的changeStyle函數中
setMineCraft:function(num,arr_first,num_first){ //雷的個數、最開始被點擊的格子周圍的八個、被點擊的那個格子 var arr_index = []; for(var i = 0;i-1){//如果是屬于第一次點擊的周圍的直接跳過在該位置布雷 num++; continue; } if (this.tiles[index_Mine].getAttribute("val") == 0) { this.tiles[index_Mine].setAttribute("val", 1); }else { num++; } } this.showValue(); this.event() }, 6.存儲周圍格子的函數:
store : function(num) { //傳入格子的index. var tiles_2d = []; var indexs = 0; for(var i = 0;i= 0 && j - 1 >= 0) { this.arr.push(tiles_2d[i - 1][j - 1]); } //正上 if (i - 1 >= 0) { this.arr.push(tiles_2d[i - 1][j]); } //右上 if (i - 1 >= 0 && j + 1 <= this.num1-1) { this.arr.push(tiles_2d[i - 1][j + 1]); } //左邊 if (j - 1 >= 0) { this.arr.push(tiles_2d[i][j - 1]); } //右邊 if (j + 1 <= this.num1-1) { this.arr.push(tiles_2d[i][j + 1]); } //左下 if (i + 1 <= this.num2-1 && j - 1 >= 0) { this.arr.push(tiles_2d[i + 1][j - 1]); } //正下 if (i + 1 <= this.num2-1) { this.arr.push(tiles_2d[i + 1][j]); } //右下 if (i + 1 <= this.num2-1 && j + 1 <= this.num1-1) { this.arr.push(tiles_2d[i + 1][j + 1]); } }, 7.showAll函數:作用是如果該格子周圍沒有雷,自動翻開周圍8個格子,然后再判斷周圍八個格子的周圍8隔格子是否有雷,利用了遞歸的方法
showAll:function(num){ if (this.tiles[num].className == "showed" && this.tiles[num].getAttribute("value") == 0){ this.store(this.tiles[num].index); var arr2 = new Array(); arr2 = this.arr; for (var i = 0; i < arr2.length; i++) { if (arr2[i].className != "showed"&&arr2[i].className !="biaoji") { if (arr2[i].getAttribute("value") == 0) { arr2[i].className = "showed"; this.showAll(arr2[i].index); } else { arr2[i].className = "showed"; arr2[i].innerHTML = arr2[i].getAttribute("value"); } } } } },8.show_zj函數:主要是中鍵按鈕的作用中鍵點擊后的函數,這里的show_zj1是鼠標鍵按下后的顯示效果,
show_zj2函數就是show_zj1:function(num){ this.store(this.tiles[num].index); for (var i = 0; i < this.arr.length; i++) { if (this.arr[i].className == "tile") { this.arr_2.push(this.arr[i]); this.arr[i].className = "showed"; // this.arr[i].className = "test"; } } }, show_zj2:function(num,zt){ var count = 0; this.store(this.tiles[num].index); for(var i = 0,len = this.arr_2.length;i9.結束判斷:
over:function(obj){ var flag = false; var showed = document.getElementsByClassName("showed"); var num = this.tiles.length - this.mine_num; if(showed.length == num){ //如果被排出來的格子數等于總格子數-雷數,這游戲成功結束 this.detail_statistics(1,true); //游戲統計 ,true代表勝,false,代表失敗 alert("恭喜你獲得成功"); flag = true; }else if(obj&&obj.getAttribute("val") == 1){ //如果被點擊的是雷,則炸死 this.detail_statistics(1,false); alert("被炸死!"); flag = true; } return flag; },10.結束后的顯示函數:
last:function(){ var len = this.tiles.length; for(var i = 0;i11 統計信息:還是比較全的和windows7掃雷版的判斷項目是一樣的,使用的是每次結束游戲后將數據存入localStorage中,
//已玩游戲,已勝游戲,勝率,最多連勝,最多連敗,當前連局; detail_statistics:function(num,zt){ var time_pay = 1; var _this = this; if(num == 0){ this.time_dsq = setInterval(function(){ $("#time_need").text(time_pay); _this.time_dc =time_pay; time_pay++; },1000); } else if(num == 1){ clearInterval(this.time_dsq); if(this.type == 4){return false;} if(localStorage.details == undefined){ localStorage.details = JSON.stringify([[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0]]); //這里存放的就是上面注釋中的六項數據 } if(JSON.parse(localStorage.details) instanceof Array){ this.details = JSON.parse(localStorage.details); } this.details[this.type][0] += 1; if(zt == false){ if(this.details[this.type][5]>=0){ this.details[this.type][5] = -1; }else{ this.details[this.type][5] -= 1; } if(this.details[this.type][5]=0){ this.details[this.type][5] += 1; }else{ this.details[this.type][5] = 1; } if(this.details[this.type][5]>this.details[this.type][3]){ this.details[this.type][3] = this.details[this.type][5]; } this.details[this.type][3] += 1; this.details[this.type][2] = this.toPercent(this.details[this.type][4]/this.details[this.type][0]); localStorage.details = JSON.stringify(this.details); var time1 = new Date(); var time_str = time1.getFullYear()+"/"+time1.getMonth()+"/"+time1.getDate()+" "+time1.getHours()+":"+time1.getMinutes(); if(localStorage.time == undefined){ localStorage.time = JSON.stringify([[],[],[]]); } if(JSON.parse(localStorage.time) instanceof Array){ this.time_arr = JSON.parse(localStorage.time); } this.time_arr[this.type].push([this.time_dc,time_str]); this.time_arr[this.type].sort(function(a,b){ return a[0]-b[0]; }); if(this.time_arr[this.type].length>5){ this.time_arr[this.type].pop(); } localStorage.time = JSON.stringify(this.time_arr); } }, 掃雷的主要部分就是這些了,還有一些小功能包括沒寫來,要看完整的可以看gitHub
之前看書學習總覺得學了就忘,感覺懂了公式卻不知道怎么用,寫完掃雷小程序覺得收獲了很多
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/88664.html
摘要:寫在前面我們已經寫過了三子棋小游戲肯定沒玩過癮,我們再寫個掃雷小游戲吧目錄寫在前面認識游戲游戲規則游戲框架游戲實現效果展示全部代碼文件文件文件認識游戲相信大家對掃雷都不陌生每臺電腦必備的小游戲游戲規則就是在規定的時間將 ...
摘要:展示雷盤和初始化雷盤不一樣,展示雷盤只需要用即可,并不需要將都展示出來,只是為了我們更好的計算掃雷的位置周圍的雷的數量。 目錄 1、需求分析 2、程序架構 3、代碼實現(分函數呈現) (1)主函數代碼實現 分析: 異常處理: (2)游戲主函數實現 分析: (3)初始化函數的實現 分析: (4...
摘要:整個這個雷區面板都是由的和組成的,最后由的方法對其進行不可變化處理剩下的主要邏輯部分就是掃雷了,傳入掃雷游戲對象一個不可變結構做為第一個參數,以及要掃的那個雷區塊對象,最后返回新的掃雷游戲實例。 不可變性(Immutability)是函數式編程的核心原則,在面向對象編程里也有大量應用。在這篇文章里,我會給大家秀一下到底什么是不可變性(Immutability)、她為什么還這么屌、以及在...
閱讀 1143·2021-08-12 13:24
閱讀 2990·2019-08-30 14:16
閱讀 3315·2019-08-30 13:01
閱讀 2078·2019-08-30 11:03
閱讀 2779·2019-08-28 17:53
閱讀 3093·2019-08-26 13:50
閱讀 2273·2019-08-26 12:00
閱讀 956·2019-08-26 10:38