原生js实现别踩白块

1. 实现效果

在这里插入图片描述

2. 知识点总结
  1. 最后一行元素的移除时
    removeChild:通过父节点对象调用,用于除去父节点中的指定子节点
    调用方法为: main.removeChild(main.childNodes[len - 1]);

    removeNode:被除去节点调用,去除某个节点
    remove:被除去节点调用,去除某个节点
    调用方法为:main.childNodes[len - 1].remove();

  2. 浏览器关闭事件 window.close();
    浏览器重启事件 window.location.reload(true);

  3. offsetTop:元素相对于父元素的高,只能读取,不能设置,没有单位,如果父元素没有设置相对定位,则元素的offset是相对于浏览器的而言的

和style属性的区别:
无论元素有没有设置定位,offset属性都可以返回位置,而style属性不行,只有定位后才能获取

3. 实现功能
  1. 点击游戏开始按钮后从上至下出现钢琴块,开始按钮隐藏
  2. 游戏失败后显示弹框:得分,选择退出游戏(关闭浏览器)或者重新开始(刷新浏览器)
  3. 分数每达到10的倍数则加速
4. 设计思路
  1. 声明变量
    var main = document.getElementById('main');
    var go = document.getElementById('go');
    var score = document.getElementsByClassName('score')[0];
    var restart = document.getElementsByClassName('restart')[0];
    var buttonExit = document.getElementsByClassName('exit')[0];
    var buttonAgain = document.getElementsByClassName('again')[0];

    var speed1 =6;/*控制移动速度*/
    var speed2 =100;
    var num = 0;/*分数*/
    var timer = null;
    var flag = true;/*是否可以点击*/
  1. 创建元素

创建 行元素 div,每行四个div,之后动态添加行
随机数(0-4)设置变色块(需要点击的),并添加类名称方便之后调用

    // 创建每一行div元素
    function creatDiv() {
        var rowDiv = document.createElement('div');
        rowDiv.className = "row";
        for (var j = 0; j < 4; j++) {
            var inDiv = document.createElement('div');
            rowDiv.appendChild(inDiv);
        }
        //    插入新生成的行
        main.insertBefore(rowDiv, main.childNodes[0]);
        var index = Math.floor(Math.random() * 4); // 根据随机数 设置一行中有颜色的div
        var clickDiv = main.childNodes[0].childNodes[index];
        clickDiv.className = "need";
        clickDiv.style.backgroundColor = "black";// 设置上背景颜色
    }
  1. 移动

1.主要问题在于控制main部分元素向下移动,利用offsetTop可以获取动态的值(-150+speed—— -5 +speed),而main里每行元素的高度为150px,每新加一行元素,top的值随之改变,从而实现内容下移
2. 当检测到当前main区域里有6(可视区域4+生成最新的一行+触底后的一行)行时删除最后一行
3)计时器也可以通过刷新来控制速度

    // 移动
    function move() {
        timer = setInterval(function () {
            // 利用top值移动main区域
            var step = parseInt(main.offsetTop) + speed;
            console.log(main.offsetTop);
            main.style.top = step + 'px';
            // 如果main区域移动到可视区域 创建一行新的元素
            if (parseInt(main.offsetTop) >= 0) {
                creatDiv();
                // 同时将main区域移动到可视区域上方
                main.style.top = '-150px';
            }
            // 获得mian区域内的行数
            var len = main.childNodes.length;
            if (len == 6) {
                // 遍历最后一行的每一个div
                for (var i = 0; i < 4; i++) {
                    // 如果其中有一个包含没有被点击的   游戏结束
                    if (main.childNodes[len - 1].children[i].className == "need") {
                        score.innerHTML=num;
                        restart.style.display="block";
                        clearInterval(timer);
                        // 游戏结束后不可以继续点击
                        flag = false;
                    }
                }
                // 将展示过后的每一行移除
                /*main.removeChild(main.childNodes[len - 1]);*/
                main.childNodes[len - 1].remove();
            }
        }, speed2)
        // 点击事件
        bindEvent();
    }
  1. 点击事件

如果选中黑色则计数器+1;如果选择其他区域背景色变为红色,flag修改为false,显示弹框(display:block
监听事件监听click,并获取当前点击的对象

  function bindEvent() {
        // 给main添加点击事件
        main.addEventListener('click', function (event) {
            // 根据flag值判断是否可以点击
            if (flag) {
                // 获得到点击的源事件
                var tar = event.target;
                // 判断点击的块是否为有颜色的
                if (tar.className == 'need') {
                    // 改变背景颜色
                    tar.style.backgroundColor = '#999';
                    tar.className = "";
                    // 计数++
                    num++;
                } else {
                    // 如果点到了白色的块   游戏结束
                    tar.style.backgroundColor = 'red';
                    score.innerHTML=num;
                    restart.style.display="block";
                    clearInterval(timer);
                    flag = false;
                }
                // 如果当前分数为10的倍数   速度++
                if (num % 10 == 0) {
                    speed++;
                }
            }
        })
    }
  1. 开始点击后开始游戏按钮隐藏,调用move函数
 // 开始按钮点击   开始移动 创建每一行元素
    clickStart();
    function clickStart() {
        go.addEventListener('click', function () {
            go.style.display = 'none';
            move();
        });
    }
  1. 弹框按钮功能
 buttonExit.onclick=function(){
            window.close();/*浏览器关闭事件*/
        }
        /*重新开始*/
        buttonAgain.onclick=function(){
            flag=true;
            window.location.reload(true);/*浏览器重启事件*/
        }
5. 待解决bug
  1. 没有动态设置移动速度,可以在代码中修改变量speed的值
  2. 刚开始元素还未填满main的空间,点击其他部分(除钢琴块外)会使所有区域变红
    在这里插入图片描述
    html框架
<div class="wrapper">
    <div id="go"><span>Game Start</span></div>
    <div id="main"></div>
</div>
<div class="restart">
    <div>游戏结束,得分:<span class="score"></span></div>
    <button class="exit">退出游戏</button>
    <button class="again">再来一局</button>
</div>

css样式

<style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        .wrapper {
            margin: 100px auto;
            width: 400px;
            height: 600px;
            position: relative;
            border: 1px solid black;
            overflow: hidden;
        }

        #go {
            width: 100%;
            position: absolute;
            top: 0;
            text-align: center;
            z-index: 99;
        }

        #go span {
            display: block;
            height: 100px;
            width: 100%;
            color: cyan;
            border-bottom: 1px solid #000000;
            background-color: #b1b1b1;
            font-size: 60px;
            cursor: pointer;
        }

        #main {
            width: 400px;
            height: 600px;
            position: relative;
        }

        .row {
            width: 400px;
            height: 150px;
        }

        .row div {
            width:100px;
            height: 149px;
            border-left: 1px solid #222;
            border-bottom: 1px solid #222;
            float: left;
            cursor: pointer;
        }

        .restart {
            width: 500px;
            height: 200px;
            border: 1px solid #ff0000;
            position: relative;
            margin: 100px auto;
            top: -450px;
            background: #ebebeb;
            padding-top: 50px;
            display: none;
        }

        .restart div {
            font-size: 30px;
            width: 498px;
            text-align: center;
        }
        .restart button{
            width: 200px;
            height: 50px;
            border-radius: 5px;
            border: 1px solid #b1b1b1;
            outline: none;
            color: #fca298;
            font-size: 30px;
            position: absolute;
            bottom: 10px;
            cursor: pointer;
        }
        .restart button:nth-of-type(1){
            left: 30px;
        }
        .restart button:nth-of-type(2){
            right: 30px;
        }
    </style>
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值