俄罗斯方块

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>俄罗斯方块</title>
        <style>
            *{
                margin: 0;
                padding: 0;
            }
            body{
                overflow: hidden;
                background-image: url("images/风景.webp");
                /* 使背景图片保持大小。不受页面放大缩小的影响 */
                background-size: 100%;
                background-position-x: center;
                background-repeat: no-repeat;
            }
            table{
                border-collapse: collapse;
                margin:20px auto;
                float: left;
                margin-right: 50px;
                background-color: #252525;
            }
            td{
                width: 30px;
                height: 30px;
                border: 1px solid rgb(84, 111, 112);
            }
            .c1{
                background-color: aqua; 
            }
            .c2{
                background-color: rgb(230, 157, 89);
            }
            .c3{
                background-color: rgb(58, 37, 175);
            }
            .c4{
                background-color: rgb(192, 41, 159);
            }
            .c5{
                background-color: rgb(194, 214, 83);
            }
            .c6{
                background-color: rgb(26, 8, 8);
            }
            .c7{
                background-color: rgb(226, 202, 196);
            }

            h2{
                color: aliceblue;
            }
        </style>
    </head>
    <body>
        <h2 id="score">分数:0</h2>
        <h2 id="f">帧编号:0</h2>
    </body>
</html>
<script src="js/jquery-3.4.1.js"></script>
<script src="js/GAME.js"></script>
<script src="js/block.js"></script>
<script src="js/block_json.js"></script>
<script src="js/Map.js"></script>
<script>
    var game=new Game(); 
    // var map=new Map();
    // var block=new block();
    // var block=new block();
    // block.render();

    // console.log(fk);
    // var block=new block();
    // block.render();
</script> 

block_json.js

//俄罗斯方块有7种,4个方向
//用二维数组表示方块的状态
// [
//     [0,0,0,0,0],
//     [1,1,1,0,0],
//     [0,1,0,0,0],
//     [0,1,0,0,0]
// ]
//用三维数组表示俄罗斯方块的各个形态

var fk={
    "S":[
        [
            [0,1,1,0],
            [1,1,0,0],
            [0,0,0,0],
            [0,0,0,0]
        ],
        [
            [0,1,0,0],
            [0,1,1,0],
            [0,0,1,0],
            [0,0,0,0]
        ],
    ],
    "Z":[
        [
            [2,2,0,0],
            [0,2,2,0],
            [0,0,0,0],
            [0,0,0,0]
        ],
        [
            [0,0,2,0],
            [0,2,2,0],
            [0,2,0,0],
            [0,0,0,0]
        ],
    ],
    "J":[
        [
            [0,3,0,0],
            [0,3,0,0],
            [3,3,0,0],
            [0,0,0,0]
        ],
        [
            [3,0,0,0],
            [3,3,3,0],
            [0,0,0,0],
            [0,0,0,0]
        ],
        [
            [0,3,3,0],
            [0,3,0,0],
            [0,3,0,0],
            [0,0,0,0]
        ],
        [
            [3,3,3,0],
            [0,0,3,0],
            [0,0,0,0],
            [0,0,0,0]
        ],
    ],
    "L":[
        [
            [0,4,0,0],
            [0,4,0,0],
            [0,4,4,0],
            [0,0,0,0]
        ],
        [
            [4,4,4,0],
            [4,0,0,0],
            [0,0,0,0],
            [0,0,0,0]
        ],
        [
            [4,4,0,0],
            [0,4,0,0],
            [0,4,0,0],
            [0,0,0,0]
        ],
        [
            [0,0,4,0],
            [4,4,4,0],
            [0,0,0,0],
            [0,0,0,0]
        ],
    ],
    "I":[
        [
            [0,5,0,0],
            [0,5,0,0],
            [0,5,0,0],
            [0,5,0,0]
        ],
        [
            [5,5,5,5],
            [0,0,0,0],
            [0,0,0,0],
            [0,0,0,0]
        ]
    ],
    "O":[
        [
            [0,6,6,0],
            [0,6,6,0],
            [0,0,0,0],
            [0,0,0,0]
        ],
    ],
    "T":[
        [
            [7,7,7,0],
            [0,7,0,0],
            [0,7,0,0],
            [0,0,0,0]
        ],
        [
            [0,0,7,0],
            [7,7,7,0],
            [0,0,7,0],
            [0,0,0,0]
        ],
        [
            [0,7,0,0],
            [0,7,0,0],
            [7,7,7,0],
            [0,0,0,0]
        ],
        [
            [7,0,0,0],
            [7,7,7,0],
            [7,0,0,0],
            [0,0,0,0]
        ],
    ],
}

