内容简介:拍于沙巴红树林萤火虫最近在对前端互动游戏技术一些学习和探索,恰逢上一个小游戏使用了 CreateJS 技术,借此文对其使用做一次备忘,同时让想用 CreateJS 写小游戏的同学可以快速上手。
拍于沙巴红树林萤火虫
TL,TR
最近在对前端互动游戏技术一些学习和探索,恰逢上一个小游戏使用了 CreateJS 技术,借此文对其使用做一次备忘,同时让想用 CreateJS 写小游戏的同学可以快速上手。
笔记基于最新1.0版本,有不少地方和网上老教程不一致,同时也建使用最新版本,主要内容如下:
概况
简介
CreateJS是基于HTML5开发的一套模块化的库和工具,基于这些库,可以非常快捷地开发出基于HTML5的游戏、动画和交互应用。
历史可以追溯到7年前 flash 使用慢慢变少那个时代,gskinner 开发它作为“下一代”的富交互的 工具 库,Adobbe、微软、火狐官方资助的一个项目,API 在很多地方和 Flash 是很像,同时可以通过Adobe Animate CC(替代 flash)直接导出Canvas在Web中使用。
在 18年 终于发布了 1.0 版本,同时官方正在开发 2.0 版本,相信不就会有一个更现代化的 Createjs 呈现给开发者。
模块组成
CreateJS 提供的 4 个模块可以帮助处理游戏开发中常见操作:
- EaselJS:用于位图、图形、Sprites、文本的绘制,还包含 Ticker 定时器
- TweenJS:用来创建补间动画效果
- PreloadJS:游戏资源的预加载和管理,包括图片、音频、json等资源
- SoundJS:播放和处理音频
更好使用
目前官方版本的 createjs 不支持通过 npm 方式的使用,导致在 ES6 开发中,需要在 html 中手动引入一个 <script>
标签才可以使用,对模块化开发不方便。
createjs-npm 通过 imports-loader、exports-loader 对官方库加了一层胶水,让大家可以向使用 npm 包方式一样使用,具体为:
// 安装后和官方 createjs 1.0 使用一致 npm install createjs-npm -S // 引入全部模块 import createjs from 'createjs-npm'; // 只引入单个模块(xx 可以是 easel、preload、tween、sound) import createjs from 'createjs-npm/lib/xx';
EaselJS 的使用
EaselJS 在 Createjs 中承担 画 的能力,比如说你要画图片、画图形、画帧动画、画文字可以使用它的 API 实现。
步骤
比如说你需要在画一个红色的圆,必含步骤为 创建舞台->创建对象->设置对象属性->添加对象到舞台->更新舞台呈现下一帧 :
//创建一个舞台,得到一个参考的画布 const stage = new createjs.Stage("myCanvas"); //创建一个形状的显示对象 const circle = new createjs.Shape(); circle.graphics.beginFill("red").drawCircle(0, 0, 40); //形状实例的设置位置 circle.x = circle.y = 50; //添加形状实例到舞台显示列表 stage.addChild(circle); //更新舞台将呈现下一帧 stage.update();
上述代码的效果为:
See the Pen Demo by Tw93 ( @tw93 ) on CodePen .
Graphics 类
在上面Demo中,我们创建了一个 Shape,这里其实是创建了一块画布,同时假如需要在画布上面画东西,就需要使用Graphics类了。
可以在 Graphics 上面设置很多样式,或者调用绘图方法来画其他的图形,同时Graphics类里的所有绘图方法都会返回一个graphics实例,这里使用链式操作会很方便,使用具体可见 【EaselJS API】 。
EaselJS 元素
上面说过,EaselJS 可以用来画图片、图形、动画帧、文字这类型的元素,对应是 Bitmap、Shape、Sprite、Text 这几个。 具体使用为:
// 使用 Bitmap 来表示图片 const bitmap = new createjs.Bitmap("imagePath.jpg"); // 使用 Shape 结合 Graphics 来表示图形 const shape = new createjs.Shape(); shape.graphics.beginFill("#ff0000").drawRect(0, 0, 100, 100); // 使用 Sprite 来表示精灵动画(后面详细介绍) const instance = new createjs.Sprite(spriteSheet); instance.gotoAndStop("frameName"); // 使用 Text 来表示文字 const text = new createjs.Text("How are you", "20px Arial", "#000000");
精灵动画
这个特性会让第一次接触的同学高兴起来,很方便使用,同时实现效果很棒,比如说需要实现一个绅士走路的样子:
See the Pen Sprite by Tw93 ( @tw93 ) on CodePen .
【技巧】此处雪碧图的生成可以借助 TexturePacker ,其中有一个导出为 EaselJS 的选项,将值直接替换 SpriteSheet即可。
上述代码应该能够很好的表达意思,可以试试animations中多设置几个动作,让其更有趣,更详细的使用可以参考 SpriteSheet Class
Ticker 刷新
主要作用
上述人物的走动,就是靠 Ticker 来实时刷新舞台的,同时可以通过addEventListener来监听tick的刷新,并在里面”做些事情”。
createjs.Ticker.framerate = 60; createjs.Ticker.timingMode = createjs.Ticker.RAF_SYNCHED; sprite.addEventListener("tick", ()=>{console.log("doing something"});
关注点
createjs.Ticker.framerate表示 Ticker 帧频率,理想下是60FPS,这里在游戏体验优化时候可以设置到60。
createjs.Ticker.timingMode表示 Ticker的渲染模式(setTimeout、requestAnimationFrame),可以这样选择:
- TIMEOUT:默认模式,这种模式通过setTimeout方式来更新下一次,虽然提供了可预期的、灵活的帧率,但是在性能体验上比requestAnimationFrame方式要差很多,不建议使用
- RAF:只单纯使用RAF,会将 framerate 设置的帧速率等值忽略,频率取决于当时运行环境和浏览器性能
- RAF_SYNCHED:它会尝试去协调RAF和设置的framerate频率,相当于结合了setTimeout 和 RAF 的优点,也即这里可以设置framerate=60,优化让CreateJS 帮忙处理,建议使用这个模式
优化点
同时这里可以和 Ticker.paused
结合起来做性能优化,比如说我们在游戏暂停时候,可以这样防止不停刷新,类似这样:
createjs.Ticker.addEventListener('tick', (e) => { !e.paused && stage.update(); }); createjs.Ticker.paused = true; //在任何地方调用这个,则会暂停tick里面的处理 createjs.Ticker.paused = false; //在任何地方调用这个,则会恢复tick里面的处理
在性能调优过程中,可以通过 createjs.Ticker.getMeasuredFPS() 将实时的帧率输出到屏幕,当这个值和设置的 framerate 很接近,说明性能良好
TweenJS 的使用
从上面可以看到,EaselJS 其实可以处理 CreateJS 开发中很多的事情,其他三项可以当做辅助工具,让开发更便捷。
TweenJS 在这里充当着“动”的能力,同时它也可以单独使用,支持数字对象属性和CSS样式属性,是一个很强大的补间动画功能库。
案例
比如说以下这个很经典的动画例子:
See the Pen TweenJS by Tw93 ( @tw93 ) on CodePen .
使用
可以看到链式处理让很多操作使用是很简单的,也即可以获取目标元素、设置等待时间、执行下一步动画、动画结束事件;
一般场景用上面完全够用,还有如下高级特性,可以通过 【文档】 来查询:
createjs.CSSPlugin.install(); RotationPlugin.install(props); createjs.MotionGuidePlugin.install(createjs.Tween);
PreloadJS 的使用
PreloadJS是一个用来管理和协调相关资源加载的类库,它可以方便的帮助你预先加载相关资源。
它主要是使用 LoadQueue 类来管理加载内容的,在游戏中很常见的场景是预加载图片资源和游戏音乐。
案例
屏幕中可以看到处理后的图片加载出来,同时在播放着背景音乐:
See the Pen PreloadJS by Tw93 ( @tw93 ) on CodePen .
使用
加载方式
const queue = new createjs.LoadQueue(false);
里面传入布尔值用来表明是用XHR还是用HTML标签来加载,默认为true,就是使用 XHR 来加载,但是XHR 加载 cdn 常常会报一些错误,也即推荐使用false类型,通过标签来加载。
资源加载和使用
通过 loadManifest 类可以加载一组游戏中用到的所有资源,包括 图片、音频、json、svg 等文件,id 用来加载完使用的标识,同时通过 queue.getResult(id)
获取。
资源加载过程中,有complete、error、progress、fileload供订阅,完成后才可以对资源进行使用,progress和complete结合来显示进度条,fileload表示当个文件加载完毕
加载音乐
加载音乐时候需要注册 Sound 插件,也即 queue.installPlugin(createjs.Sound);
,同时指明音乐文件格式,比如说 createjs.Sound.alternateExtensions = ["mp3"];
这里还有一个小坑,对于低版本的浏览器,可能会出现音乐不能播放情况,可以引入 HTMLAudioPlugin 解决: createjs.Sound.registerPlugins([createjs.HTMLAudioPlugin])
对于音乐播放,使用 createjs.Sound.play(id);
即可,详细使用后面 SoundJS 介绍。
SoundJS 的使用
一个小游戏要想互动性比较好,背景音乐是必不可少少的,可以选择一些轻松活泼的,需要使用SoundJS来“放音乐”,同时具备完善的兼容处理。
Sound 类
音频管理主要使用 Sound 类,有如下功能:
createjs.Sound.play(id)
AbstractSoundInstance 播放实例类
当我们调用 Sound.play API时候其实就创建了一个AbstractSoundInstance 类,创建好后,我们可以通过它来直接控制音频的播放或者其他操作,同时可以监听其播放状态:
const myInstance = createjs.Sound.play("myAssetPath/mySrcFile.mp3"); // 属性控制,实际中选择需要的属性设置就好 // 属性同时以对象方式可以加到play第二个参数 myInstance.volume = 0.5; myInstance.paused = false; // 控制音乐暂停否 myInstance.loop = true; // 循环播放 myInstance.duration = 30; //播放时长 // 监听状态,常用于错误时候,重新播放 myInstance.on("complete", handleComplete); myInstance.on("loop", handleLoop); myInstance.on("failed", handleFailed);
性能体验优化
图片优化
- 图片大小和正常 H5 相比更加影响性能,尽量使用合适尺寸和通过tinypng 压缩后的图片
- 对于精灵图或者很多小图场景,可用 TexturePacker 工具将他们合成一张雪碧图
- 对于帧动画的场景,可用 gka 工具对图片进行压缩和直接生成动画文件
善用回收机制
- 对于屏幕外或者不在舞台里面的需及时销毁
- 对于复杂的对象使用cache来增加性能,简单的尽量就不要用了,会有反作用
- SpriteSheetBuilder 的方式可以代替 cache,而且效果更好
多用位图少用矢量
- 在 CreateJS 中矢量运算比较影响性能,奇怪是 Text shape都算矢量,建议此处直接将字和矢量图直接通过工具转成位图
- 如果某些项目必须用矢量,滤镜,叠加模式,或者含有非常多子元件,可以通过使用SpriteSheetBuilder进行位图渲染,从而优化
- animateCC 中的遮罩相当于把整个动画序列帧化,矢量化,所以也尽量少用,如果实在要用,操作方法跟处理上面矢量一样
滤镜和动画场景优化
- 不要使用滤镜特效比如(阴影滤镜和发光滤镜)来做动画,因为这样会非常耗费性能,在移动端上性能不可控
- 可以使用逐帧图片来代替相关滤镜特效来实现动画效果
减少嵌套和叠加
- 在做动画或者其他场景时候,尽量不要有太多容器的嵌套,尽量打平层级(有点点像写 Weex,讲究平和薄)
- 有些叠加的场景,可以直接用图片代替
帧率优化
createjs.Ticker.timingMode = createjs.Ticker.RAF_SYNCHED createjs.Ticker.framerate createjs.Ticker.getMeasuredFPS()
试试 StageGL 神器
- StageGL 在目前压缩版本没有引入,需要额外引入
- 使用起来和 Stage 差不多,相当于将原有的 Stage 改成 StageGL,但是相当于使用WebGl能力,性能会比原有的好太多,更多详细可见 GETTING STARTED WITH STAGEGL
// 常规的2D场景 const stage = new createjs.Stage("canvasId"); // 使用 WebGl const stage = new createjs.StageGL("canvasId");
移动端点击事件优化
在我们游戏初始化时候,一般需要为之绑定点击事件,但是对于移动端来说加上这一句效果会好很多
var stage = new createjs.Stage("canvasId"); createjs.Touch.enable(stage);
结束
CreateJS 的特性应该不止上述这些,更多的需要在实际项目中使用,通过各种游戏场景可以发掘很多有趣的使用,假如你也对 H5 互动小游戏开发有见解,欢迎一起交流。
Buy Me a Coffee !
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 史上最强副驾驶——开车打瞌睡?Python叫醒你
- 开车出门没处停?未来可用AI实时预判空车位
- 开源手机WiPhone即将众筹,你甚至还能用手机“开车”
- 运维老司机:问题排查经验总结
- 老司机 iOS 周报 #30 | 2018-08-06
- 老司机 iOS 周报 #33 | 2018-08-27
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Google成功的七堂课
罗耀宗 / 电子工业出版社 / 2005-7 / 28.00元
Google是全球使用人数最多的搜索引擎,在短短几年内,Google从斯坦福大学的实验室,茁壮成长为举世瞩目的IT业超级巨人,他们的成功绝非偶然,尤其是在网络泡沫破灭,行业一片萧条之际,它的崛起更为IT业带来一缕曙光。作者从趋势观察家的角度,以讲座的形式,向读者讲述Google成功的关键因素:破除因循守旧、不断打破常规,核心技术领先、做出了“更好的捕鼠器”,使得Google在搜索技术方面远远超越对......一起来看看 《Google成功的七堂课》 这本书的介绍吧!