俄罗斯方块 1 (实现移动和相关显示)

/**
 * Created by Administrator on 2016/10/22.
 */
//定义cell类型:3个属性:r,c,src
function cell(r,c,src){
    this.r=r;
    this.c=c;
    this.src=src;
}

function State(arr){//创建状态对象  把相对坐标数据封装进去
    for(var i=0;i<4;i++){
        this["r"+i]=arr[2*i];
        this["c"+i]=arr[2*i+1];
    }

}
function shape(rcs,src,states,orgi) {
    this.cells =[];
    for (i = 0;i<4;i++){
        this.cells.push(new cell(rcs[2*i],rcs[2*i+1],src));
    }
    this.states=states;//状态数组
    this.orgCell=this.cells[orgi];//旋转参照的格子对象
    this.statei=0;
}

shape.prototype={
    IMGS:{
    T:"img/T.png",
    O:"img/O.png",
    I:"img/I.png"
},
    moveDown:function(){
     for(i=0;i<this.cells.length;i++){
         this.cells[i].r++;
     }
    },
    moveLeft:function(){
        for(i=0;i<this.cells.length;i++){
            this.cells[i].c= this.cells[i].c-1;
        }
    },
    moveRight:function(){
        for(i=0;i<this.cells.length;i++){
            this.cells[i].c++;
        }
    },
    rotateR:function(){//右旋转
        this.statei++;
        if(this.statei==this.states.length){
            this.statei=0;
        }
        this.rotate();
    },
    rotate:function(){
        var state=this.states[this.statei];
        for(i=0;i< this.cells.length;i++){
            if(this.cells[i]!=this.orgCell){
                if(this.cells[i]!=this.orgCell){   //使用状态数据修改当前shape里面格子坐标
                    this.cells[i].r=this.orgCell.r+state["r"+i];
                    this.cells[i].c=this.orgCell.c+state["c"+i];
                }
            }
        }
    },
    rotateL:function(){
        this.statei--;
        if(this.statei==-1){
            this.statei=4;
        }
        this.rotate();
    }

    };
function T(){
    shape.call(this,[0,3,0,4,0,5,1,4],this.IMGS.T,[
        new State([0,-1,0,0,0,+1,+1,0]),     //封装状态数据传进去 相对坐标
        new State([-1,0,0,0,+1,0,0,-1]),
        new State([0,+1,0,0,0,-1,-1,0]),
        new State([+1,0,0,0,-1,0,0,+1])
    ],1);
};
Object.setPrototypeOf(T.prototype,shape.prototype);
function O(){
    shape.call(this,[0,3,0,4,1,3,1,4],this.IMGS.O,[],1);
};
Object.setPrototypeOf(O.prototype,shape.prototype);
function I(){
    shape.call(this,[0,3,0,4,0,5,0,6],this.IMGS.I);
};
Object.setPrototypeOf(I.prototype,shape.prototype);
/**
 * Created by Administrator on 2016/10/22.
 */