block.js

(function () {
    window.block=function(){
        // this.block=[
        //     [0,1,1,0],
        //     [1,1,0,0],
        //     [0,0,0,0],
        //     [0,0,0,0]
        // ];
        //1.得到随机的方块
        var allType=["S","Z","J","L","I","O","T"];
        //2.从所有的类型中随机得到一种
        this.type=allType[parseInt(Math.random()*allType.length)]; 
        //3.得到随机图案的不同状态
        this.allDar=fk[this.type].length;
        //4.通过当前的allDar的长度随机得到不同的数字
        this.dir=parseInt(Math.random()*this.allDar)
        //得到随机的方块
        this.code=fk[this.type][this.dir];


        //初始的行
        this.row=0; 
        //初始的列,因为要居中显示,所以列要为4
        this.col=4;
    }
    block.prototype.render=function(){
        //渲染四行四列的方块
        for (i = 0; i < 4; i++) {
            for(var j=0;j<4;j++){
                //判断四行四列中不等于0的
                if (this.code[i][j]!=0) {
                    game.setColor(i+this.row,j+this.col,this.code[i][j])
                }
            }
            
        }
    }

    block.prototype.check=function(row,col){
        //能力判断方法,判断对应位置的方块和地图是否都有不为0的情况,如果有返回true,否则返回false
        for (var i = 0; i < 4; i++) {
            for (var j = 0; j < 4; j++) {
                if (this.code[i][j]!=0 && game.map.mapCode[i+row][j+col]!=0) {
                    return false;
                }
            }
            
        }
        return true;
    }

    //判断是否有向左移动的能力
    block.prototype.checkLeft=function(){
        //判断是否可以向左
        if (this.check(this.row,this.col-1)) {
            this.col--;
        }
    }

    //判断是否有向右移动的能力
    block.prototype.checkRight=function(){
        //判断是否可以向右
        if (this.check(this.row,this.col+1)) {
            this.col++;
        }
    }

    //一键到底
    block.prototype.checkBotton=function(){
        if (this.check(this.row+1,this.col)) {
            //改变方向
            this.row++;
        }
    }

    //方块的旋转
    block.prototype.checkRot=function(){
        //备份旧的形状方向
        var oldDir=this.dir;
        //改变新的
        this.dir++;
        if (this.dir>this.allDar-1) {
            this.dir=0;
        }
        //改变方向之后渲染新的方块方向
        this.code=fk[this.type][this.dir];
        // console.log(this.dir);
        //渲染之后的方块需要判断,是否有能力渲染
        if (!this.check(this.row,this.col)) {
            //重合,打回原形
            this.dir=oldDir;
            //再次渲染方块
            this.code=fk[this.type][this.dir]
        }
    }

    //方块下落,判断当前的位置是否能下落
    block.prototype.checkDown=function(){
        //判断当前地图的位置和方块的位置是否重合,this.row+1是预判断
        if (this.check(this.row+1,this.col)) {
            this.row++;
        }else{
            //此时就是下落到底的状态,渲染新的方块
            game.block=game.nextblock;//预测下一次
            game.nextblock=new block();
            //方块到底了,渲染到地图的code中
            this.renderMap();
            //判断是否可以消行
            game.map.CheckRemove();
            //判断是否游戏结束
            this.checkOver();
        }
    }

    //将已经到底的方块渲染到地图上
    block.prototype.renderMap=function(){
        for (var i = 0; i < 4; i++) {
            //将现在已有的方块渲染到Map的mapCode上
            for (var j = 0; j < 4; j++) {
                if (this.code[i][j]!==0) {
                    //改变地图的mapCode数据
                game.map.mapCode[this.row+i][this.col+j]=this.code[i][j];
                } 
            }
        }
    }


    //判断结束
    block.prototype.checkOver=function(){
        for (var i = 0; i < game.col; i++) {
            if (game.map.mapCode[0][i]!=0) {
                clearInterval(game.time);
                alert("游戏结束,您当前的分数为"+game.score);
            }
        }
    }
})()

Game.js

