超详细利用原生 js实现别踩白块小游戏

超详细利用原生 js实现别踩白块小游戏

先上效果图

首先这是针对于初学者的js联系,大神可以路过。

开始界面:
超详细利用原生 js实现别踩白块小游戏
游戏界面:
超详细利用原生 js实现别踩白块小游戏

原理

实现这个小游戏的原理非常简单,以下用直接上图解释:
超详细利用原生 js实现别踩白块小游戏
这里我们将wrap设置为400 x 600 ,main是装方块的容器,大小和wrap一样,分为四列四行。最开始我们利用绝对定位将它的top设置为-150px,也就是将最前面一行提前。
通过改变定时器改变main的top值使得main向下运动。如果第一行的位置已经到达了0px的位置,这时候,我们就要重新生成一行新的,并且每一行有四个div。我们利用for循环生成。在生成的同时我们也应该将整个main容器的位置回到原来-150px的位置。好了,这就是原理的大概。

html代码

html的结构比较简单。我们需要的一个标题,就是游戏名,一个div就可以了。
然后是容器wrap ,这里面有开始按钮go,方块容器main。
下方还有显示分数的countShow。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>别踩白块</title>
    <link rel="stylesheet" href="css/style.css">
</head>

<body>
    <div id="gameName">不要踩到白块哦~</div>
    <div class="wrap">
        <div class="go">
            <a href="###">开始 游戏</a>
        </div>
        <div class="main"></div>
    </div>
    <p class="count">当前分数:</p>
    <p class="countShow"></p>
    <script src="js/index.js"></script>
</body>

</html>

css代码

css最重要的就是设置定位的问题。我们需要的是包含方块的main相对于wrap的位置进行移动。所以我们将wrap设置为position:relative,main设置为position:absolute;
实现方块的时候,用到了css3的box-sizing,这样我们在设置边框就是不需要考虑内容区的大小。

 * {
     margin: 0;
     padding: 0;
     text-decoration: none;
 }

 body {
     background: #777;
 }

 #gameName {
     font-size: 40px;
     margin-top: 60px;
     text-align: center;
 }

 .wrap {
     margin: 30px auto;
     background: #fff;
     width: 400px;
     height: 600px;
     border: 5px solid #000;
     position: relative;
     overflow: hidden;
     border-radius: 4px;
     cursor:pointer;
 }

 .go {
     position: absolute;
     z-index: 333;
     font-size: 60px;
     text-align: center;
     line-height: 100px;
     width: 100%;
     height: 100px;
     border-bottom: 2px dashed #333;
 }

 .go a {

     color: red;
     display: inline-block;
 }

 .main {
     position: absolute;
     width: 100%;
     height: 600px;
     position: absolute;
     top: -150px;
 }

 .main .row {
     width: 100%;
     height: 150px;
 }

 .row div {
     float: left;
     background: #fff;
     width: 100px;
     height: 150px;
     border: 1px solid #333;
     box-sizing: border-box;
 }

 .count {
     text-align: center;
     font-size: 33px;
 }

 .countShow {
     text-align: center;
     font-size: 44px;
     color: red;
 }

js代码

以下的js代码,每一行我都加了详细的注释,根据我的说明一步一步看

首先是点击开始按钮

//获取元素
var go = document.querySelector('.go');  //开始按钮
var main = document.querySelector(".main"); // 方块的容器
var timer = null; //定时器
var speed = 5;  //设定的速度
var count = 0;  //积分器
var flag = true;  //加锁
var countShow = document.querySelector(".countShow");  //分数显示
var color = ["black", "black", "black", "black"];  //颜色数组


function goStart() {
	//给开始按钮绑定事件
    go.addEventListener("click", function() {
        this.style.display = "none";
        cDiv();//点击开始按钮立刻在第一行创建一行
        move(); //容器移动
        console.log(main.offsetTop)
    })
}
goStart();




function move() {
    clearInterval(timer); //移动前先清除已有定时器
    timer = setInterval(function() {

    	//改变top值使得容器开始向下移动
        main.style.top = parseInt(main.offsetTop) + speed + "px";
        if (parseInt(main.offsetTop) >= 0) { //如果第一行的top值已经到达0的位置,则在第一行新创建一行,并且将容器重新拉回原来开始的位置 
            cDiv();
            console.log(main.offsetTop)
            main.style.top = "-150px";
        }
        var len = main.childNodes.length;
        if (len == 6) { //如果容器有6个节点,说明最后一行已经超出了容器。第一行也已经生成
            for (var i = 0; i < 4; i++) {
            	//判断每一行的每一个节点看是否它的类名列表里有"i";有的话清除定时器,弹出分数
                if (main.childNodes[len - 1].childNodes[i].classList.contains("i")) {
                    clearInterval(timer);
                    flag = false;   //游戏结束,flag赋值为false
                    alert("你的分数是:" + count);
                }
            }
            console.log("正在移出最后一个div");
            //将超出容器的最后一行移除
            main.removeChild(main.childNodes[len - 1]);
        }
    }, 30);
    bindEvent();
}



//创建行和列
function cDiv() {

    var oDiv = document.createElement("div");
    oDiv.className = "row";//创建行,并且给行设定一个row类名
    for (var i = 0; i < 4; i++) {
        var iDiv = document.createElement("div");
        oDiv.appendChild(iDiv); //for循环,创建4个div ,每创建一个div就塞进每行
    }


    if (main.childNodes.length == 0) { //如果当前main,没有div。那就直接插入
        console.log("现在我是第一个div")
        main.appendChild(oDiv);
    } else {    
        console.log("正在在第一个位置插入")
        main.insertBefore(oDiv, main.childNodes[0]);  //如果已经有了行,就在最前面的那一行插入  insertBefore(newNode,site);
    }
    var index = Math.floor(Math.random() * 4);  //随机生成0 1 2 3
    var clickDiv = main.childNodes[0].childNodes[index];    //将要点击的方块随机生成
    clickDiv.className = "i";  //点击的方块给一个类名 i
    clickDiv.style.backgroundColor = color[index];    //给点击的方块添加随机的颜色
}




//给每一个div绑定事件,利用事件委托
function bindEvent() {
    main.addEventListener('click', function(event) {
        var tar = event.target;
        if (flag == true) {  //这里加锁,游戏开启前flag 为true ,如果游戏结束了则赋值为false
            if (tar.className == "i") {  //点击到类名为"i"的方块,背景颜色改变,并且将类名"i"移除
                tar.style.backgroundColor = "#bbb";
                tar.classList.remove("i");
                count++;
                console.log("分数正在加1")
                countShow.innerHTML = count;  //分数显示
                if (count % 10 == 0) {    //如果分数是10的倍数,速度+1
                    speed++;
                }
            } else if(!tar.classList.contains("main")){ //  如果你点击的不是容器,才让空白的方块颜色改变。并且清除定时器,弹出弹出框
            	console.log(this)
                tar.style.backgroundColor = "red";
                clearInterval(timer);
                setTimeout(function() { //这里定时器解决执行先后的问题,让方块的颜色先变为red再弹出弹出框
                    alert("游戏结束,你的分数是:" + count);
                }, 500)

                flag = false;  //游戏结束赋值为false
            }
        }
        console.log("你的分数是:" + count);

    })
}

总结

以上案例,都是js最基本的内容。例如节点的增、删、改、查,还有对运动的理解。定时器的使用,条件判断语句等。还有一点非常重要,那就是代码的逻辑性。要先思考问题的存在,才用代码去解决问题。这点相当重要,希望以上内容对你的学习有帮助。