javascript version 2048 mini game

  • 2020-05-17 04:47:48
  • OfStack

No technical content, just to practice the logic of the code. For the sake of clarity, I've written the logical controls in global variables and encapsulated the UI operations in UI objects, and that's about it. For reference only. At work, my coding style was teased too messy, so I wanted to try to write something that wasn't so messy.


<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>
// Global methods are used for logical control
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];
}
// The interface operation begins, and the parameters of the interface operation are obtained through the global method
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;// Block user actions before animation is completed
    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;// unlocked
};
// create
UI.init=function(nw,maxUndo,size,times){
    UI.times=times||8;// Animation transition
    UI.nw=nw||5;// Square side length
    UI.map=map=x4(UI.nw);// Create a number block object
    UI.size=size||100;// Cell width
    UI.maxUndo=maxUndo||5;// Maximum undo steps
    $('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);
// Autoplay, for demonstration only. No event binding
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>

That's all for this article, I hope you enjoy it.


Related articles: