如何用JavaScript实现一个简单的小游戏FlyBird

如何用JavaScript实现一个简单的小游戏FlyBird【前言】 作为一个前端初学者,秉承着不想当老师的学生不是好学生的思想。利用空余时间将FlyBird这个曾经让人想砸手机的小游戏梳理了一下,整理成了一个小教程让大家来指点指点。

【前言】

作为一个前端初学者,秉承着不想当老师的学生不是好学生的思想。利用空余时间将FlyBird这个曾经让人想砸手机的小游戏梳理了一下,整理成了一个小教程让大家来指点指点。

image.png

【首页图】

  1. 首先我们对首页图进行分析它的构成,我们可以从中发现以下元素①背景②start按钮③大标题④小鸟⑤草地(滚动的)等五大板块。在这我们通过图片来实现,虽说用代码也能够达到这种效果,但工程量太大,我们在这不推荐。

  2. 首先先建立基本的html页面(快捷键!+tab可以快速建立基础页面)我们根据所看到的游戏封面先建立一个盒子#wrapBg用于存放背景图,设置好宽高。

         > #wrapBg
         > {
         >     height480px;
         >     width:343px;
         >     margin:0 auto;
         >     position: relative;
         >     top:100px;
         >     background-imageurl(../img/bg.jpg);
         > }
    

其中margin 0:auto 将图片在x轴上水平居中,此时对position属性用relative,为下面的其它图片定位作父元素使用,后面会提到。

  1. 在背景图中加入大标题 并对其定位,同时在其中放入小鸟图片

         >  <!--标题-->
         >         <div id="headTitle">
         >             <img src="img/bird0.png" alt="" id="headBird">
         >         </div>
    
  2. 在css中设置标题的位置,在这用absolute定位,父容器为#wrapBg盒子,则相对于父容器来定位,以此来确定标题的位置

         > #headTitle
         > {
         >     width236px;
         >     height:77px;
         >     background-imageurl(../img/head.jpg);
         >     position:absolute;
         >     left:53px;
         >     top:100px;
         > }
    

/相对于父容器进行定位。谁有relative谁就是父容器,身上有absolute也行,没有父容器就以body作为榜样来进行定位/

  1. 由于小鸟在前面写入了headTitle盒子里,所以对其进行定位在这里我们也可以用position位置来确定小鸟的位置,但在此我们使用float浮动来将其放于盒子的最右边,浮动就是脱离文档流(文档流可以理解为类似js的从上到下运行,按顺序运行),通过设置float让它去最左边或者右边,类似从排队中提出某一人让他去任意地方,我是这样理解的。

  2. 按部就班将按钮位置给定位好

         > #startBtn{
         >     width:85px;
         >     height29px;
         >     background-imageurl(../img/start.jpg);
         >     position: absolute;
         >     left:129px;
         >     top:250px;
         > }/*按钮自己天生有自带外边距,下面可以处理掉*/
         > 
    

【实现运动】 下一阶段就是让标题,鸟,翅膀还有草地进行运动

标题运动

首先我们思考,如何让标题进行上下运动 在这里我们首先想到通过变换标题位置的方式来对其进行运动,采取位置上下变换的方式来实现运动效果,在这我们使其上下移动3像素来进行来回运动。 首先我们要对标题盒子中的图片进行运动,在这里我们通过id这个属性来获取到当前的dom结构 我们定义jsHeadTitle来获取它的dom结构

var jsHeadTitle = document.getElementById(‘headTitle’);

再定义上下移动的幅度,在此我们设置为3像素

var Y = 3//上下摆动3像素  标题摆动的幅度

我们建立一个函数来实现这个效果

`           function headWave() {
            Y = Y * -1;
            jsHeadTitle.style.top = jsHeadTitle.offsetTop + Y + 'px'

         <!--------------------------分割线-------------------------!>
            //bird交替更换图片  思考怎么让鸟翅膀来回变换 应用数组下标
            jsHeadBird.src = imgArr[index++]
            if (index == 2) {
                index = 0;  //一旦index变成了2 就马上赋值为0
            }`

此函数前半段通过改变标题盒子离父类盒子的上部距离来改变其定位,我们在这里用offsetTop来获取 headTitle中top的数值,我们采取将Y值设置为相反数的方式,来实现标题的上下运动。

