天天看點

原生js實作别踩白塊

1. 實作效果

原生js實作别踩白塊

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的空間,點選其他部分(除鋼琴塊外)會使所有區域變紅
    原生js實作别踩白塊
    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>