微信小游戏 demo 飞机大战 代码分析(一)(main.js)html
微信小游戏 demo 飞机大战 代码分析(二)(databus.js)canvas
微信小游戏 demo 飞机大战 代码分析(四)(enemy.js, bullet.js, index.js)数组
本博客将使用逐行代码分析的方式讲解该demo,本文适用于对其余高级语言熟悉,对js还未深刻了解的同窗,博主会尽量将全部遇到的不明白的部分标注清楚,如有不正确或不清楚的地方,欢迎在评论中指正微信
本文的代码均由微信小游戏自动生成的demo飞机大战中获取ide
游戏基础的精灵类函数
代码oop
/** * 游戏基础的精灵类 */ export default class Sprite { constructor(imgSrc = '', width= 0, height = 0, x = 0, y = 0) { this.img = new Image() this.img.src = imgSrc this.width = width this.height = height this.x = x this.y = y this.visible = true } /** * 将精灵图绘制在canvas上 */ drawToCanvas(ctx) { if ( !this.visible ) return ctx.drawImage( this.img, this.x, this.y, this.width, this.height ) } /** * 简单的碰撞检测定义: * 另外一个精灵的中心点处于本精灵所在的矩形内便可 * @param{Sprite} sp: Sptite的实例 */ isCollideWith(sp) { let spX = sp.x + sp.width / 2 let spY = sp.y + sp.height / 2 if ( !this.visible || !sp.visible ) return false return !!( spX >= this.x && spX <= this.x + this.width && spY >= this.y && spY <= this.y + this.height ) } }
构造器动画
将精灵画于画布上this
动画类所在文件code
代码
import Sprite from './sprite' import DataBus from '../databus' let databus = new DataBus() const __ = { timer: Symbol('timer'), } /** * 简易的帧动画类实现 */ export default class Animation extends Sprite { constructor(imgSrc, width, height) { super(imgSrc, width, height) // 当前动画是否播放中 this.isPlaying = false // 动画是否须要循环播放 this.loop = false // 每一帧的时间间隔 this.interval = 1000 / 60 // 帧定时器 this[__.timer] = null // 当前播放的帧 this.index = -1 // 总帧数 this.count = 0 // 帧图片集合 this.imgList = [] /** * 推入到全局动画池里面 * 便于全局绘图的时候遍历和绘制当前动画帧 */ databus.animations.push(this) } /** * 初始化帧动画的全部帧 * 为了简单,只支持一个帧动画 */ initFrames(imgList) { imgList.forEach((imgSrc) => { let img = new Image() img.src = imgSrc this.imgList.push(img) }) this.count = imgList.length } // 将播放中的帧绘制到canvas上 aniRender(ctx) { ctx.drawImage( this.imgList[this.index], this.x, this.y, this.width * 1.2, this.height * 1.2 ) } // 播放预约的帧动画 playAnimation(index = 0, loop = false) { // 动画播放的时候精灵图再也不展现,播放帧动画的具体帧 this.visible = false this.isPlaying = true this.loop = loop this.index = index if ( this.interval > 0 && this.count ) { this[__.timer] = setInterval( this.frameLoop.bind(this), this.interval ) } } // 中止帧动画播放 stop() { this.isPlaying = false if ( this[__.timer] ) clearInterval(this[__.timer]) } // 帧遍历 frameLoop() { this.index++ if ( this.index > this.count - 1 ) { if ( this.loop ) { this.index = 0 } else { this.index-- this.stop() } } } }
继承于Sprite类
构造器
初始化帧动画的全部帧
把播放中的帧画到画布上
中止帧动画播放
帧遍历