微信小游戏 demo 飞机大战 代码分析(三)(spirit.js, animation.js)

微信小游戏 demo 飞机大战 代码分析(一)(main.js)

微信小游戏 demo 飞机大战 代码分析(二)(databus.js)

微信小游戏 demo 飞机大战 代码分析(四)(enemy.js, bullet.js, index.js)

本博客将使用逐行代码分析的方式讲解该demo,本文适用于对其他高级语言熟悉,对js还未深入了解的同学,博主会尽可能将所有遇到的不明白的部分标注清楚,若有不正确或不清楚的地方,欢迎在评论中指正

本文的代码均由微信小游戏自动生成的demo飞机大战中获取

spirit.js

游戏基础的精灵类

代码

/**
* 游戏基础的精灵类
*/
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 )
}
}

Spirite类

constructor

构造器

  • 根据输入图片路径,高度,宽度,初始坐标(x,y)生成一个精灵

    • 这里的x,y 是指图片的左上角坐标
    • 应注意的一点是此处所有参数均有缺省值
  • 初始visible设置为true,即可见

drawToCanvas(ctx)

将精灵画于画布上

  • 如果不可见,那么不画到画布上
  • 如果可见,根据该精灵的x,y坐标

isCollideWith(sp)

  • 根据传入物体的左上角的坐标和大小计算中心坐标
  • 若两个物体中任意一个不可见,则无需计算,直接返回失败
  • 判断传入物体的中心坐标有没有在该物体的方框之内

animation.js

动画类所在文件

代码

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()
}
}
}
}

准备内容

  • 引入Spirit类和DataBus类
  • 生成一个databus对象
  • 确定一个Symbol对象

Animation类

继承于Sprite类

constructor

构造器

  • 先用图片路径和宽度高度初始化超类(spirit类)
  • 一些基本的动画设置参数,如备注所述作用

initFrames(imgList)

初始化帧动画的所有帧

  • 对传入参数imgList进行遍历

    • forEach是对js中对数组遍历的一种方式
    • =>是匿名函数的语法

aniRender(ctx)

把播放中的帧画到画布上

  • 通过调用drawImage画上动画在该时刻应该有的图像
  • 该函数在main.js中的render中有调用

playAnimation(index = 0, loop = false)

  • 将精灵图的可见设为false

    • 在本例子中有一个敌机被击毁,发生了敌机爆炸,展示爆炸的动画
  • 设置正在播放
  • 将是否循环的情况设置为初始设置的(初始设置为不循环)
  • 判断是否有动画切换间隔和帧数
    • 有的话设置定时器,使用函数setInterval
    • setInterval函数
      • 第一个参数是回调函数,是在这个过程中不断调用的函数
      • 第二个参数是间隔
      • 整个函数的含义就是在该间隔内不断调用传入的回调函数
      • (博主猜测一般情况来说主函数中的图像切换频率大于该间隔,这样才能体现动画的变化)

stop()

停止帧动画播放

  • 将播放设置为false
  • 清除原本设置的定时器

frameLoop()

帧遍历

  • 帧计数变量index加加
  • 若帧数大于图片数-1(由于计数从0开始)
    • 如果要求循环,将index置0
    • 否则将index--,即设置为最后一张图片,并且调用stop()函数暂停

