• 【转】 前端笔记之JavaScript面向对象(四)组件化开发&轮播图|俄罗斯方块实战


    【转】 前端笔记之JavaScript面向对象(四)组件化开发&轮播图|俄罗斯方块实战

    一、组件化开发

    1.1组件化概述

    页面特效的制作,特别需要HTMLCSS有固定的布局,所以说现在越来越流行组件开发的模式,就是用JS写一个类,当你实例化这个类的时候,页面上的效果布局也能自动完成。

    new Carousel();

    实例化后,页面中就有一个轮播图的布局结构,而且可以通过参数传递进去。

    这个new里面封装了HTMLCSSJS的业务逻辑。组件开发的规律就是所有按钮、小圆点、图片等等都是这个类(的实例的)属性,自己管理自己。

    组件开发的好处就是在用的时候可以高度自定义,在new的时候应该能传入一个JSON参数进行配置,当你的JSON里面的属性改变的时候,我们的UI界面逻辑就要有响应的变化。

    面向对象+设计模式组合各种类(通常是中介者模式),就是组件化开发。

    本质思想,组件只考虑两个事情:

    l 别人怎么控制我,要提供很多函数,这个函数可以改变我的状态。

    我怎么给别人提供接口,比如轮播图被点击时,要提供一个click事件回调。

    组件只需要对自己负责,至于别人怎么调用我的接口,在我提供的接口中做什么,自己不需要考虑。

    特点:

    组件都是可以单独测试的,所有组件都可以单独上树,进行测试。

    DOM都是动态生成的,组件开发中,现在90%以上的,都是将DOM写在JS中,在“查看源代码”中看见的是空标签。

    组件是嵌套的,往往大组件是小组件的中介者。

    优点:

    方便维护,功能易于插拔,很容易找出BUG的地方。

    l 易于复用,比如我们做一个分页条组件,此时可以非常自由在其他项目使用。

    组件开发是一个非常实用的技术,组件开发越来越火,催生了一些组件开发的框架:ReactVueAngular等。


    1.2轮播图组件开发

    JS对象、DOM对象,JS对象的属性是DOM对象

    用轮播图的面向对象举例,JS对象中有自己的参数属性(比如当前显示图片的编号、速度、间隔时间、宽度、高度),还DOM属性。

    <script type="text/javascript" src="js/jquery-1.12.3.min.js"></script>
    <script type="text/javascript" src="js/Carousel.js"></script>
    <script type="text/javascript">
         new Carousel({
           "id" : "Carousel",
           "images" : [
               {"picUrl" : "images/0.jpg", "link" : "http://www.iqianduan.cn"},
               {"picUrl" : "images/1.jpg", "link" : "http://www.iqianduan.cn"},
               {"picUrl" : "images/2.jpg", "link" : "http://www.iqianduan.cn"},
               {"picUrl" : "images/3.jpg", "link" : "http://www.iqianduan.cn"},
               {"picUrl" : "images/4.jpg", "link" : "http://www.iqianduan.cn"}
           ],
           "width" : 560,
           "height": 300,
           "speed" : 500,
           "interval" : 2000
         });
    </script>

     CSS样式:carousel样式后面动态创建

    #Carousel{
        width: 560px;
        height: 300px;
        position: relative;
        overflow: hidden;
    }
    .leftBtn,.rightBtn{
        position: absolute;
        top:50%;
        width: 30px;
        height: 30px;
        background-color: orange;
    }
    .leftBtn{left: 10px;}
    .rightBtn{right: 10px;}
    .circls{
        position: absolute;
        bottom: 10px;left: 100px;
        list-style: none;
    }
    .circls li{
        float: left;
        width: 20px;
        height: 20px;
        background-color: orange;
        margin-right: 10px;
    }
    .circls li.cur{background-color: red;}
    (function(){
        //强行暴露一个变量,一枝红杏出墙来
        window.Carousel = Carousel;
        //轮播图类
        function Carousel(JSON){
            this.$dom = $("#" + JSON.id); //DOM元素
            this.$imagesUl = null;
            this.$imagesUlLis = null;
            this.width = JSON.width;
            this.height = JSON.height;
            this.$leftBtn = null;
            this.$rightBtn = null;
            this.$circleOl = null;
            this.$circleLis = null;
            this.interval = JSON.interval;
            this.speed = JSON.speed; //滑动速度
            this.idx = 0;//信号量
            this.imagesURLArr = JSON.images;//图片地址数组
            this.pictureLength = JSON.images.length;//图片长度
            this.init();
            this.bindEvent();
            this.autoPlay(); //定时器
        }
        //初始化DOM
        Carousel.prototype.init = function(){
            //创建ul节点
            this.$imagesUl = $("<ul></ul>");
            this.$dom.append(this.$imagesUl);
            //创建li节点
            for(var i = 0; i < this.pictureLength; i++) {
                $("<li><img src='"+this.imagesURLArr[i].picurl+"'/></li>")
    .appendTo(this.$imagesUl);
            };
            //获得li元素引用
            this.$imagesUlLis = this.$imagesUl.find("li");
            //大盒子的布局
            this.$dom.css({
                "width" : this.width,
                "height" : this.height,
                "position" : "relative",
                "overflow" : "hidden"
            });
            //猫腻,让所有li藏起来(left移动到显示区域外)
            this.$imagesUlLis.css({
                "position" : "absolute",
                "left": this.width,
                "top": 0
            });
        //只显示第一张图
            this.$imagesUlLis.eq(0).css("left",0);
            //创建按钮
            this.$leftBtn = $("<a href='javascript:;' class='leftBtn'></a>");
            this.$rightBtn = $("<a href='javascript:;' class='rightBtn'></a>");
            this.$leftBtn.appendTo(this.$dom);
            this.$rightBtn.appendTo(this.$dom);
            //创建小圆点
            this.$circleOl = $("<ol class='circls'></ol>");
            this.$circleOl.appendTo(this.$dom);
            for (var i = 0; i < this.pictureLength; i++) {
                $("<li></li>").appendTo(this.$circleOl);
            };
            //获得ol的li元素
            this.$circleLis = this.$circleOl.find("li");
            //加cur
            this.$circleLis.eq(0).addClass("cur");
        }
    })();

    事件监听方法:

    Carousel.prototype.bindEvent = function(){
        var self = this;
        //右边按钮的监听
        this.$rightBtn.click(function(){
            if(self.$imagesUlLis.is(":animated")) return;
            self.showNext();
        });
        //左边按钮的监听
        this.$leftBtn.click(function(){
            if(self.$imagesUlLis.is(":animated")) return;
            self.showPrev();
        });
    }

     showNext() 显示下一张方法

    //展示下一张
    Carousel.prototype.showNext = function(){
        this.$imagesUlLis.eq(this.idx).animate({"left" : -this.width},this.speed);
        this.idx++;
        if(this.idx > this.pictureLength - 1){
            this.idx = 0;
        }
        this.$imagesUlLis.eq(this.idx).css("left",this.width).animate({"left" : 0},this.speed);
        //圆点的cur
        this.changeCirclesCur();
    }

     changeCirclesCur()小圆点方法

    Carousel.prototype.changeCirclesCur = function(){
        this.$circleLis.eq(this.idx).addClass("cur").siblings().removeClass("cur");
    }

     showPrev() 显示上一张方法

    //展示上一张
    Carousel.prototype.showPrev = function(){
        this.$imagesUlLis.eq(this.idx).animate({"left" : this.width},this.speed);
        this.idx--;
        if(this.idx < 0){
            this.idx = this.pictureLength - 1;
        }
        this.$imagesUlLis.eq(this.idx).css("left",-this.width).animate({"left" : 0},this.speed);
        //圆点的cur
        this.changeCirclesCur();
    }
    //自动轮播
    Carousel.prototype.autoPlay = function(){
        var self = this;
        this.timer = setInterval(function(){
            self.showNext();
        },this.interval);
    }

    bindEvent()

    Carousel.prototype.bindEvent = function(){
        var self = this;
        //鼠标停表
        this.$dom.mouseenter(function(){
            clearInterval(self.timer);
        });
    //离开开启
        this.$dom.mouseleave(function(){
            self.autoPlay();
        });
    //圆点的监听
    this.$circleLis.click(function(){
        self.show($(this).index());
    });
    }
    //小圆点点击展示任意
    Carousel.prototype.show = function(number){
        var old = this.idx; //旧idx信号量
        this.idx = number;    //当前点击的信号量,改变全局
        //判断
        if(this.idx > old){ //从右到左
            this.$imagesUlLis.eq(old).animate({"left" : -this.width},this.speed);
            this.$imagesUlLis.eq(this.idx).css("left",this.width).animate({"left" : 0},this.speed);
        }else if(this.idx < old){//从左到右
            this.$imagesUlLis.eq(old).animate({"left" : this.width},this.speed);
            this.$imagesUlLis.eq(this.idx).css("left",-this.width).animate({"left" : 0},this.speed);
        }
        //圆点的cur
        this.changeCirclesCur();
    }

    二、俄罗斯方块游戏开发

    2.1先认识方块

    俄罗斯方块一共有7种:SZJLOIT

    2.2写二维数组的JSON表(表示砖块)

    首先做两种图形:

    // S Z J L O I T

    var block_json = {
        "I":[ //I有2种方向
            [
                [0,1,0,0],
                [0,1,0,0],
                [0,1,0,0],
                [0,1,0,0]
            ],
            [
                [0,0,0,0],
                [0,0,0,0],
                [1,1,1,1],
                [0,0,0,0]
            ]
        ],
        "L":[ //L有4种方向
            [
                [0,1,0,0],
                [0,1,0,0],
                [0,1,1,0],
                [0,0,0,0]
            ],
            [
                [1,1,1,0],
                [1,0,0,0],
                [0,0,0,0],
                [0,0,0,0]
            ],
            [
                [1,1,0,0],
                [0,1,0,0],
                [0,1,0,0],
                [0,0,0,0]
            ],
            [
                [0,0,1,0],
                [1,1,1,0],
                [0,0,0,0],
                [0,0,0,0]
            ]
        ],
        "J":[//J有4种方向
            [
                [0,1,0,0],
                [0,1,0,0],
                [1,1,0,0],
                [0,0,0,0]
            ],
            [
                [1,0,0,0],
                [1,1,1,0],
                [0,0,0,0],
                [0,0,0,0]
            ],
            [
                [1,1,0,0],
                [1,0,0,0],
                [1,0,0,0],
                [0,0,0,0]
            ],
            [
                [1,1,1,0],
                [0,0,1,0],
                [0,0,0,0],
                [0,0,0,0]
            ]
        ],
        "O":[ //O有1种方向
            [
                [1,1,0,0],
                [1,1,0,0],
                [0,0,0,0],
                [0,0,0,0]
            ]
        ],
        "Z":[ //Z有2种方向
            [
                [1,1,0,0],
                [0,1,1,0],
                [0,0,0,0],
                [0,0,0,0]
            ],
            [
                [0,0,1,0],
                [0,1,1,0],
                [0,1,0,0],
                [0,0,0,0]
            ]
        ],
        "S":[ //S有2种方向
            [
                [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]
            ]
        ],
        "T":[//T有4种方向
            [
                [1,1,1,0],
                [0,1,0,0],
                [0,0,0,0],
                [0,0,0,0]
            ],
            [
                [0,1,0,0],
                [1,1,0,0],
                [0,1,0,0],
                [0,0,0,0]
            ],
            [
                [0,1,0,0],
                [1,1,1,0],
                [0,0,0,0],
                [0,0,0,0]
            ],
            [
                [0,1,0,0],
                [0,1,1,0],
                [0,1,0,0],
                [0,0,0,0]
            ]
        ]
    }
    数组图形

    2.3基本布局【table表格(12*20)】

    都是套路,和贪吃蛇没区别。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8" />
        <title>Document</title>
        <style type="text/css">
            table{
                margin:50px auto;
            }
            table,tr,td{border: 1px solid #000;border-collapse:collapse;}
            td{width: 18px;height: 18px;}
        </style>
    </head>
    <body>
        <div id="app"></div>
    </body>
    <script type="text/javascript" src="js/Game.js"></script>
    <script type="text/javascript" src="js/Block.js"></script>
    <script type="text/javascript">
        var game = new Game()
    </script>
    </html>

    循环创建12*20table表格,原因:为了方块能居中。

    (function(){
        window.Game = function(){
            this.init()
        }
    
        //20 * 12创建表格
        Game.prototype.init = function(){
            this.dom = document.createElement('table');
            document.getElementById("app").appendChild(this.dom);
    
            var tr,td;
            //循环插入行
            for(var i = 0;i < 20;i++){
                tr = document.createElement('tr');
                this.dom.appendChild(tr);
                for(var j = 0;j < 12;j++){
                    //循环插入列
                    td = document.createElement('td');
                    tr.appendChild(td);
    
                }
            }
        }
    })();
    //如果别的类修改Game类的表格颜色,尽量提供一个方法给其他类调用,不要让其他类修改自己的属性
    //设置table表格的颜色
    Game.prototype.setClass = function(row, col, classname){
        this.dom.getElementsByTagName('tr')[row].getElementsByTagName('td')[col].className = 
    classname
    }

    index.html中写两个类:

    .L{background: skyblue;}
    .I{background: pink;}

    (function(){
        window.Block = function(){
            //在所有的形状中,选择一个砖块形状
            var arr = ["I","L","J"];
            this.allType = arr[~~(Math.random() * arr.length)]
            console.log(this.allType)
            //自己所有的方向个数
            this.allDirectionNumber = block_json[this.allType].length;
            //随意一个方向
            this.direction = ~~(Math.random() * this.allDirectionNumber);
    
            //得到形状,马上渲染图形的而进行code码
            this.code = block_json[this.allType][this.direction];
    
            //4 * 4小方块的初始位置
            this.row = 0;
            this.col = 4; //保证方块从中间出现
        }
    })();


    2.4砖块渲染

    (function(){
        window.Block = function(){
             ...
        }
    
        //渲染砖块
        Block.prototype.render = function(){
            for(var i = 0; i < 4;i++){
                for(var j = 0; j < 4;j++){
                    //显示4 * 4矩阵颜色,写class类
                    game.setClass(this.row + i, this.col + j, "gray");
                    if(this.code[i][j] == 1){
                        //如果4 * 4 二维数组编码中有1就渲染颜色,0就没色
                        game.setClass(this.row + i, this.col + j, this.allType)
                    }
                }
            }
        }
    })();

    别忘记在Game类中添加定时器并render block(渲染方块)

    (function(){
        window.Game = function(){
            this.init();
            this.start();
            //实例化砖块类
            this.block = new Block();
        }
    
        Game.prototype.start = function(){
            var self = this;
            setInterval(function(){
                //渲染砖块
                self.block.render();
            },30);
        }
    })();


    2.5砖块下落

    //砖块下落
    Block.prototype.down = function(){
        this.row++;
    }
    
    //清屏方法
    Game.prototype.clearClass = function(){
        for(var i = 0; i < 20;i++){
            for(var j = 0; j < 12;j++){
                game.setClass(i, j, "");
            }
        }
    }
    Game.prototype.start = function(){
        this.f = 0;
        var self = this;
        setInterval(function(){
            self.f++;
            //清屏
            self.clearClass()
            //渲染砖块
            self.block.render();
            //每间隔20帧下落
            self.f % 20 == 0 && self.block.down();
        },30);
    }

    砖块就能下落了


    2.6 Map地图类

    Map地图类存储死亡的方块

    (function(){
        window.Map = function(){
            this.code = [
                [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]
            ]
        }
    })()
    地图

    for循环更优雅的创建二维数组

    this.code = (function(){
        var arr = [];
        for(var i = 0;i < 20;i++){
            arr.push([]);
            for(var j = 0;j < 12;j++){
                arr[i].push(0)
            }
        }
        return arr;
    })();

     

    ES6语法,写一个二维数组:

    new Array(20).fill(new Array(12).fill(0)
    (function(){
        window.Map = function(){
            this.code = (function(){
                var arr = [];
                for(var i = 0;i < 20;i++){
                    arr.push([]);
                    for(var j = 0;j < 12;j++){
                        arr[i].push(0)
                    }
                }
    
                //写一个“一柱擎天”方便测试
                arr[10][5] = "L";
                arr[11][5] = "L";
                arr[12][5] = "L";
                arr[13][5] = "L";
                arr[14][5] = "L";
                arr[15][5] = "L";
                arr[16][5] = "L";
                arr[17][5] = "L";
                arr[18][5] = "L";
                arr[19][5] = "L";
    
                return arr;
            })();
    
            console.log(this.code)
        }
    })()

    Map地图类渲染:

    //地图渲染
    Map.prototype.render = function(){
        for(var i = 0;i < 20; i++){
            for(var j = 0;j < 12; j++){
                //如果地图中二维数组中有非0的,就渲染方块
                if(this.code[i][j] != 0){
                    game.setClass(i, j, this.code[i][j])
                }
            }
        }
    }


    2.7下落的砖块卡住判断

    看下一行能不能进取决于两个条件:

    1、地图类的下一行不能是非0

    2、方块的下一行不能是1

    //检测碰撞,提供check方法,返回值true或false
    Block.prototype.check = function(row,col){
        for(var i = 0; i < 4; i++){
            for(var j = 0; j < 4; j++){
                if(this.code[i][j] != 0 && game.map.code[row + i][col + j] != 0){
                    return false; //如果不能进,返回false
                }
            }
        }
        return true; //能进返回true
    }
    //砖块下落
    Block.prototype.down = function(){
        //调用check方法,如果为真就继续row++往下落
        console.log(this.check(this.row+1,this.col))
        if(this.check(this.row+1,this.col)){
            this.row++;
        }
    }

    到这来碰撞检测完成。

    当删除测试的“一柱擎天”后,block下落到底的时候,报错了,因为下标越界了,map类最下面没有非0code码,检测block.check方法中循环不到第ij列没有非0的值了。

     

    解决办法:手动在最后补一行非0的数组值即可。

    arr.push([1,1,1,1,1,1,1,1,1,1,1,1]);
    
    arr.push(Array(12).fill(1));


    2.8添加键盘事件监听

    //键盘事件监听
    Game.prototype.BindEvent = function(){
        var self = this;
        document.onkeyup = function(event){
            if(event.keyCode == 37){
                self.block.left();
            }else if(event.keyCode == 38){
                self.block.rotate();
            }else if(event.keyCode == 39){
                self.block.right();
            }else if(event.keyCode == 40){
                self.block.goDown();
            }
        }
    }
    
    //向左
    Block.prototype.left = function(){
        if(this.check(this.row,this.col-1)){
            this.col--;
        }
    }
    // 向右
    Block.prototype.right = function(){
        if(this.check(this.row,this.col+1)){
            this.col++;
        }
    }
    //一键到底
    Block.prototype.goDown = function(){
        while(this.check(this.row+1,this.col)){
            this.row++;
        }
    }
    键盘监听

    可以左右、向下控制砖块了。

    只要碰到map中的死尸砖块就添加。

    //添加死亡方块
    Block.prototype.addDie = function(){
        for(var i = 0; i < 4;i++){
            for(var j = 0; j < 4;j++){
                // console.log(this.row+i,this.col+j)
                if(this.code[i][j] != 0){
                    //如果不是0表示有颜色(有砖块)
                    //将随机出来的字母类名,写在地图类的code中
                    game.map.code[this.row + i][this.col + j] = this.allType;
                }
            }
        }
    }
    //砖块下落
    Block.prototype.down = function(){
        //调用check方法,如果为真就继续row++往下落
        if(this.check(this.row+1,this.col)){
            this.row++;
        }else{
            //如果为假,表示碰到非0的砖块了,将自己添加到map地图类中
            this.addDie();
            //同时new一个新的砖块出来
            game.block = new Block();
        }
    }

    2.10旋转

    //旋转
    Block.prototype.rotate = function(){
        //备份旧方向
        var oldDirection = this.direction;
        //如果旋转的值已经等于自己方向的个数,就回到0,重新翻转
        if(this.direction == this.allDirectionNumber - 1){
            this.direction = 0;
        }else{
            // 否则继续加,可以旋转
            this.direction++;
        }
        //得到自己的方向下标后,马上渲染图形的二维数组的code码
        this.code = block_json[this.allType][this.direction];
        if(!this.check(this.row,this.col)){
            //已经碰到了
            //如果不可以旋转,就撤回来
            this.direction = oldDirection
            //改为刚刚随机出来的旧方向。
            this.code = block_json[this.allType][this.direction];
        }
    }

    2.11消行判断

    //消行判断
    Block.prototype.remove = function(){
        //判断map地图类中的code中某一行是不是没有0,如果没有0,就消行
        for(var i = 0;i < 20;i++){
            if(!game.map.code[i].includes(0)){
                //如果没有0,就删除行
                game.map.code.splice(i,1);
                //删除行之后,再重新在头部填充一行全0的
                game.map.code.unshift(new Array(12).fill(0));
            }
        }
    }
    //砖块下落
    Block.prototype.down = function(){
        //调用check方法,如果为真就继续row++往下落
        if(this.check(this.row+1,this.col)){
            this.row++;
        }else{
            //如果为假,表示碰到非0的砖块了,将自己添加到map地图类中
            this.addDie();
            //同时new一个新的砖块出来
            game.block = new Block();
            //没碰到一次检测是否需要消行
            this.remove();
        }
    }

    2.12游戏结束判断

    //砖块下落
    Block.prototype.down = function(){
        //判断数组的第0行,有没有不等于0的项,如果有,游戏结束
        game.map.code[0].forEach(function(item){
            if(item != 0){
                clearInterval(game.timer);
                alert`游戏结束`;
            }
        });
        //调用check方法,如果为真就继续row++往下落
        if(this.check(this.row+1,this.col)){
            this.row++;
        }else{
            //如果为假,表示碰到非0的砖块了,将自己添加到map地图类中
            this.addDie();
            //同时new一个新的砖块出来
            game.block = new Block();
            //没碰到一次检测是否需要消行
            this.remove();  
        }
    }

    2.13添加音效和美化

    <html>
    <head>
        <style type="text/css">
            *{margin: 0;padding: 0;}
            body{
                height: 100%;
                background: url(img/bg.jpg) no-repeat 0 0;
                background-size:cover;
            }
            table{
                margin:50px auto;
                background: rgba(0, 0, 0,0.5);
            }
            table,tr,td{
                border: 1px solid #000;
                border-collapse:collapse;
            }
            td{
                 20px;
                height: 20px;
            }
            .L{ background: linear-gradient(to right bottom, #800080, #ffc0cb);}
            .I{ background: linear-gradient(to right bottom, #00f260, #0575e6);}
            .S{ background: linear-gradient(to right bottom, #fc4a1a, #f7b733);}
            .Z{ background: linear-gradient(to right bottom, #22c1c3, #fdbb2d);}
            .J{ background: linear-gradient(to right bottom, #ff9966, #ff5e62);}
            .O{ background: linear-gradient(to right bottom, #7f00ff, #e100ff);}
            .T{ background: linear-gradient(to right bottom, #c0392b, #8e44ad);}
            .B{ background:yellow; }
            .A{ background:yellowgreen; }
            h1,h2{color:#fff;text-align:center;}
        </style>
    </head>
    <body>
        <audio src="audio/bg.wav" autoplay id="bg"></audio>
        <audio src="audio/一键到底.wav" id="goDown"></audio>
        <audio src="audio/旋转.wav" id="rotate"></audio>
        <audio src="audio/移动.wav" id="move"></audio>
        <audio src="audio/消行.wav" id="goDie"></audio>
        <h1 id="score"></h1>
        <h2 id="info"></h2>
        <div id="app"></div>
    </body>
    </html>
    <script type="text/javascript" src="js/Block_json.js"></script>
    <script type="text/javascript" src="js/Game.js"></script>
    <script type="text/javascript" src="js/Block.js"></script>
    <script type="text/javascript" src="js/Map.js"></script>
    <script type="text/javascript">
         document.getElementById("bg").volume = 0.2;
         var game = new Game();
    </script>
    HTML

     

    //主循环,游戏定时器
    Game.prototype.start = function(){
        var self = this;  
        this.f = 0;
        this.score = 0;
        this.timer = setInterval(function(){
            self.f++;
            document.getElementById("info").innerHTML = "帧编号:"+ self.f;
            document.getElementById("score").innerHTML = "分数:"+ self.score;
            //先清屏,再渲染
            self.clearClass();
            //渲染小方块
            self.block.render();
            //每隔20帧,方块下落
            self.f % 30 == 0 && self.block.down();
            //地图方块渲染
            self.map.render();
        },20);
    }

    音效:

    //旋转
    Block.prototype.rotate = function(){
        document.getElementById("rotate").play();
    }
    //一键下落
    Block.prototype.goDown = function(){
        document.getElementById("goDown").play();
    }
    //向左
    Block.prototype.left = function(){
        document.getElementById("move").play();
    }
    //向右
    Block.prototype.right = function(){
        document.getElementById("move").play();
    }
    //消行判断、加分
    Block.prototype.remove = function(){
        //判断map类中的code中某一行是不是没有0,如果没有0,就消行
        for (var i = 0; i < 20; i++) {
            if(!game.map.code[i].includes(0)){
                game.score++;
                document.getElementById("goDie").play();
            }
        };
    }

  • 相关阅读:
    剑指offer:2.二维数组的查找(Java版)
    剑指offer:1.找出数组中重复的数(java版)
    Java自动内存管理机制学习(二):垃圾回收器与内存分配策略
    Java自动内存管理机制学习(一):Java内存区域与内存溢出异常
    Java并发编程学习:线程安全与锁优化
    Java并发编程学习:volatile关键字解析
    Java 8之重新认识HashMap
    【转】java内部类的作用分析
    不能进入String.class调试
    SCJP考试题310-025(第二套<4>)92-147/147
  • 原文地址:https://www.cnblogs.com/Javastudy-note/p/13812633.html
Copyright © 2020-2023  润新知