鸟的翅膀运动

此函数的下半部分则是让鸟的翅膀来回变动,我们这里采取将翅膀图片不断变换来实现效果。

  1. 我们先定义一个数组用于存放鸟翅膀的图片 var imgArr = ['img/bird0.png', 'img/bird1.png']

  2. 通过id来获取到当前的dom结构  var jsHeadBird = document.getElementById('headBird');

  3. 用下列代码实现,当index即数组下标等于2时,对其赋值为0,之后不断重复,以此来达到两张图片不断来回切换的效果

     `
     jsHeadBird.src = imgArr[index++]
     if (index == 2) {
       index = 0;  //一旦index变成了2 就马上赋值为0
                      }
     var headWaveTimer= setInterval(headWave, 200)`
    

在这里使用一个定时器来实现函数的定时运行

草地滚动

我们思考如何让草地产生滚动效果?让草地无限长么?那显然咱们的电脑hold不住哈,大致思路是用两张同样的草地图片在y轴固定的位置来进行来回运动。

代码实现如下,先在html中

 <div id="grassLand1"></div>  <div id="grassLand2"></div>

再回到css中对草地1和草地2对齐分别进行设置属性

> #grassLand1,#grassLand2
> {
>     width:343px;
>     height14px;
>     background-imageurl(../img/banner.jpg);
>     position: absolute;
>     top:423px;
> } 


单独拿出来设置left属性 是因为两个草地要来回滚动 所以一个没有边距,一个刚好要在外面,所以left设置为草地的宽度

>  #grassLand1
> {
>     left:0;
> }
> #grassLand2
> {
>     left:343px;
> }

草地1的left为0的原因是,#grassLand1刚好处在wrapBg当中,另一个设置距离刚好为343px,即wrapBg盒子的宽度,则它所处的位置刚好位于盒子的右部,为了使其溢出的图片不被显示,我们在这里用这行代码

 overflow: hidden;/*用于隐藏超出容器的草地*/

来隐藏溢出的草地

QQ图片20210420225014.png

(此时是溢出的草地)

同样的,我们通过id来获取当前的dom结构

 var jsGrassLand1 = document.getElementById(‘grassLand1’)  var jsGrassLand2 = document.getElementById(‘grassLand2’)

然后建立landRun函数来实现效果

>  > function landRun() {
>             //思考如何来回动 用来判断 看草地离左边的距离
>             if (jsGrassLand1.offsetLeft <= -343) {
>                 jsGrassLand1.style.left = '343px'
>             }
>             if (jsGrassLand2.offsetLeft <= -343) {
>                 jsGrassLand2.style.left = '343px'
>             }
>             jsGrassLand1.style.left = jsGrassLand1.offsetLeft - 3 + 'px'
>             jsGrassLand2.style.left = jsGrassLand2.offsetLeft - 3 + 'px'
>         }
>         setInterval(landRun, 30)同样用计时器来让函数运行,以实现效果

其中两个if语句是实现草地来回滚动的关键,我们通过获取其left值后,判断其大小是否<=-343px,根据相对位置可知,这个位置是草地刚好位于wrapBg的左边,当判断它完全滚完后,对其的left进行重新赋值放于最右边

此时 游戏的基本页面已经制作完成,那我们要进行一个完整的游戏,点击开始按钮后,原来的开始页面肯定得被游戏页面所取代才行

首先同样的,我们先拿到它

var jsStartBtn=document.getElementById(‘startBtn’)

接着创建一个函数

`        jsStartBtn.onclick=function()
        {
            jsHeadTitle.style.display='none'//css属性都要加一个style,用了none则这个容器就会消失
            jsStartBtn.style.display='none'
            //除了让上下抖动消失外,再干一个操作
            clearInterval(headWaveTimer)
            //插入小鸟到页面上
            bird.showBird(jsWrapBg)
        }
`

这个函数的作用是: 在按动按钮得时候,画面中的按钮键和标题全部消失,与此同时,我们要让新的画面出现。 在这里我们建立一个bird对象来实现

