【转】微信小游戏学习

1月份的时候微信更新了小游戏的功能,微信公众平台也放出了小游戏的开发文档,这里总结一下最近对小游戏的学习。

登录微信公众平台,能发现小程序的开发文档下多了一个小游戏类别。按照文档的指引,在开发工具中新建项目时勾选“建立游戏快速启动模板”就可以得到一个可以运行的小游戏了。

第一个小游戏

上图可以看到一个飞机的游戏,在开发工具中预览游戏,可以进行试玩。接下来就学习一下这个飞机游戏的代码。

项目的完整目录结构
|
|---audio
|  |...                     // 音频文件
|---images
|  |...                     // 图片/动画资源
|---js
|  |---base
|  |  |---animation.js      // Sprite的子类,实现了动画相关的功能
|  |  |---pool.js           // 一个简单的对象池实现,减少对象创建开销和频繁的垃圾回收
|  |  |---sprite.js         // 游戏基础的精灵类
|  |---libs
|  |  |---symbol.js         // 对于ES6中Symbol的极简兼容,方便模拟私有变量
|  |  |---weapp-adapter.js  // 模拟BOM和DOM的代码库,使游戏引擎在调用DOM API和访问DOM属性时不产生错误
|  |---npc
|  |  |---enemy.js
|  |---player
|  |  |---bullet.js
|  |  |---index.js
|  |---runtime
|  |  |---background.js
|  |  |---gameinfo.js
|  |  |--music.js
|  |---databus.js           // 全局状态管理器
|  |---main.js              // 游戏主函数
|---README.md
|---game.js                 // [必要]小游戏的入口文件
|---game.json               // [必要]配置文件
|---project.config.json     // 项目相关的配置文件

可以看到虽然只是一个模板,但包含的文件很多。不过文件虽多,结构还是很清晰的。首先从入口文件game.js开始。

game.js

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

import Main from './js/main'

new Main()

 

执行的代码只有一行:new Main()。接着来到main.js。顺着Main类中的constructor,来到restart()中:

restart() {
    databus.reset()

    canvas.removeEventListener(
      'touchstart',
      this.touchHandler
    )

    this.bg = new BackGround(ctx)
    this.player = new Player(ctx)
    this.gameinfo = new GameInfo()
    this.music = new Music()

    this.bindLoop = this.loop.bind(this)
    this.hasEventBind = false

    // 清除上一局的动画
    window.cancelAnimationFrame(this.aniId);

    this.aniId = window.requestAnimationFrame(
      this.bindLoop,
      canvas
    )
  }

 

这个函数中做了一些初始化工作,移除了重开游戏对话框的Listener,然后是最重要的一步:

this.aniId = window.requestAnimationFrame(
      this.bindLoop,
      canvas
    )

window.requestAnimationFrame是adapter封装的接口,内部是微信提供的接口[requestAnimationFrame()](“https://mp.weixin.qq.com/debug/wxagame/dev/document/render/frame/requestAnimationFrame.html“)。参数中的bindLoop就是main中的loop函数,在loop中同样调用了window.requestAnimationFrame,从而使得每一帧都会调用一次loop(),从而实现了游戏的帧循环。

接下来就到了loop()中了。

loop() {
    databus.frame++

    this.update()
    this.render()

    this.aniId = window.requestAnimationFrame(
      this.bindLoop,
      canvas
    )
  }

databus.frame记录了游戏开始到现在的帧数,在生成敌人和计算开炮时机的时候会用到。update中计算玩家和敌人的移动、碰撞等,render负责在画布上绘制需要展示的元素。这些都和主流的游戏结构类似。

最后来看看Sprite和Animation两个类。

Sprite类比较简单,其中保存了图片路径、大小、位置以及是否可见等信息,并实现了绘制到画布(drawToCanvas)的方法和一个简单的碰撞检测(isCollideWith)。碰撞检测检查的是一个精灵的中心点是否位于本精灵的矩形内。

Animation要稍微复杂一点,它继承了Sprite类,实现了播放帧动画的功能。由于只是个简单的实现,所以只支持了一个帧动画,当然简单修改之后就可以支持多个帧动画,更能满足实际应用的需求。从代码中可以看出帧动画是通过将精灵本体设置为不可见,再通过一个定时器(setInterval)按照一个固定的速率(this.interval)依次切换帧动画序列中的帧图片,主循环进行渲染时会把该图片显示到画布,达到动画的效果。这里比较重要的是setInterval方法,它是微信提供的一个定时器api,作用是设定一个定时器,按照指定的周期来执行注册的回调函数。这里的回调函数的工作就是切换帧图片的index。当动画播放结束时,要结束这个定时器,这时就需要使用微信提供的clearInterval接口了。

这里简单总结了一下微信开发者工具中提供的小游戏模板,可以看到整个游戏的生命周期都是由自己编写代码实现的,不像在一些引擎中只用“填空”即可。有点奇怪的是动画类是自己实现的,实际在写代码时,会发现提示中是有wx.createAnimation接口的,但文档中并没有给出来,可能以后会开放吧。

期待微信开发工具更新更多功能,并早日开放个人开发者发布微信小游戏的权限。

 

原文链接:https://blog.csdn.net/speeds3/article/details/79657131

 

您可能感兴趣的

Fundebug提供微信小游戏BUG监控,通过独创的截屏技术,方便开发者可视化了解BUG严重程度。

点击查看详情:Fundebug上线微信小游戏错误监控!支持自动截屏!

posted @ 2018-05-04 08:35  curationFE  阅读(448)  评论(0编辑  收藏  举报