原生JS小游戲:從0實(shí)現(xiàn)一個(gè)掃雷游戲x_第1頁
原生JS小游戲:從0實(shí)現(xiàn)一個(gè)掃雷游戲x_第2頁
原生JS小游戲:從0實(shí)現(xiàn)一個(gè)掃雷游戲x_第3頁
原生JS小游戲:從0實(shí)現(xiàn)一個(gè)掃雷游戲x_第4頁
已閱讀5頁,還剩6頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、原生js小游戲:從0實(shí)現(xiàn)一個(gè)掃雷游戲x 原生 js 小游戲:從 0 實(shí)現(xiàn)一個(gè)掃雷游戲 這兩天閑著無事,寫了幾個(gè) web 游戲供自己打發(fā)時(shí)間。其中筆者感覺掃雷這個(gè)游戲的實(shí)現(xiàn)中涉及到的知識(shí)點(diǎn)比較全面,故在此和大家分享一下。 先放效果圖: 首先我們要把基本的架子搭建起來: !doctype html html head meta charset=utf-8 title原生 js 實(shí)現(xiàn)掃雷小游戲/title style *margin:0;padding:0; .containerwidth:600px;height:600px;border:1px solid #ccc;margin:0 auto;

2、 .container .blockwidth:60px;height:60px;background:#abcdef;float:left;border:1px solid #f00;box-sizing:border-box; .container .block:activebackground:#eee; .container .lei /* 雷顯示 */ .container .showbackground:url("tim.jpg") no-repeat center center/ 100% 100%;cursor:pointer; /* 周圍有雷的話顯示數(shù)字

3、*/ .container .numberbackground:#fff;text-align:center;line-height:60px; /* 紅旗標(biāo)記顯示 */ .container .biaojibackground:url("qz.jpg") no-repeat center center/ 100% 100%;cursor:pointer; .ts0position:fixed;width:100%;height:100vh;top:0;left:0;z-index:888;background:rgba(255,255,255,0);display:non

4、e; .tsposition:fixed;width:200px;height:60px;background:rgb(255,255,255);top:0;right:0;left:0;bottom:0;margin:auto;z-index:999;display:none; .ts ptext-align:center;line-height:60px; /style /head body h4mxc-云風(fēng)清/h4 div class=container /div div class=ts0/div div class=ts p游戲結(jié)束!/p /div /body script /scr

5、ipt /html 這并沒有什么好說的 事實(shí)上,它非常簡單: 一個(gè)小標(biāo)題( h4 )、一個(gè)"游戲區(qū)域'( class=container )、一個(gè)結(jié)束時(shí)的提示框( class=ts )、以及襯托提示框的蒙層( class=ts0 )。 但你會(huì)發(fā)現(xiàn),所謂"游戲區(qū)域'僅僅是一個(gè)擁有一個(gè) div 的"空架子'? 這里筆者采用了 js 動(dòng)態(tài)渲染 div 元素(一個(gè)一個(gè)小方塊),因?yàn)楹竺?quot;劇情'的需要,我們要將每個(gè)小方塊都設(shè)置【專屬 id】(id 名): let container=document.queryselector(&q

6、uot;.container"); for(let i=0;i10;i+) for(let j=0;j10;j+) let divobj=document.createelement("div"); divobj.classlist.add("block"); divobj.id="a"+i+"_"+j; /設(shè)置專屬 id(id 名) container.appendchild(divobj); 我們很快便完成了這一代碼。這樣真的好嗎? 現(xiàn)在只是 10x10,如果是 100x100呢?在大數(shù)據(jù)量循環(huán)中執(zhí)行

7、 appendchild 可不是一個(gè)明智的決定! 在筆者關(guān)于 js 性能優(yōu)化的文章中提到過一種解決方案:createdocumentfragment() : let container=document.queryselector(".container"); let fragment=document.createdocumentfragment(); for(let i=0;i10;i+) for(let j=0;j10;j+) let divobj=document.createelement("div"); divobj.classlist.ad

8、d("block"); divobj.id="a"+i+"_"+j; /設(shè)置專屬 id(id 名) fragment.appendchild(divobj); container.appendchild(fragment); 其實(shí),原生中對(duì)元素的很多樣式上的操作從性能上考慮最終都可歸結(jié)到對(duì) classname 的操作。 現(xiàn)在,我們畫面上有了下面的樣式: 該進(jìn)行下一步了。 不過在此之前,我們需要找兩張圖片: (我們不必關(guān)注他們的大小 在 css 中改變即可) 做完上面的準(zhǔn)備工作,正餐便開始了: 雷的分布:隨機(jī),且 上面筆者說: 原生中對(duì)

