微信小游戏之飞机大战解析

一、从抄官方代码开始

    1.1 首先是game.js,具体代码如下:

import './js/libs/weapp-adapter'
import './js/libs/symbol'

import Main from './js/main'

new Main()

    导入了两个libs文件,weapp-adapter是为了与浏览器中DOM,BOM的概念兼容而写的,总共有1500行左右代码,抄完所有的代码之后,需要回头检查一下确保里面的代码准确无误。这里就不上代码了。

    另外一个symbol.js文件内容如下,看开头的注释是方便模拟私有变量:

/*对于ES6中Symbol的极简兼容
 *方便模拟私有变量
 */
let Symbol = window.Symbol
let idCounter = 0

if (!Symbol) {
	Symbol = function Symbol(key) {
		return `__${key}_${Math.floor(Math.random() * 1e9)}_${++idCounter}__`
	}

	Symbol.iterator = Symbol('Symbol.iterator')
}

window.Symbol = Symbol

    接着,import了main.js 中Main类,然后new了一个Main,看一下Main的内容:

这里调用了restart()函数,原project中是已经new好了所有的对象,这里,我一个一个来测试,先写上this.music = new Music(),这时候,就需要在main.js文件开头写上

然后创建出runtime目录,新建music.js文件,文件内容如下:

     可以看出,这块的接口就会调用weapp-adaptor.js的相关接口,比如new Audio()会最后调用wx.createInnerAudioContext()接口。

    此时,保存文件之后,运行会听到bgm的音频播放。

    1.2 继续!接下来我们来绘制背景图案,这里试了一下官方的代码绘制红色的矩形框,是ok的!但是我在restart()中加入绘制BackGround的render,没有背景图产生,加的代码如下,暂时还没找到原因:

        然后再加了loop的循环渲染的机制代码之后,背景图出现了。继续测试,在代码中我加入了count的变量,让其loop函数执行2次(不算restart中的requestAnimationFrame),背景图会出现; 让其loop函数执行1次(不算restart中的requestAnimationFrame),背景图不会出现;对比图如下:

     1.3 接下来绘制gameinfo.

      看一下效果图和代码

      

      

      gameinfo类中的renderGameInfo()的代码如下:
       

       ctx的fillStyle、font、fillText属性控制着显示的样式。

      1.4 继续绘制player。效果图和代码如下显示:

      

     

      然后我们看一下Player的class内容:

            

     此时Main类中的render的drawToCanvas内容在Sprite.js文件中:

      

    1.5 接着我们绘制不断生成的enemy敌机。我们需要在loop函数中循环执行update和render的代码,如下图

      

      然后看一下update的代码:

     

     databus中enemys的update函数,看一下内容:

     

     很明显,y的方向是y值加上步进距离。

     再看一下render函数的内容:

          

   databus中的enemys的drawToCanvas()函数内容(注意:调用的是Sprint中的drawToCanvas()):

      

  看一下效果图:

   

    1.6 我们发现背景图并没有随着敌机的移动而缓慢移动,接下来我们加一下背景图的移动。

    首先在main中的update函数中增加如下代码:

           

   然后在background.js中增加update函数,代码如下:

   

    效果图如下,可以发现两张截图的背景图发生了变化:

    

    1.7  接下来我们加入子弹功能。在main的update中加入如下代码:

    

     上面item.update()会执行子弹类的update和敌机类的update函数。

     看一下子弹类的update内容:

     

     跟敌机类的update函数内容很相似。

    看一下player类的shoot函数内容:

    

   效果图如下:

    

    1.8 接着我们加入手指按住战机左右移动。在index.js文件中加入如下代码:

    

    看一下initEvent()函数的内容:

   

    监听了手指触摸事件,检查是否在战机上并设置位置,内容分别如下:

        

    最终的效果如下:

    

    1.9 接着我们加入全局碰撞检测模块。在Main类中的update函数中增加如下红框代码:

    

    接下来看一下全局碰撞检测函数内容:

    

    playAnimation()是播放敌机爆炸的动画,playExplosion()是播放敌机爆炸的声音,

    bullet.visible = false是子弹和敌机消失,然后score加1.

    播放敌机爆炸动画是需要提前初始化帧动画的,所以在之前创建enemy敌机对象的时候,执行了如下代码:

    

   其中将19张爆炸效果图push到frames中,然后执行initFrames(),代码内容如下:
   

   此时,imgList中就有了对应的帧动画图片。   

   看一下playAnimation函数的内容,setInterval设置了每隔interval事件执行frameLoop的代码,this.index初始值是-1,当是0的时候播放当前帧:

   

   这时候Main类中的update的相关代码执行完毕,执行render中的内容:

   

   然后看一下aniRender内容,将每一帧的动画图画了出来:

   

     看一下效果图:

     

    1.10 到目前为止,基本的游戏逻辑已经完成,还剩最后一个重新开始模块。

     还是从全局碰撞检测开始,当战机碰到敌机的有效矩形时,设置gameOver的值为true,如下:

    

    然后在render中执行如下代码:

    

    通过gameinfo中的renderGameOver渲染游戏结束的画面,代码如下:

    

    底下代码中btnArea点击之后触发事件。在main类中的touchEventHandler函数中执行了改事件的动作,如下:

    

猜你喜欢

转载自blog.csdn.net/zhangge3663/article/details/81783773