> 
> 	var bird={
>     flyTime:null,//键值对,key:value  此处留作小鸟飞翔的定时器;
>     wingTimer:null,//小鸟摆动的定时器
> 
>     div:document.createElement('div'),//此时代表它就是一个div容器了
>     showBird:function(parentobj)
>     {
>         this.div.style.width='40px'//给上面那个容器宽度设置为40px
>         this.div.style.height='28px'
>         this.div.style.background='#000'
>         parentobj.appendChild(this.div)//父容器添加一个孩子div
>     }//后面调用它时,页面上就会出现一只小鸟
> }
> 

我们需要一只鸟,在按动按钮的时候,凭空出现,会自由下落,而且翅膀还会进行扇动 在这里我们定义一个bird

> var bird = {
>   flyTime: null// 小鸟飞翔的定时器
>   wingTimer: null// 小鸟翅膀摆动的定时器
>   div: document.createElement('div'),
>   showBird: function(parentObj) {
>     this.div.style.width = '40px'
>     this.div.style.height = '28px'
>     this.div.style.backgroundImage = 'url(img/bird0.png)'
>     this.div.style.backgroundRepeat = 'no-repeat'
>     this.div.style.position = 'absolute'
>     this.div.style.left = '50px'
>     this.div.style.top = '200px'
>     this.div.style.zIndex = '1'
>     parentObj.appendChild(this.div)
>   },

设置好鸟的宽高后, 默认情况下当图片没有盒子大时, 图片会在盒子的水平或者垂直方向平铺。在本游戏中我们要的只是一只鸟,所以我们在这对bird0.png设置定位与不平铺 >  this.div.style.backgroundRepeat = ‘no-repeat’ >     this.div.style.position = ‘absolute’ >     this.div.style.left = ’50px’ >     this.div.style.top = ‘200px’

同时用z-index属性设置堆叠顺序,将bird的z-index设为正值,将其置于首位,在这大家可以了解下7阶层叠水平

image.png

具体内容自行了解,在此不作赘述。 在设置好bird0后,我们思考,这个游戏需要什么,在画面中我们可以得知小鸟在不断前进的过程中在柱子之间上下飞行,但显然如果操控小鸟在上下飞行的同时还要前进的话,用代码来实现无疑是复杂的,所以我们将其分为两部分。一部分是操控鸟的上下运动,另一部分操纵柱子的运动即可实现相对运动的效果。 在此,我们先对鸟的初速度定为0

fallSpeed: 0, // 小鸟下落的速度

接着写控制小鸟下落的函数

> flyBird: function() { // 控制小鸟下落的函数
>     bird.flyTime = setInterval(fly, 60)
>     function fly() {
>       bird.div.style.top = bird.div.offsetTop + bird.fallSpeed++ + 'px'
>       if (bird.div.offsetTop >= 395) { // 掉到地面,清除定时器
>         bird.fallSpeed = 0
>         clearInterval(bird.flyTime)
>         clearInterval(bird.wingTimer)
>       }
>       // 不让小鸟飞出界
>       if (bird.div.offsetTop < 0) {
>         bird.div.style.top = '0px'
>         bird.fallSpeed = 2
>       }
>       if (bird.fallSpeed > 12) {
>         bird.fallSpeed = 12
>       }//设定最大速度
>     }
>   },

此时我们写好了小鸟下落的函数,里面针对小鸟触地和小鸟飞出上边界两种情况分别用代码进行了设置,其中当小鸟触及上边界时,自行设置了小鸟当时的速度。 再写出控制小鸟向上飞行的函数,我们用通过在按钮点击的同时对其bird.fallSpee设置为-8的方式来控制小鸟的向上飞行,具体代码如下:

         ` bird.showBird(jsWrapBg)
            bird.flyBird()
            bird.wingWave()
            jsWrapBg.onclick=function(){
            bird.fallSpeed=-8
                }`

我们此时虽然已经可以控制小鸟的上升和下落,但是我们会发现,此时小鸟的翅膀和头部方向并不会扇动和改变,于是我们采用上文封面中小鸟翅膀扇动的方法:

` wingWave: function () {//控制小鸟扇动翅膀
        var up = ['url(img/up_bird0.png)', 'url(img/up_bird1.png)']
        var down = ['url(img/down_bird0.png)', 'url(img/down_bird1.png)']
        bird.wingTimer = setInterval(wing, 120)
        var i = 0,j=0
        function wing() {
           if(bird.fallSpeed>0){
            bird.div.style.backgroundImage = down[i++]
            if (i == 2) { i = 0 }
           }
            if (bird.fallSpeed < 0) {
             bird.div.style.backgroundImage = up[j++]
             if (j == 2) { j = 0} 
          }

        }

html中的代码实现

     var jsStartBtn = document.getElementById('startBtn')
     jsStartBtn.onclick = function() {
      jsHeadTitle.style.display = 'none'
      jsStartBtn.style.display = 'none'
      clearInterval(headWaveTimer)
      // 插入小鸟到页面中
      bird.showBird(jsWrapBg)
      bird.flyBird()
      bird.wingWave()
      jsWrapBg.onclick = function() {
        bird.fallSpeed = -8//用于设置点击鼠标时,小鸟上升的效果
      }

做完上述的几步之后,我们小鸟的翅膀和头部就可以随着上下的飞动而发生改变。接下来就是为游戏设置管道了,为了游戏的趣味性我们对管道的长度设置随机。

QQ图片20210425140455.png

    var baseObj={
        randomNum:function(min,max){
            return Math.random()*(max-min+1)+min //设置随机数
            return parseInt(Math.random()*(max-min+1)+min)//对它进行取整
        }
    }

接下来让函数拿到随机数对上管道与下管道的长度和间隙进行设置

function Block(){
    this.upDivWrap=null
    this.downDivWrap=null
    this.downHeight=baseObj.randomNum(0,150)//设置0到150之间的高度
    this.gapHeight=baseObj.randomNum(150,160)//设置管道间隙
    this.upHeight=312-this.downHeight-this.gapHeight//上方管道长度

接着我们声明一个方法用于生成管道

this.createDiv=function(url,height,positionType){
        var newDiv=document.createElement('div')
        newDiv.style.width='62px'
        newDiv.style.height=height
        newDiv.style.position=positionType
        newDiv.style.left=left
        newDiv.style,top=top
        newDiv.style.backgroundImage=url
        return newDiv

然后写入值,生成管道

this.creatBlock=function(){
        var upDiv1=this.createDiv('url(img/up_mod.png',this.upHeight+'px')
        var upDiv2=this.createDiv('url(img/up_pipe.png','60px')
        this.upDivWrap=this.createDiv(null,null,'absolute','450px')
        this.upDivWrap.appendChild(upDiv1)
        this.upDivWrap.appendChild(upDiv2)
        jsWrapBg.appendChild(this.upDivWrap)
    }

接着就是在html中调用他们。使其实例化,生成管道。

 var b = new Block() // 实例化
      b.createBlock()
    

接着对管道的运动进行设置

this.moveBlock = function () {
    this.upDivWrap.style.left = this.upDivWrap.offsetLeft - 3 + 'px'
    this.downDivWrap.style.left = this.downDivWrap.offsetLeft - 3 + 'px'
  }
}

接着咱们在js中写入判断相撞的代码

// 判断两个矩形是否发生碰撞
  rectangleCrashExamine: function (obj1, obj2) {
    var obj1Left = obj1.offsetLeft
    var obj1Width = obj1.offsetLeft + obj1.offsetWidth
    var obj1Top = obj1.offsetTop
    var obj1Height = obj1.offsetTop + obj1.offsetHeight

    var obj2Left = obj2.offsetLeft
    var obj2Width = obj2.offsetLeft + obj2.offsetWidth
    var obj2Top = obj2.offsetTop
    var obj2Height = obj2.offsetTop + obj2.offsetHeight

    if (!(obj1Left > obj2Width || obj1Width < obj2Left || obj1Top > obj2Height || obj1Height < obj2Top)) {
      return true
    }
    return false
  }
} 

写到这里大致就结束了,由于代码过长就不在这贴完整代码了,在这贴上链接,有需要的朋友可以自行下载学习 因为本人github这边暂时登不上上传不了,这里贴的是gitee的地址 gitee.com/little-fish…

今天的文章如何用JavaScript实现一个简单的小游戏FlyBird分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/21260.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注