在本系列的上一篇文章中,我们演示了在小游戏中如何使用 context 在 canvas 中绘制图像。 在本文中,我们将演示如何让图像动起来。
基本方法
要让图像动起来,其实就是要不断的改变图像的位置,大小甚至是图像的内容。在微信小游戏的官方文档 介绍了一种使用定时器来完成变化的方法,代码如下:
1 2 3 4 5 6 7 8 9 10
| const { windowWidth, windowHeight } = wx.getSystemInfoSync() function drawRect(x, y) { context.clearRect(0, 0, windowWidth, windowHeight) context.fillRect(x, y, 100, 100) } const rectX = canvas.width / 2 - 50 let rectY = 0 setInterval(function(){ drawRect(rectX, rectY++) }, 16)
|
其中,drawRect 用来绘制矩形,而 setInterval 函数通过定时 16ms 来不断的在新坐标绘制矩形,从而达到在屏幕上移动矩形的效果。
使用 requestAnimationFrame
如果屏幕上有多个图像(物体)要运动,并且要判断相互之间是否有碰撞,就需要在一个统一的时钟里去完成。这时候用 setInterval 就不叫难以处理,所以在小游戏中引入了一个新的方法,利用 requestAnimationFrame 函数将要执行的更新操作挂载到系统更新动作中,当系统要更新屏幕之前,就会去执行我们挂载的函数。每调用一次,就挂载一次。
为实现这种方法, 修改原 main.js 文件如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| let ctx = canvas.getContext('2d')
export default class Main { constructor() {
this.aniId = 0
this.bindLoop = this.loop.bind(this)
this.restart() }
restart() {
window.cancelAnimationFrame(this.aniId);
this.aniId = window.requestAnimationFrame( this.bindLoop, canvas ) }
render() { console.log('main render') }
update() { console.log('main update') }
loop() {
console.log('loop, aniId = ' + this.aniId)
this.update() this.render()
this.aniId = window.requestAnimationFrame( this.bindLoop, canvas ) } }
|
保存这段代码,你会看到在开发工具的 Console 窗口中,不断的有文本输出,说明 loop, render, update 这三个函数不断的被调用。 也就是说,我们有一个近似于硬件刷新屏幕的时钟,我们可以在这个时钟下来统一游戏中的处理逻辑,并快速的更新屏幕,为玩家提供更好的体验。
下一步
在下一步中,我们将让游戏背景动起来。