基于JS制作一個簡易的2048游戲
更新時間:2022年05月06日 08:21:30 作者:巨輪
這篇文章主要介紹了如何利用JS編寫一個簡單的2048小游戲,代碼簡單易懂對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
效果圖
實現(xiàn)代碼
<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/> <title>2048</title> <style type="text/css"> .basic{ height:80px; width:80px; background-color:#DBDBDB; float:left; margin:2px; } .row{ height:80px; clear:both; } </style> </head> <body> <div id="pool"></div> <div id="sample" class="basic" style='opacity: 0;'></div> <div>score:<span id='score' style="font-size:200%;font-weight:bold;"></span></div> <script type="text/javascript" > //對象內(nèi)使用,要加this var container={ rowNum:4, colNum:4, score:0,//靠弄個Cookie記錄下游戲記錄 isMoved:false,//Block 有沒有移動過 content:[],//{x:col,y:row,v:value} colour:['#DBDBDB','#56A36C','#EFCEE8', '#81C2D6','#8192D6','#D9B3E6', '#DCF7A1','#83FCD8','#E8F2FF', '#91C6FF','#B8F788','#58D2E8', '#F2B6B6','#E8ED51','#FFE3FB', '#E8FF8C','#FFDEC9','#F5A433', '#E6109B','#96C4E6','#E560CD'], colourObject:{}, //初始化 背景 loadBackground:function(){ var pool = document.getElementById("pool"); var sample = document.getElementById("sample") var margin = 2; var dotWidth = parseFloat(sample.offsetWidth) + margin;//基本方塊寬度 + margin for(var i = 0; i != this.rowNum; i++){ //創(chuàng)建行 var rDiv = document.createElement("div"); rDiv.setAttribute('id','r' + i); rDiv.setAttribute('class','row'); for(var j = 0; j != this.colNum; j++){ var cDiv = document.createElement("div"); cDiv.setAttribute('id','c'+j + '_r' + i); cDiv.setAttribute('class','basic'); rDiv.appendChild(cDiv); } rDiv.setAttribute('width',(this.colNum * (dotWidth + margin)) + 'px') pool.appendChild(rDiv); } }, findBlock:function(colx, rowy){ return this.content.find(function(value){ return value.x == colx && value.y == rowy; }); }, addBlockToMine:function(){//開局或移動后,添加新塊 var zeroBlockArray = this.content.filter(function(value){ return value.v == 0; }); if(zeroBlockArray.length != 0){ zeroBlockArray[this.makeRandomInteger(zeroBlockArray.length)].v = (this.makeRandomInteger(2) + 1) * 2; } }, makeRandomInteger:function(scope){ return Math.floor(Math.random() * scope); }, checkDeath:function(){ if(this.content.filter(function(value){ return value.v == 0; }).length != 0){ return false;//有零塊就表示沒有死 }else{ //滿格時,檢測相鄰之間可合并的可能性//Jallen Kwong //再沒有合并的可能,沒有的話,游戲就結束 //窮舉法(不聰明的方法) for(var i = 0; i < this.rowNum; i++){ if(i != this.rowNum - 1){ for(var j = 0;j < this.colNum; j++){ var mainBlock = this.findBlock(j, i); var downBlock = this.findBlock(j, i + 1); if(j != this.colNum - 1){ var rightBlock = this.findBlock(j + 1,i); if(mainBlock.v == rightBlock.v || mainBlock.v == downBlock.v){ return false; } }else{ if(mainBlock.v == downBlock.v){ return false; } } } }else{ for(var j = 0;j < this.colNum - 1; j++){ var mainBlock = this.findBlock(j, i); var rightBlock = this.findBlock(j + 1, i); if(mainBlock.v == rightBlock.v){ return false; } } } } return true;//真的Game Over } }, refresh:function(){//刷新顯示頁面 for(var row = 0;row < this.rowNum;row++){ for(var col = 0;col < this.colNum;col++){ var value = this.findBlock(col,row).v; var elem = document.getElementById('c'+col+'_r'+row); elem.style.backgroundColor = this.colourObject[value] == undefined?this.colourObject[0]:this.colourObject[value]; elem.innerHTML = (value == 0 ? "" : "<span style='font-size:200%;font-weight:bold;'>"+value+"</span>"); } } document.getElementById('score').innerHTML = this.score; }, addKeyListener:function(event){ var keycode = event.keyCode; if(keycode >= 37 && keycode <= 40){ //alert(keycode); event.preventDefault(); var changeCount = 0;//記住塊有沒真正得移動過 switch(keycode){ case 37://左 //console.log(keycode); for(var i = 0; i < this.rowNum; i++){ var queue = []; var flag = false; //入棧 for(var j = 0 ; j < this.colNum; j++){ var block = this.findBlock(j, i); if(block.v == 0){ continue; } flag = this.coreCalculate(block, queue, flag); } //出隊列 for(var k = 0 ;k < this.colNum; k++){ changeCount += this.outOfQueue(k, i, queue, k); } } break; case 38://上 for(var i = 0; i < this.colNum; i++){ var queue = []; var flag = false; for(var j = 0 ;j < this.rowNum; j++){ var block = this.findBlock(i, j); if(block.v == 0){ continue; } flag = this.coreCalculate(block, queue, flag); } //出隊列 for(var k = 0 ;k < this.rowNum; k++){ changeCount += this.outOfQueue(i, k, queue, k); } } break; case 39://右 for(var i = 0; i < this.rowNum; i++){ var queue = []; var flag = false; //入棧 for(var j = this.colNum - 1 ; j >= 0; j--){ var block = this.findBlock(j, i); if(block.v == 0){ continue; } flag = this.coreCalculate(block, queue, flag); } //console.log(queue); //出隊列 for(var k = this.colNum - 1 ,l = 0;k >= 0; k--,l++){ changeCount += this.outOfQueue(k, i, queue, l); } } break; case 40://下 for(var i = 0; i < this.colNum; i++){ var queue = []; var flag = false; for(var j = this.rowNum - 1 ;j >= 0; j--){ var block = this.findBlock(i, j); if(block.v == 0){ continue; } flag = this.coreCalculate(block, queue, flag); } //出隊列 for(var k = this.rowNum - 1 ,l = 0;k >= 0; k--,l++){ changeCount += this.outOfQueue(i, k, queue, l); } } break; default:break; } //要檢查content的v們有沒有改變過 //1.入棧操作前,要來個數(shù)組拷貝,然后在做比對,這做法并不聰明 //2.出隊列的時候,跟原來的值進行比較,有改變 changCount++ //console.log('changeCount:' + changeCount); if(changeCount != 0){ this.addBlockToMine(); this.refresh();//刷新顯示頁面 if(this.checkDeath()){ alert("Game Over!"); document.onkeydown = function(event){ var keycode = event.keyCode; if(keycode >= 37 && keycode <= 40){ event.preventDefault(); alert("Game Over!"); } }; } } } }, init:function(){ for(var row = 0; row < this.rowNum; row++){ for(var col = 0; col < this.colNum; col++){ this.content[this.content.length] = {x:col,y:row,v:0}; } } for(var i = 0;i <= 20;i++){ if(i == 0){ this.colourObject[i] = this.colour[i]; continue; } this.colourObject[Math.pow(2,i)] = this.colour[i]; } //console.log(this.colourObject[7]); }, coreCalculate:function(block, queue, flag){ flag的作用,入棧方式有問題,譬如2,2,4 應得 4,4 但結果 得8 if(queue.length == 0 ){ queue[queue.length] = block.v; return flag; }else{ var tailOfQueue = queue[queue.length - 1]; if((tailOfQueue == block.v) && !flag){ this.score += (queue[queue.length - 1] = tailOfQueue * 2); return true; }else{ queue[queue.length] = block.v; return false; } } }, outOfQueue:function(colx, rowy, queue, index){ var block = this.findBlock(colx, rowy); var oldValue = block.v; block.v = queue[index] == undefined ? 0 : queue[index]; return oldValue != block.v? 1 : 0; } }; //main window.onload = function(){ container.loadBackground(); container.init(); //alert(container.findBlock(1,1).v); container.addBlockToMine(); container.addBlockToMine(); container.refresh(); document.addEventListener('keydown', function(event){ container.addKeyListener(event); }); }; </script> </body> </html>
到此這篇關于基于JS制作一個簡易的2048游戲的文章就介紹到這了,更多相關JS 2048游戲內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
解析ScrollPic在ie8下只滾動一遍,然后變?yōu)榭瞻?ie6,ie7,chrome,firefox正常
解析ScrollPic在ie8下只滾動一遍,然后變?yōu)榭瞻?ie6,ie7,chrome,firefox都正常)2013-06-06Bootstrap 模態(tài)對話框只加載一次 remote 數(shù)據(jù)的完美解決辦法
前端框架 Bootstrap 的模態(tài)對話框,可以使用 remote 選項指定一個 URL,這樣對話框在第一次彈出的時候就會自動從這個地址加載數(shù)據(jù)到 .modal-body 中,但是它只會加載一次,不過通過在事件中調(diào)用 removeData() 方法可以解決這個問題,具體操作方法,大家通過本文了解下吧2017-07-07一文帶你掌握JavaScript中Moment.js如何操作日期和時間
Moment.js是一個極其強大的JavaScript庫,專門用于解析、驗證、操作和顯示日期和時間,下面就跟隨小編一起學習一下Moment.js的具體使用吧2024-01-01在table中插入多行的js代碼(與insertAdjacentHTML相似的功能)
在table中插入多行,能使用與insertAdjacentHTML相似的功能2010-06-06