javascript版2048小游戲
沒有技術(shù)含量,只是用來練習(xí)代碼邏輯的。為了代碼結(jié)構(gòu)清晰,我把邏輯控制部分寫在全局變量里,用戶界面操作封裝在UI對象里,大概就這樣了。僅供參考。工作時(shí)候,我的編碼風(fēng)格有人吐槽太亂了,所以我想試著寫一個(gè)不是那么亂的東西出來。。
<HTML>
<head>
<title>2048 DEMO</title>
<meta charset='utf-8' />
<!--
708616 javascript present
http://treemonster.sinaapp.com
1696292264@qq.com
-->
<head>
<div id='box'>
MSIE is SB
<script>
//全局方法用于邏輯控制
function x4(n){
var t=[];
while(n-->0)t.push([]);
return t;
}
function xx(f){
for(var i=0;i<UI.nw;i++){
for(var j=0;j<UI.nw;j++){
f(i,j);
}
}
}
function make(n){
return {
number:n,
moveStep:0,
newNumber:n,
needKill:0
};
}
function tran(_arr,md){
var undo=x4(UI.nw);
var out=x4(UI.nw);
var ud=UI.undo;
if(ud.push(undo)>32)ud.shift();
for(var i=0;i<UI.nw;i++){
var t=[],o=md%2^1;
for(var k=0;k<UI.nw;k++){
undo[i][k]=_arr[i][k].number;
if(md<3)t.push(_arr[i][k]);else t.push(_arr[k][i]);
}
o && t.reverse();
t=trans(t);
if(o)t[0].reverse(),t[1].reverse();
for(var j=0;j<UI.nw;j++){
var x=i,y=j;
if(md>2)x=j,y=i;
_arr[x][y]=t[0][j];
out[x][y]=t[1][j];
}
}
return [_arr,out];
}
function trans(arr){
for(var i=0,m=0;i<UI.nw;i++){
if(arr[i].number===0)m++;else arr[i].moveStep+=m;
var _i=arr[i];
for(var j=i-1;j>=0;j--){
if(!arr[j].number)continue;
if(arr[j].needKill)break;
if(arr[j].number==_i.number){
arr[j].needKill=1;
arr[i].newNumber*=2;
arr[i].moveStep++;
m++;
}
}
}
var out=[];
for(var i=UI.nw;i--;){
!arr[i].needKill && arr[i].number && out.unshift(arr[i].newNumber);
}
while(out.length<UI.nw)out.push(0);
return [arr,out];
}
//界面操作開始,界面操作的參數(shù)通過全局方法來獲得
function $(a){return document.getElementById(a);}
UI={};
UI.update=function(d){
if(UI.locked)return;
var map=this.map;
var n=this.times;
UI.locked=1;//未完成動(dòng)畫之前阻止用戶動(dòng)作
var out=tran(map,d)[1];
var _n=0,_begin=x4(UI.nw);
(function(){
if(_n>n){
var _q=0;
xx(function(i,j){
_q=_q||this.map[i][j].moveStep;
var o=$('i'+i+'j'+j);
o.innerHTML=out[i][j]||'';
o.className='x r'+o.innerText;
this.map[i][j]=make(out[i][j]);
o=o.style;
o.display='block';
o.left=UI.size*j+"px";
o.top=UI.size*i+"px";
});
return _q ? UI.addNew():(UI.locked=0);
}
xx(function(i,j){
var o=$('i'+i+'j'+j),t,o1=o.style,s=d<3?'left':'top';
if(t=map[i][j][_n==n?'newNumber':'number'])o.innerHTML=t;else o1.display='none';
if(_begin[i][j]===undefined)_begin[i][j]=parseInt(o1[s]);
o1[s]=(_begin[i][j]+(map[i][j].moveStep*100/n*_n)*Math.pow(-1,d))+'px';
});
_n++;
setTimeout(arguments.callee,10);
})();
}
UI.undo=[];
UI.addNew=function(_q){
UI.locked=1;
var r=[];
xx(function(i,j){
this.map[i][j].number || r.push([i,j]);
});
if(!r.length)return UI.locked=0;
var q=new Date%r.length;q=r[q];
var b=$('i'+q[0]+'j'+q[1]);
var m=this.map[q[0]][q[1]];
b.innerHTML=m.number=m.newNumber=2<<new Date%2;
b.className='x r'+b.innerText;
var o=0,q=5;
(function(){
if(o<100)setTimeout(arguments.callee,10);
b.style.opacity=Math.min(o+=q++,100)/100;
})();
UI.locked=0;//解除鎖定
};
//創(chuàng)建
UI.init=function(nw,maxUndo,size,times){
UI.times=times||8;//動(dòng)畫過度次數(shù)
UI.nw=nw||5;//方陣邊長
UI.map=map=x4(UI.nw);//創(chuàng)建數(shù)字塊對象
UI.size=size||100;//單元格寬度
UI.maxUndo=maxUndo||5;//最大撤銷步數(shù)
$('box').innerHTML='';
xx(function(i,j){
map[i][j]=make(0);
document.write("<div class='x' id='i"+i+"j"+j+"'\
style='left:"+(UI.size*j)+"px;top:"+(UI.size*i)+"px;'></div>\
<div class='y' \
style='left:"+(UI.size*j)+"px;top:"+(UI.size*i)+"px;'></div>");
});
UI.addNew();
UI.addNew();
};
UI.init(6,3,100,20);
//自動(dòng)播放,僅用來做演示的。沒有做事件綁定
setInterval(function(){UI.update([1,2,3,4][Math.random()*4|0]);},200);
</script>
</div>
<style>
#box{position:absolute;left:50%;top:50%;margin-left:-300px;margin-top:-300px;}
.x,.y{background:#ddd;position:absolute;width:80px;height:80px;font-size:30px;text-align:center;line-height:80px;font-weight:700;font-family:arial;z-index:1;}
.x{z-index:30;}
.r2{background: #eee4da;}
.r4{background: #ede0c8;}
.r8{color: #f9f6f2;background: #f2b179;}
.r16{ color: #f9f6f2;
background: #f59563; }
.r32{color: #f9f6f2;
background: #f67c5f; }
.r64{ color: #f9f6f2;
background: #f65e3b; }
.r128{ color: #f9f6f2;
background: #edcf72;}
.r256{ color: #f9f6f2;
background: #edcc61;}
.r512{ color: #f9f6f2;
background: #edc850;}
.r1024{ color: #f9f6f2;
background: #edc53f;}
.r2048{ color: #f9f6f2;
background: #edc22e;}
</style>
以上就是本文所述的全部內(nèi)容了,希望大家能夠喜歡。
相關(guān)文章
JS實(shí)現(xiàn)商品倒計(jì)時(shí)實(shí)現(xiàn)代碼
JS實(shí)現(xiàn)商品倒計(jì)時(shí)實(shí)現(xiàn)代碼,需要的朋友可以參考一下2013-05-05js中如何把字符串轉(zhuǎn)化為對象、數(shù)組示例代碼
在本文為大家介紹下把字符串轉(zhuǎn)化為對象:把文本轉(zhuǎn)化為對象、把文本轉(zhuǎn)化為數(shù)組,具體實(shí)現(xiàn)如下,感興趣的朋友可以參考下哈,希望對大家有所幫助2013-07-07Bootstrap 網(wǎng)站實(shí)例之單頁營銷網(wǎng)站
這篇文章主要介紹了Bootstrap 網(wǎng)站實(shí)例之單頁營銷網(wǎng)站的相關(guān)資料,本文給大家介紹的非常詳細(xì)具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2016-10-10Layui數(shù)據(jù)表格 前后端json數(shù)據(jù)接收的方法
今天小編就為大家分享一篇Layui數(shù)據(jù)表格 前后端json數(shù)據(jù)接收的方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09使用JS判斷是否數(shù)字和小數(shù)點(diǎn)組合的數(shù)字的兩中方法比較(isNaN和逐判斷)
使用js判斷數(shù)字和小數(shù)點(diǎn)的方法非常之多。但是就目前而言,我見過最好用的判斷方法應(yīng)該來說是isNaN,它比較方便,而逐個(gè)比較的方法有一定的弊端。2009-09-09用js實(shí)現(xiàn)手把手教你月入萬刀(轉(zhuǎn)貼)
用js實(shí)現(xiàn)手把手教你月入萬刀(轉(zhuǎn)貼)...2007-11-11使用JS判斷移動(dòng)端手機(jī)橫豎屏狀態(tài)
本文通過js和cas代碼分別給大家介紹了移動(dòng)端判斷手機(jī)橫豎屏狀態(tài)的相關(guān)知識(shí),非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2018-07-07