javascript實(shí)現(xiàn)數(shù)字配對(duì)游戲的實(shí)例講解
游戲效果如下圖所示:
規(guī)則:
在4X5的格子中,有隨機(jī)的互不相等的10個(gè)數(shù),每個(gè)數(shù)據(jù)有兩份(也就是20個(gè)數(shù),有兩兩相等的十對(duì)),隨機(jī)分布在20個(gè)格子中。游戲開(kāi)始,彈出二十個(gè)數(shù)的序列。每次點(diǎn)擊格子會(huì)顯示當(dāng)前格子中的數(shù)據(jù)并暫時(shí)保留顯示,直到下一次點(diǎn)擊,如果下一次點(diǎn)擊顯示的數(shù)據(jù)與保留的數(shù)據(jù)不同,則之前點(diǎn)擊保留的數(shù)據(jù)會(huì)消失(仍然存在于該格子但不顯示)。如果連續(xù)點(diǎn)擊顯示的兩個(gè)數(shù)據(jù)一樣,則兩個(gè)數(shù)據(jù)都會(huì)顯示并且不會(huì)再消失。
直到所有數(shù)據(jù)都通過(guò)連續(xù)點(diǎn)擊相同數(shù)據(jù)的方式顯示出來(lái),就算游戲結(jié)束,報(bào)出游戲用時(shí)。此時(shí)可以點(diǎn)擊開(kāi)始游戲或刷新來(lái)繼續(xù)。
分析:
1:二十個(gè)格子對(duì)應(yīng)二十個(gè)數(shù)據(jù),產(chǎn)生兩組相等的十個(gè)隨機(jī)數(shù)并放入數(shù)組,數(shù)組下標(biāo)決定顯示位置。
2:每個(gè)格子的狀態(tài)的三種:數(shù)據(jù)隱藏,暫時(shí)保留數(shù)據(jù)和永久顯示。數(shù)據(jù)隱藏的格子通過(guò)點(diǎn)擊的下一次狀態(tài)是暫時(shí)保留。暫時(shí)保留數(shù)據(jù)的格子通過(guò)點(diǎn)擊下一次狀態(tài)是永久顯示或數(shù)據(jù)隱藏,這里要根據(jù)連續(xù)兩次獲取的數(shù)據(jù)是否相等來(lái)判斷。永久顯示之后狀態(tài)已經(jīng)不可變,只能永久顯示出來(lái),此時(shí)對(duì)點(diǎn)擊是無(wú)效的。
3 :計(jì)時(shí)從點(diǎn)擊開(kāi)始按鈕之后,點(diǎn)擊第一個(gè)格子時(shí)開(kāi)始。直到游戲完成或點(diǎn)擊刷新重開(kāi),期間計(jì)時(shí)器不能停止。
4 :得出,這里需要一個(gè)布爾值,記錄游戲是否已經(jīng)開(kāi)始,已經(jīng)開(kāi)始的游戲?qū)﹂_(kāi)始按鈕應(yīng)該拒絕,計(jì)時(shí)器運(yùn)行直到游戲完成。游戲完成時(shí),改變布爾值,計(jì)時(shí)器停止工作,顯示游戲用時(shí),開(kāi)始按鈕可用。
實(shí)現(xiàn):
表格通過(guò)script創(chuàng)建,其中的元素先默認(rèn)顯示為“”空字符串。通過(guò)對(duì)應(yīng)的點(diǎn)擊來(lái)顯示。CSS樣式可自行設(shè)定。
<table border:1> <script> var rowlength = 4; var collength = 5; var str = ''; for (var i = 0; i < rowlength; i++) { str += '<tr>' for (var j = 0; j < collength; j++) { //這里將每個(gè)td的id拼接為imgxx xx為元素索引 var index = i * collength + j; var id = "img" + index; //注意這里字符串 每個(gè)''是一個(gè)字符串進(jìn)行輸出 str += '<td id="' + id + '" onclick="showImg(' + index + ')">'; str += '</td>'; } str += '</tr>' } document.write(str); </script> </table>
NEW_START記錄是否可以開(kāi)始游戲的變量
times記錄已用時(shí)間
trans記錄每個(gè)格子的翻轉(zhuǎn)狀態(tài) ,數(shù)組每個(gè)格子有三種狀態(tài) 0:隱藏-1:顯示(仍可翻轉(zhuǎn))-2:顯示(不可翻轉(zhuǎn))。也就是數(shù)組的每個(gè)元素只有三個(gè)可能的值0,1,2)
numArr三十個(gè)數(shù)的隨機(jī)序列數(shù)組
var NEW_START = true; var times = 0; var trans = []; var numArr = [];
通過(guò)ID獲取到元素的方法:
function $(id) { return document.getElementById(id); }
下面通過(guò)函數(shù)獲取到二十個(gè)隨機(jī)數(shù),兩兩相等的十組(可參見(jiàn):生成指定范圍隨機(jī)數(shù))
function getNum() { var index = 0; var arrLength = rowlength * collength / 2; var arr = new Array(); while (index < arrLength) { var flag = true; var num = parseInt(Math.random() * 100); for (var i in arr) { if (arr[i] == num || arr[i] < 1) { flag = false; } } if (flag == true) { arr[index] = num; index++; } } //alert(arr.length); //arr是十個(gè)互不相等的隨機(jī)數(shù) // newArr數(shù)組就是每個(gè)隨機(jī)數(shù)都有兩個(gè)的數(shù)組 var newArr = new Array(); for (var i = 0; i < arrLength; i++) { newArr[i] = arr[i]; newArr[arrLength + i] = arr[i]; } return newArr; }
創(chuàng)建表格,生成隨機(jī)數(shù)數(shù)組這些都是準(zhǔn)備工作。
下面是具體的邏輯:
開(kāi)始游戲的點(diǎn)擊函數(shù)
<input type="button" id="startButton" value="開(kāi)始游戲" onclick="init()">
點(diǎn)擊開(kāi)始游戲,需要初始化游戲相關(guān)的參數(shù),注意如果已經(jīng)開(kāi)始,就需要拒絕處理。將數(shù)組元素用排序函數(shù)打亂做到隨機(jī)性。
function init() { //如果已經(jīng)開(kāi)始 拒絕點(diǎn)擊 if (NEW_START == false) { return; } //結(jié)束時(shí)用于顯示時(shí)間的h4標(biāo)簽 $('end').innerHTML = ''; var count = rowlength * collength; //將每個(gè)格子的數(shù)據(jù)隱藏 初始化每個(gè)格子的翻轉(zhuǎn)狀態(tài) for (var i = 0; i < count; i++) { $('img' + i).innerHTML = ''; trans[i] = 0; } //將游戲用時(shí)置為0 times = 0; $('gametime').innerHTML = times + '秒'; //獲取隨機(jī)的三十個(gè)數(shù)的隨機(jī)序列數(shù)組 注意排序函數(shù)的使用 numArr = getNum().sort(function () { return Math.random() - 0.5; }); alert("已生成隨機(jī)數(shù),按表格順序排列:" + numArr); }
計(jì)時(shí)函數(shù)
在點(diǎn)擊第一個(gè)格子時(shí),就需要開(kāi)始計(jì)時(shí)。NEW_START=false表示已經(jīng)開(kāi)始,需要確保只在游戲進(jìn)行中時(shí)才計(jì)時(shí)。每秒調(diào)用自身一次,并通過(guò)innerHTML把所用時(shí)間實(shí)時(shí)顯示出來(lái)。
用時(shí):<span id="gametime">0秒</span> function countTime() { if (NEW_START == false) { setTimeout('countTime()', 1000); $('gametime').innerHTML = times + "秒"; times++; } }
每個(gè)格子的點(diǎn)擊函數(shù)(超重點(diǎn))
在未開(kāi)始時(shí)拒絕點(diǎn)擊格子的(沒(méi)有效果)。進(jìn)入游戲點(diǎn)擊第一個(gè)格子,游戲開(kāi)始,狀態(tài)改變,NEW_START=false表示已經(jīng)開(kāi)始不可創(chuàng)建新游戲。計(jì)時(shí)開(kāi)始。
后面的點(diǎn)擊事件就需要判斷點(diǎn)擊的格子來(lái)處理不同的邏輯:
點(diǎn)擊已永久顯示的元素,不處理return。
點(diǎn)擊剛顯示但不是永久顯示的元素,也不處理return。
(注意這里判斷是不是同一元素是直接通過(guò)狀態(tài)值在trans中將索引index查找出來(lái)后對(duì)比)
點(diǎn)擊未顯示元素,獲取值,與前一個(gè)顯示的元素對(duì)比:
相等,都將trans中對(duì)應(yīng)索引的狀態(tài)值改為2,表示永久顯示
不等,新點(diǎn)擊元素在trans中對(duì)應(yīng)索引狀態(tài)值改為1(暫時(shí)保留),前一個(gè)點(diǎn)擊的元素索引值為0(需要隱藏)。
設(shè)置完?duì)顟B(tài)值,就立馬需要更新顯示(refreshUI函數(shù))。更新顯示時(shí)根據(jù)記錄狀態(tài)值的數(shù)組trans來(lái)操作的。
function showImg(index) { //未點(diǎn)擊開(kāi)始,還未初始化,退出 if (numArr[0] == undefined) { return; } //初次點(diǎn)擊進(jìn)入,開(kāi)啟計(jì)時(shí) if (NEW_START) { NEW_START = false; countTime(); } //1-點(diǎn)擊已經(jīng)徹底顯示的元素 退出 if (trans[index] == 2) { return; } //將點(diǎn)擊的格子的元素顯示出來(lái),并改變翻轉(zhuǎn)狀態(tài) //alert(index); //alert(numArr) var clickEle = $('img' + index); clickEle.innerHTML = numArr[index]; //已點(diǎn)擊元素的index var transIndex; for (var i in trans) { if (trans[i] == 1) { transIndex = i; } } //2-如果點(diǎn)擊的是剛剛已顯示元素 if (transIndex == index) { trans[index] = 1; return; } //3-點(diǎn)擊新元素 與先前顯示元素對(duì)比 兩種情況-相等 不等 else { if (numArr[transIndex] == numArr[index]) { trans[transIndex] = 2; trans[index] = 2; } else { trans[transIndex] = 0; trans[index] = 1; } } refreshUI(); }
根據(jù)狀態(tài)值設(shè)置顯示的函數(shù)refreshUI
根據(jù)trans中每個(gè)元素的值,改變對(duì)應(yīng)索引的格子的值。注意,如果格子的數(shù)據(jù)永久顯示,需要記錄已經(jīng)永久顯示的格子的數(shù)量,當(dāng)?shù)扔谒懈褡訑?shù)量時(shí),表示已經(jīng)全部顯示。需要判定游戲結(jié)束,顯示出游戲用時(shí)。
function refreshUI() { //此處用fore循環(huán)會(huì)最后存在一個(gè)undefined //count記錄已經(jīng)被徹底顯示的個(gè)數(shù) var count = 0; for (var i = 0; i < trans.length; i++) { if (trans[i] == 0) { $('img' + i).innerHTML = ''; } if (trans[i] == 1) { $('img' + i).innerHTML = numArr[i]; } if (trans[i] == 2) { $('img' + i).innerHTML = numArr[i] count++; } } if (count == collength * rowlength) { NEW_START = true; var endTime = times; $('end').innerHTML = '用時(shí)' + endTime + '秒??!游戲結(jié)束,點(diǎn)擊開(kāi)始游戲繼續(xù)'; $('gametime').innerHTML = endTime + "秒"; } }
通過(guò)數(shù)組和表格的配合,實(shí)現(xiàn)配對(duì)游戲,加深對(duì)表格創(chuàng)建和數(shù)組的運(yùn)用。處理邏輯和數(shù)據(jù)顯示分離,根據(jù)狀態(tài)值做到不同顯示的狀態(tài)。
以上這篇javascript實(shí)現(xiàn)數(shù)字配對(duì)游戲的實(shí)例講解就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
淺談Emergence.js 檢測(cè)元素可見(jiàn)性的 js 插件
這篇文章主要介紹了淺談Emergence.js 檢測(cè)元素可見(jiàn)性的 js 插件,詳細(xì)的介紹了Emergence.js安裝和使用方法,具有一定的參加性,有興趣的可以了解一下2017-11-11input鏈接頁(yè)面、打開(kāi)新網(wǎng)頁(yè)等等的具體實(shí)現(xiàn)
input可以鏈接到某頁(yè)、返回、打開(kāi)新網(wǎng)頁(yè)、打開(kāi)無(wú)邊框的新窗口等等,本文整理了一些,感興趣的朋友可以參考下2013-12-12前端CryptoJS加密、后端JAVA解密代碼實(shí)現(xiàn)參考
這篇文章主要介紹了前端CryptoJS加密、后端JAVA解密代碼實(shí)現(xiàn)參考,需要的朋友可以參考下2023-12-12純Javascript實(shí)現(xiàn)ping功能的方法
這篇文章主要介紹了純Javascript實(shí)現(xiàn)ping功能的方法,實(shí)例分析了javascript實(shí)現(xiàn)ping功能的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03js實(shí)現(xiàn)運(yùn)行代碼需要刷新的解決方法
js實(shí)現(xiàn)運(yùn)行代碼需要刷新的解決方法...2007-08-08bootstrap模態(tài)框?qū)崿F(xiàn)拖拽效果
這篇文章主要為大家詳細(xì)介紹了bootstrap模態(tài)框?qū)崿F(xiàn)拖拽效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-12-12