微信小游戏 demo 飞机大战 代码分析 (三)(spirit.js, animation.js)
微信小游戏 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)的更多相关文章
- 微信小游戏 demo 飞机大战 代码分析(四)(enemy.js, bullet.js, index.js)
微信小游戏 demo 飞机大战 代码分析(四)(enemy.js, bullet.js, index.js) 微信小游戏 demo 飞机大战 代码分析(一)(main.js) 微信小游戏 demo 飞 ...
- 微信小游戏 demo 飞机大战 代码分析 (二)(databus.js)
微信小游戏 demo 飞机大战 代码分析(二)(databus.js) 微信小游戏 demo 飞机大战 代码分析(一)(main.js) 微信小游戏 demo 飞机大战 代码分析(三)(spirit. ...
- 微信小游戏 demo 飞机大战 代码分析 (一)(game.js, main.js)
微信小游戏 demo 飞机大战 代码分析(一)(main.js) 微信小游戏 demo 飞机大战 代码分析(二)(databus.js) 微信小游戏 demo 飞机大战 代码分析(三)(spirit. ...
- Python小游戏之 - 飞机大战美女 !
用Python写的"飞机大战美女"小游戏 源代码如下: # coding=utf-8 import os import random import pygame # 用一个常量来存 ...
- Python小游戏之 - 飞机大战 !
用Python写的"飞机大战"小游戏 源代码如下: # coding=utf-8 import random import os import pygame # 用一个常量来存储屏 ...
- 微信demo小游戏:飞机大战从无到有
微信demo游戏飞机大战从无到有 现在创建新项目会默认给飞机大战的demo,这里给大家从基础开始讲解游戏的从无到有是怎么实现的. 具体实现步骤: 创建背景图->背景图运动起来->创建飞机并 ...
- 【转】利用 three.js 开发微信小游戏的尝试
前言 这是一次利用 three.js 开发微信小游戏的尝试,并不能算作是教程,只能算是一篇笔记吧. 微信 WeChat 6.6.1 开始引入了微信小游戏,初期上线了一批质量相当不错的小游戏.我在查阅各 ...
- 微信小游戏的本地缓存和清除的使用 (text.js image.js file-util.js)
参考: 微信小游戏,文件系统 UpdateManager-小游戏 一.Egret提供的本地缓存工具类( 备注:新版本进行了修改,并增加了sound.js等) 在微信小游戏项目中,Egret提供了fil ...
- cocos creator开发微信小游戏记录
先用cocoscreator实现游戏逻辑 在cocoscreator项目里可以调用微信小游戏api 在cocos里面判断小游戏的运行环境 if (cc.sys.platform === cc.sys. ...
随机推荐
- android SDK manager 无法获取更新版本的解决办法
http://mirrors.neusoft.edu.cn/eclipse/releases/luna/打开这个网址就可以看到adt的详细信息: http://developer.android.c ...
- 聊聊tcpdump与Wireshark抓包分析
1 起因# 前段时间,一直在调线上的一个问题:线上应用接受POST请求,请求body中的参数获取不全,存在丢失的状况.这个问题是偶发性的,大概发生的几率为5%-10%左右,这个概率已经相当高了.在排查 ...
- 忘记mysql数据库密码时进行修改方法
长时间没有使用数据库了,或者把密码改完之后就忘了数据库密码,不能正常进入数据库,也无法修改密码,有一个简单的常用修改密码方式: 1.首先找到和打开mysql.exe和mysqld.exe所在的文件夹( ...
- mysql 主从复制以及binlog 测试
###mysql查看binlog日志内容 https://blog.csdn.net/nuli888/article/details/52106910 mysql的binlog日志位置可通过show ...
- MySQL复制机制原理
背景介绍 复制,就是对数据的完整拷贝,说到为什么要复制,首先能想到的是怕数据意外丢失,使得用户蒙受损失. 当完成了数据复制之后,会发现它的优势不止这一点,假如一台机器宕机了,可以启用备份在另一台机器的 ...
- Python3基础(1)Python介绍、Python2 与Python3、变量、用户输入、if...else和for循环、while循环、break与continue
---------------个人学习笔记--------------- ----------------本文作者吴疆-------------- ------点击此处链接至博客园原文------ P ...
- jQuery知识重构
jQuery知识重构 目录: 一.入口函数 1 $(document).ready(function(){}); 2 $(function(){}); jQuery ...
- Android Broadcast Receive
Broadcast Receive 广播接收(Broadcast Receive)为android的四大组件之一.主要用于监听广播消息,并做出响应.与应用程序中监听事件相比而言,该监听事件为全局监听. ...
- graylog插件的安装
什么是插件和插件的作用我就不说了,大家应该都知道了. 安装方法是打开下面选择项 进去后出现如下界面 选择事先下载好的插件后,点击上传.这里以nginx日志插件为例 之后查看效果,发现对应的过滤 ...
- Q9400为何难以100%全速运行
采用基于正域的约简. 数据:Ticdata2000 记录数:5822 条件属性:85 结果: 1. Core i7 3632QM 4四核八线程 2.2G 动态加速3.2G 0.516s 2. Core ...