javascript版2048小游戏

  没有技术含量,只是用来练习代码逻辑的。为了代码结构清晰,我把逻辑控制部分写在全局变量里,用户界面操作封装在UI对象里,大概就这样了。仅供参考。工作时候,我的编码风格有人吐槽太乱了,所以我想试着写一个不是那么乱的东西出来。。

  

复制代码 代码如下:

  <HTML>

  <head>

  <title>2048 DEMO</title>

  <meta charset='utf-8' />

  <!--

  708616 javascript present

  http://treemonster.sinaapp.com

  [email protected]

  -->

  <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];

  }

  //界面操作开始,界面操作的参数通过全局方法来获得

  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;//未完成动画之前阻止用户动作

  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;//解除锁定

  };

  //创建

  UI.init=function(nw,maxUndo,size,times){

  UI.times=times||8;//动画过度次数

  UI.nw=nw||5;//方阵边长

  UI.map=map=x4(UI.nw);//创建数字块对象

  UI.size=size||100;//单元格宽度

  UI.maxUndo=maxUndo||5;//最大撤销步数

  $('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);

  //自动播放,仅用来做演示的。没有做事件绑定

  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>

  以上就是本文所述的全部内容了,希望大家能够喜欢。