var game={
    CSIZE:26,
    OFFSET:15,
    pg:null,//保存游戏容器元素
    shape:null,
    interval:200,
    timer:null,
    RN:20,
    CN:10,
    wall:null,
    shape:null,
    nextshape:null,
    start:function(){
          this.wall=[];
        for(var r=0;r<this.RN;r++){
            this.wall[r]=new Array(this.CN);
        }
        this.pg=document.querySelector(".playground");
        this.shape=new T();
        this.shape=this.randomShape();
        this.nextshape=this.randomShape();
        this.paint();
        this.timer=setInterval(this.moveDown.bind(this),this.interval);
        document.onkeydown= (function (ev) {
             switch (ev.keyCode){
                 case 37:this.moveLeft();break;
                 case 39:this.moveRight();break;
                 case 40:this.hardDrop();break;
                 case 38:this.rotateR();break;
                 case 90:this.rotateL();break;
             }
        }).bind(this);
},
    canRotate:function(){//判断是否越界
        for(var i=0;i<this.shape.cells.length;i++){
            var cell=this.shape.cells[i];
            if(cell.r>=this.RN||cell.r<0
                ||cell.c>=this.CN||cell.c<0)
                return false;
            else if(this.wall[cell.r][cell.c])
                return false;
        }
        return true;
    },
    rotateR:function(){
        this.shape.rotateR();
        if(!this.canRotate())//如果旋转后越界,再转回来
            this.shape.rotateL();
    },
    rotateL:function(){
        this.shape.rotateL();
        if(!this.canRotate())
            this.shape.rotateR();
    },
    hardDrop:function(){//直接降下来

        while(this.canDown()){
            this.moveDown();
        }
    },
    canLeft:function(){//判断能否左移动
        for(var i=0;i<this.shape.cells.length;i++){
            var cell=this.shape.cells[i];
            if(cell.c==0){
                return false;
            }
            else if(this.wall[cell.r][cell.c-1]){
                return false;
            }
        }
        return true;
    },
    moveLeft:function(){//左移

        if(this.canLeft()){
            this.shape.moveLeft();
            this.paint();
        }
    },
    canRight:function(){//判断能否右移动
        for(i=0;i<this.shape.cells.length;i++){
            var cell=this.shape.cells[i];
            if(cell.c==this.CN-1){
                return false;
            }
            else if(this.wall[cell.r][cell.c+1]){
                return false;
            }
        }
        return true;
    },
    moveRight:function(){//右移

        if(this.canRight()){
            this.shape.moveRight();
            this.paint();
        }
    },

    paintShape:function(){//绘制主图形//未删存在的
        var frag=document.createDocumentFragment();
        for(var i=0;i<4;i++){
            var cell=this.shape.cells[i];
            frag.appendChild(this.paintCell(cell));
        }
        this.pg.appendChild(frag);
    },
    moveDown:function(){  //下移动
        if(this.canDown()){
            this.shape.moveDown();
            this.paint();
        }

       else{   //到底了 替换

            this.landIntoWall();
            this.shape=this.nextshape;
            this.nextshape=this.randomShape();
        }
    },
    paint:function(){//总的画
        this.pg.innerHTML=this.pg.innerHTML.replace(/<imgs[^>]*>/g,"");
        this.paintShape();
        this.painWall();
        this.painNext();
    },
    canDown:function(){ //能否下
        for(var i=0;i<this.shape.cells.length;i++) {
            var cell = this.shape.cells[i];
            if(cell.r==this.RN-1){return false;}
            else if(this.wall[cell.r+1][cell.c]){
                return false;
            }
        }
        return true;
    },
    landIntoWall:function(){//保存在墙数组中
        for(var i=0;i<this.shape.cells.length;i++){
            var cell=this.shape.cells[i];
            this.wall[cell.r][cell.c]=cell;
        }


    },
    painWall:function(){//画墙
        var frag=document.createDocumentFragment();
        for(var r=this.RN-1;r>0;r--){
            if(this.wall[r].join("")=="") break;
            else
            for(var c=0;c<this.CN;c++) {
                if(this.wall[r][c])
                {frag.appendChild(this.paintCell(this.wall[r][c]))};
            }
        }
        this.pg.appendChild(frag);
    },
    paintCell:function(cell){//画单元
        var img=new Image();
        img.style.left=cell.c*this.CSIZE+this.OFFSET+'px';
        img.style.top=cell.r*this.CSIZE+this.OFFSET+'px';
        img.src=cell.src;
        return img;
},
    randomShape:function(){//随机生成一个shape
        var r=Math.floor(Math.random()*3);
        switch (r){
            case 0: return new O();
            case 1: return new T();
            case 2: return new I();
        }
    },
    painNext:function(){ //画nextShape
        var frag=document.createDocumentFragment();
        for(var i=0;i<this.nextshape.cells.length;i++){
            var img=this.paintCell(this.nextshape.cells[i]);
            img.style.left=parseFloat(img.style.left)+10*this.CSIZE+"px";
            img.style.top=parseFloat(img.style.top)+this.CSIZE+"px";
            var cell=this.nextshape.cells[i];
            frag.appendChild(img);
        }
        this.pg.appendChild(frag);
    },
}
game.start();
原文地址:https://www.cnblogs.com/godbutton/p/5988171.html