微信小游戏 demo 飞机大战 代码分析 (三)(spirit.js, animation.js)的更多相关文章

  1. 微信小游戏 demo 飞机大战 代码分析(四)(enemy.js, bullet.js, index.js)

    微信小游戏 demo 飞机大战 代码分析(四)(enemy.js, bullet.js, index.js) 微信小游戏 demo 飞机大战 代码分析(一)(main.js) 微信小游戏 demo 飞 ...

  2. 微信小游戏 demo 飞机大战 代码分析 (二)(databus.js)

    微信小游戏 demo 飞机大战 代码分析(二)(databus.js) 微信小游戏 demo 飞机大战 代码分析(一)(main.js) 微信小游戏 demo 飞机大战 代码分析(三)(spirit. ...

  3. 微信小游戏 demo 飞机大战 代码分析 (一)(game.js, main.js)

    微信小游戏 demo 飞机大战 代码分析(一)(main.js) 微信小游戏 demo 飞机大战 代码分析(二)(databus.js) 微信小游戏 demo 飞机大战 代码分析(三)(spirit. ...

  4. Python小游戏之 - 飞机大战美女 !

    用Python写的"飞机大战美女"小游戏 源代码如下: # coding=utf-8 import os import random import pygame # 用一个常量来存 ...

  5. Python小游戏之 - 飞机大战 !

    用Python写的"飞机大战"小游戏 源代码如下: # coding=utf-8 import random import os import pygame # 用一个常量来存储屏 ...

  6. 微信demo小游戏:飞机大战从无到有

    微信demo游戏飞机大战从无到有 现在创建新项目会默认给飞机大战的demo,这里给大家从基础开始讲解游戏的从无到有是怎么实现的. 具体实现步骤: 创建背景图->背景图运动起来->创建飞机并 ...

  7. 【转】利用 three.js 开发微信小游戏的尝试

    前言 这是一次利用 three.js 开发微信小游戏的尝试,并不能算作是教程,只能算是一篇笔记吧. 微信 WeChat 6.6.1 开始引入了微信小游戏,初期上线了一批质量相当不错的小游戏.我在查阅各 ...

  8. 微信小游戏的本地缓存和清除的使用 (text.js image.js file-util.js)

    参考: 微信小游戏,文件系统 UpdateManager-小游戏 一.Egret提供的本地缓存工具类( 备注:新版本进行了修改,并增加了sound.js等) 在微信小游戏项目中,Egret提供了fil ...

  9. cocos creator开发微信小游戏记录

    先用cocoscreator实现游戏逻辑 在cocoscreator项目里可以调用微信小游戏api 在cocos里面判断小游戏的运行环境 if (cc.sys.platform === cc.sys. ...

随机推荐

  1. android SDK manager 无法获取更新版本的解决办法

    http://mirrors.neusoft.edu.cn/eclipse/releases/luna/打开这个网址就可以看到adt的详细信息:  http://developer.android.c ...

  2. 聊聊tcpdump与Wireshark抓包分析

    1 起因# 前段时间,一直在调线上的一个问题:线上应用接受POST请求,请求body中的参数获取不全,存在丢失的状况.这个问题是偶发性的,大概发生的几率为5%-10%左右,这个概率已经相当高了.在排查 ...

  3. 忘记mysql数据库密码时进行修改方法

    长时间没有使用数据库了,或者把密码改完之后就忘了数据库密码,不能正常进入数据库,也无法修改密码,有一个简单的常用修改密码方式: 1.首先找到和打开mysql.exe和mysqld.exe所在的文件夹( ...

  4. mysql 主从复制以及binlog 测试

    ###mysql查看binlog日志内容 https://blog.csdn.net/nuli888/article/details/52106910 mysql的binlog日志位置可通过show ...

  5. MySQL复制机制原理

    背景介绍 复制,就是对数据的完整拷贝,说到为什么要复制,首先能想到的是怕数据意外丢失,使得用户蒙受损失. 当完成了数据复制之后,会发现它的优势不止这一点,假如一台机器宕机了,可以启用备份在另一台机器的 ...

  6. Python3基础(1)Python介绍、Python2 与Python3、变量、用户输入、if...else和for循环、while循环、break与continue

    ---------------个人学习笔记--------------- ----------------本文作者吴疆-------------- ------点击此处链接至博客园原文------ P ...

  7. jQuery知识重构

    jQuery知识重构 目录: 一.入口函数 1          $(document).ready(function(){}); 2          $(function(){}); jQuery ...

  8. Android Broadcast Receive

    Broadcast Receive 广播接收(Broadcast Receive)为android的四大组件之一.主要用于监听广播消息,并做出响应.与应用程序中监听事件相比而言,该监听事件为全局监听. ...

  9. graylog插件的安装

    什么是插件和插件的作用我就不说了,大家应该都知道了. 安装方法是打开下面选择项     进去后出现如下界面 选择事先下载好的插件后,点击上传.这里以nginx日志插件为例 之后查看效果,发现对应的过滤 ...

  10. Q9400为何难以100%全速运行

    采用基于正域的约简. 数据:Ticdata2000 记录数:5822 条件属性:85 结果: 1. Core i7 3632QM 4四核八线程 2.2G 动态加速3.2G 0.516s 2. Core ...