//最外层用IIFE包裹起来  实际中多个方法并行开发,将多个js文件打包成一个js文件,没有IIFE会造成作用域和命名的冲突
(function(){
    window.Game=function(mapGame) {
        //初始化
        this.row=20;
        this.col=12;
        //初始化
        this.init();
        //实例化方块
        this.block=new block();
        //实例化下一个方块
        this.nextblock=new block();
        //实例化地图
        this.map=new Map(this);
        //启动定时器
        this.start();
        //事件监听
        this.bindEvent();
        //分数
        this.score=0;
        //速度
        this.during=30;
    }
    Game.prototype.init=function(){
        //初始化大表格
        var $table=$("<table></table>")
        $table.addClass("tab1");
        for (var i = 0; i < this.row; i++) {
            $tr=$("<tr></tr>")
            for (var j = 0; j < this.col; j++) {
                $td=$("<td></td>")
                $tr.append($td)
            }
            $table.append($tr);
        } 
        //初始化预览窗口
        var $table2=$("<table></table>")
        $table2.addClass("tab2");
        for (var i = 0; i < 4; i++) {
            $tr2=$("<tr></tr>")
            for (var j = 0; j < 4; j++) {
                $td2=$("<td></td>")
                $tr2.append($td2)
            }
            $table2.append($tr2); 
        } 

        $("body").append($table);
        $("body").append($table2);
    }
    Game.prototype.setColor=function(row,col,num){
        //给对应的有颜色的方块添加类名
        $(".tab1").find("tr").eq(row).children("td").eq(col).addClass("c"+num)
    }

    Game.prototype.setnextColor=function(row,col,num){
        for (var i = 0; i < 4; i++) {
            for (var j = 0; j < 4; j++) {
                if (this.nextblock.code[i][j]!=0) {
                    $(".tab2").find("tr").eq(i).children("td").eq(j).addClass("c"+this.nextblock.code[i][j])
                }
                
            }
        }
        
    }

    //清屏功能
    Game.prototype.clear=function(){
        for (var i = 0; i < this.row; i++) {
            for (var j = 0; j < this.col; j++) {
                $(".tab1").find("tr").eq(i).children("td").eq(j).removeClass();
            }
            
        }

        for (var i = 0; i < this.row; i++) {
            for (var j = 0; j < this.col; j++) {
                $(".tab2").find("tr").eq(i).children("td").eq(j).removeClass();
            }
            
        }
    };
    Game.prototype.bindEvent=function(){
        //备份
        var self=this;
        $(document).keydown(function(event){
            // console.log(event.keyCode);
            if (event.keyCode==37) {
                //判断是否有向左移动的能力
                self.block.checkLeft();
            }
            else if(event.keyCode==39){
                //判断是否有向右移动的能力
                self.block.checkRight()
            }
            else if(event.keyCode==40){
                self.block.checkBotton()
            }
            else if(event.keyCode==38){
                self.block.checkRot()
            }
            // console.log(event.keyCode)
        })
    }
    Game.prototype.start=function(){
        var self=this;
        //帧编号
        this.f=0;
        this.time=setInterval(function(){
            self.f++;
            //渲染帧编号
            document.getElementById("f").innerHTML="帧编号:"+self.f;
            //清屏
            self.clear();
            //渲染方块
            self.block.render();
            //渲染预览方块
            self.setnextColor();
            //渲染地图
            self.map.render(self); 
            //下落
            self.f % self.during == 0 && self.block.checkDown()
        },20)
    }
})()
    

Map.js

(function(){
    window.Map=function(){
        //地图的矩阵
        this.mapCode=[
            [0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0],
            [9,9,9,9,9,9,9,9,9,9,9,9],
        ]
    }
    Map.prototype.render=function(mapGame){
        // 渲染地图
        for (var i = 0; i < mapGame.row; i++) {
            for (var j = 0; j < mapGame.col; j++) {
                //当方块到底之后,不会渲染当前的状态,只会消失,是mapCode一直在维持底部的持状态
                if (this.mapCode[i][j]!=0) {
                    game.setColor(i,j,this.mapCode[i][j])
                }
            }
            
        }
    }

    Map.prototype.CheckRemove=function(){
        //判断当前的MapCode是否该消行
        //如果当前行的每一个元素都不是0,则消掉此行
        for (var i = 0; i < 20; i++) {
            if (this.mapCode[i].indexOf(0)==-1) {
                //删除这一行
                this.mapCode.splice(i,1)
                //删除一行补充一行
                this.mapCode.unshift([0,0,0,0,0,0,0,0,0,0,0,0]);
                //分数增加
                game.score+=10;
                //渲染分数
                document.getElementById("score").innerHTML="分数:"+game.score;
                if (game.score%100==0) {
                    game.during-=5 ;
                }
            }
        }

    }
})()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值