zoukankan      html  css  js  c++  java
  • JS实现别踩白块小游戏

    最近有朋友找我用JS帮忙仿做一个别踩白块的小游戏程序,但他给的源代码较麻烦,而且没有注释,理解起来很无力,我就以自己的想法自己做了这个小游戏,主要是应用JS对DOM和数组的操作。


    程序思路:如图:将游戏区域的CSS设置为相对定位、溢出隐藏;两块“游戏板”上分别排布着24块方格,黑色每行随机产生一个,“游戏板”向下滚动并交替显示,将每个操作板的黑块位置存入数组,每次点击时将数组pop出来进行比对(我觉得亮点在这……)。

    这里是游戏的GitHub地址,大家可以到里点击中部菜单最右边的的Download ZIP按钮下载到桌面一试,HTML和JS,无需服务器。

    下载地址

    以下是具体实现,关键部分有注释。


    HTML部分:

    <!DOCTYPE html>
    
    <html>
    
    <head><title>别踩白块</title></head>
    
    <body>
    
    <div id="gameZone"><div id="boardb" style="position: absolute;top: 0px;"></div></div>//初始化一个boardb,使ab同时存在
    
    </body>
    
    </html>

    CSS部分:

    *{margin: 0px;padding: 0px;box-sizing: border-box;}  //简单的reset一下,并用box-sizing设置盒子尺寸将边框也计算进去,便于后面计算小方块位置
    
    #gameZone{width: 302px;height: 602px;border: 1px solid green;margin: 20px auto;position: relative;overflow: hidden;} //游戏区域,多两个像素是为了除去边框外还有足够的300*600的空间
    
    .square{width: 75px;height: 100px;float: left;border: 1px solid black;}
    
    .squareBlack{width: 75px;height: 100px;border: 1px solid black;float: left;background: black;}//每个小方块为75*100,并且设置黑色小方块的背景色。

    JS部分:

     这里分函数介绍:

    全局变量初始化

    var loc=600;//黑块落地失败判定
    
    var count=0;//初始化击中黑块总数
    
    var locArr=[];//初始化游戏板上黑块位置的
    
    var order=(function(){
    
        var ord="A";
    
        return function(){
    
        if(ord=='boarda')ord='boardb';
    
        else ord='boarda';
    
        return ord;
    
    }
    
    })()//用闭包函数使每次创建的游戏板的ID为boarda与boardb,其实用一个全局变量也行,不过为了有点逼格。。。
    
     

    每次点击判定结果的函数

    function judge(){
    
        var num=this.id.substr(3)//获取元素的ID号
    
        if(num!=locArr.pop()){  //与位置数组pop出的对比
    
            clearTimeout(timer); 
    
            alert("你的得分为:"+count+"分!");
    
            return;  //失败清除定时器,结算分数。
    
        }else{
    
            loc+=100;  
    
            this.style.background="silver";
    
            count+=1;//成功将落地标志加方格的高度,将方格背景色改变一下,击中数+1
    
        }
    
        if(count!=0&&count%15==0){
    
            clearTimeout(timer);
    
            newtimer=50-count/15*5;
    
            timer=setInterval('fall()',newtimer);
    
        }//每击中15个后将速度加快一点,这个式子可自行定义。
    
    }

    产生大框中小黑框位置的随机数,每次创建游戏板时调用此函数,根据产生数定义小黑块的位置

    function generateRand(){
    
        var numArr=[];
    
        for(var j=0;j<6;j++){
    
            var num=Math.floor(Math.random()*4)+j*4;
    
            numArr.push(num);
    
        }
    
        return numArr;
    
    }

    每次调用在游戏区域的上方生成一个待往下滚动的游戏板,并将其黑色的部分的数字PUSH进locArr中

    function drawBoard(){
    
        var temArr=generateRand();//这里应用一个临时的位置数组,为了防止两块游戏板之间的位置冲突。
    
        locArr=temArr.concat(locArr);//将临时数组相连到全局位置数组中
    
        var board=document.createElement('div');
    
        board.setAttribute('id',order());
    
        board.style.position="absolute";
    
        board.style.top='-600px';
    
        for(var i=0;i<24;i++){
    
            var ele=document.createElement('div');
    
            ele.setAttribute('id',"ele"+i);
    
            if(temArr.indexOf(i)>-1){   //判断当前创建的小方块的ID序列是否属于临时位置数组
    
                ele.setAttribute('class','squareBlack')
    
            }else{
    
                ele.setAttribute('class','square');
    
            }
    
            ele.addEventListener('click',judge,false); //给每一个小方格添加点击判定函数judge
    
            board.appendChild(ele);
    
        }
    
        var gameZone=document.getElementById('gameZone');
    
        gameZone.appendChild(board);
    
    }

    找到脚本中存在的两个游戏板,使其往下滚动

    function fall(){
    
        gameZone=document.getElementById('gameZone');
    
        var boarda=document.getElementById('boarda');//因为ab两个游戏板全局一直存在,所以不需要定义找不到时的逻辑
        var anowtop=parseInt(boarda.style.top);//因为获取到的top位置是xxxpx类型,所以用一个parseInt()将其转换为整数便于处理。     if(anowtop==595){ //这里数目为595而不是600是因为在这一帧删除后,下一帧正好600px,刚好使两块游戏板衔接完好。         gameZone.removeChild(boarda);         drawBoard();//删除游戏区域的游戏板,并在最上方新生成一个。     }     anowtop+=5;     boarda.style.top=anowtop+"px";     var boardb=document.getElementById('boardb');     var bnowtop=parseInt(boardb.style.top);     if(bnowtop==595){         gameZone.removeChild(boardb);         drawBoard();     }     bnowtop+=5;     boardb.style.top=bnowtop+"px";     loc-=5;     if(loc==0){         clearTimeout(timer);         alert("你的得分为:"+count+"分!");         return;     } //每一帧将落地判定减5,当落地判定为0时表示落地,结算分数。 }

    将主体调用写在window.onload函数里,使得页面的游戏区域加载完成后再调用函数。

    window.onload=function(){
    
        drawBoard();
    
        fall();
    
        timer=setInterval('fall()',50);
    
    }

    游戏扩展:

    增加页面UI:因为一开始的HTML特别简单,所以UI也很好修改,设置按钮,点击触发开始函数。

    改变游戏难度:修改setInterval的值,也可以对judge函数内的间隔数目进行修改,或将下落加速的表达式优化一下。

    增加比分排行等:用ajax连接服务器,在游戏结束后将结果写入数据库,并引用数据中的排行榜。

    改为街机模式:去除定时,修改judge函数,使其每次点击游戏板下落一个小方格的高度。设置总数,开始计时,结束计时。

    如果您觉得本博文对您有帮助,您可以推荐或关注我,如果您有什么问题,可以在下方留言讨论,谢谢。

  • 相关阅读:
    mysql导sql脚本
    oracle导sql脚本
    基于jdk proxy的动态代理模式
    vue组件之组件的生命周期
    vue组件之组件间的通信
    python-爬虫scrapy框架安装及基本使用
    mongdb的使用
    python-爬虫 多线程爬虫
    python-爬虫 爬虫利器BeautifulSoup
    python-爬虫lxml库
  • 原文地址:https://www.cnblogs.com/zhenbianshu/p/4985245.html
Copyright © 2011-2022 走看看