9、元素的很多樣式上的操作從性能上考慮最終都可歸結(jié)到對(duì)classname 的操作 的操作,于是我們可以想到:為每個(gè)需要變成"雷'的小方塊添加一個(gè)【特別的類】(.lei): 筆者采用循環(huán)實(shí)現(xiàn): let count=13; let block=document.queryselectorall(".block"); do let random=math.floor(math.random()*block.length); blockrandom.classlist.add("lei"); while(document.queryselector

10、all(".lei").length=count); 看!這就體現(xiàn)出了 do-while 循環(huán)的好處了。 然后是處理鼠標(biāo)事件:這將是最后一步了。 筆者發(fā)現(xiàn)身邊不少學(xué)前端的同學(xué)在做事件處理時(shí)直接上去就是 onclick、oninput、onmouse 小一點(diǎn)的文件還好說,稍微對(duì)性能很高的網(wǎng)頁或者說本游戲設(shè)置為10000x10000 之后,瀏覽器就"吃不消'了 因?yàn)樵诔跏紩r(shí)對(duì)函數(shù)的加載太過龐大! 函數(shù)的優(yōu)化 函數(shù)的優(yōu)化:我們?yōu)槭裁床荒茏裱径栊约虞d模式】,在觸發(fā)時(shí)再去加載函數(shù)呢? /block 是前面獲取過的變量獲取的".block',指&q

11、uot;.container'中的每個(gè)小方塊 block.foreach(function(item) item.onclick=function() /鼠標(biāo)左鍵事件 leftclick(item); item.oncontextmenu=function(e) /鼠標(biāo)右鍵事件 /阻止瀏覽器默認(rèn)鼠標(biāo)右鍵事件 e.preventdefault(); rightclick(item); ) xxx.oncontextmenu 鼠標(biāo)右鍵事件注意一下:平時(shí)說的像禁止鼠標(biāo)右鍵、禁止復(fù)制粘貼(其中的一種)、f12 彈出控制臺(tái)都和這個(gè)有關(guān) 然后便是兩個(gè)函數(shù)了: 鼠標(biāo)左鍵的對(duì)應(yīng)函數(shù)到?jīng)]什么判斷點(diǎn)擊處是

12、不是雷(有沒有.lei 這個(gè)類)、如果不是,循環(huán)判斷點(diǎn)擊處周圍 8 個(gè)小方塊中有幾個(gè)雷并顯示出來: function leftclick(obj) if(obj.classlist.contains("biaoji") return ; if(obj.classlist.contains("lei") let lei=document.queryselectorall(".lei"); lei.foreach(function(item) item.classlist.add("show"); ) /結(jié)束時(shí)提示框及

13、蒙層顯示 document.queryselector(".ts0").style.display="block" document.queryselector(".ts").style.display="block" settimeout(function()let yes=prompt(是否刷新刷新進(jìn)入下一關(guān)?);if(yes = 是)window.location.reload(),1700); else obj.classlist.add("number"); let ids=obj.i

14、d; /下面三行作用是將【專屬 id】(id 名)拆分開來,以確定位置坐標(biāo) let arr=ids.split("_"); let x=number(arr0.substr(1); let y=number(arr1); let num=0; for(let i=x-1;i=x+1;i+) for(let j=y-1;j=y+1;j+) let objs=document.queryselector("#a"+i+"_"+j); /這里也可以用"es6 模板字符串':let objs=document.queryse

15、lector(#a$i_$j); if(objs objs.classlist.contains("lei") num+; if(num) obj.innerhtml=num; if(num=0) for(let i=x-1;i=x+1;i+) for(let j=y-1;j=y+1;j+) let objs=document.queryselector("#a"+i+"_"+j); if(objs !objs.classlist.contains("number") leftclick(objs); 倒是鼠標(biāo)右鍵

16、:它是插紅旗的 這里涉及到一個(gè)問題:插紅旗和掃到雷不一樣,你還可以取消。這問題說大不大,但也是個(gè)性能問題。 筆者查閱資料找到了一個(gè)函數(shù): toggle() 單次點(diǎn)擊時(shí)操作一個(gè)函數(shù),偶次點(diǎn)擊時(shí)執(zhí)行另一個(gè)函數(shù)(也可以在里面放一個(gè)類名,即單次點(diǎn)擊時(shí)添加類名,偶次點(diǎn)擊時(shí)取消類名): function rightclick(obj) if(!obj.classlist.contains("number") obj.classlist.toggle("biaoji"); let biaoji=document.queryselectorall(".biaoji.lei"); let biaoji2=document.queryselectoral

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論