图集Atlas是游戏开发中常用的一种美术资源,通过工具将多张图片合并成一张大图,并通过.atlas
或.json
等格式的文件存放原始图片资源信息。
游戏中使用多张图片合成的图集资源作为美术资源的优势
- 优化内存:合成图集时会去除每张图片图片周围的空白区域,加上可以在整体上实施优化,合成图集后可减少游戏包体和内存占用。
- 减少CPU运算:多个Sprite精灵渲染的是来自同一张图集图片时,这些Sprite可以使用同一个渲染批次来处理,大大减少了CPU的运算时间,提高运行效率。
图集格式
LayaAir IDE支持对PNG和JPG两种资源格式打包为图集,图集打包的原始资源推荐使用PNG,因为JPG的体积会较大。需要注意的是,PNG原始资源的位深度不能超过32,否则打包出来的图集会出现花屏。另外,PNG与JPG资源不能是其它格式资源重命名所产生的PNG和JPG格式。
Laya图集文件区别
.atlas
和.json
文件都是PNG图集的配置信息文件,最早期LayaAir引擎默认使用JSON作为图集配置信息的格式,后来为了优化引擎的使用,默认修改为了.atlas
,为了兼容旧版本,生成图集的时候可选择两种格式。使用时这两种后缀的区别在于:
.atlas
是Laya特有的图集格式,仅用于图集,在加载.atlas
时无需填写类型和加载普通单图方式一样,更为方方便,是推荐的图集加载方式。
Laya.loader.load(
"./res/atlas/ui.atlas",
Laya.Handler.create(this, onLoaded)
);
.json
是一种兼容第三方的图集配置方式,由于.json
文件应用广泛,不仅可以用于图集,所以为了是被是否为图集配置信息,在加载.json
文件的图集配置时,需要填写类型以进行区分。
Laya.loader.load(
[{url:"./res/atlas/ui.json", type:Laya.Loader.ATLAS}],
Laya.Handler.create(this, this.onLoaded)
);
图集打包
LayaAir IDE中打包图集的方式有两种,分别是使用LayaAir IDE的图集打包工具和资源管理器内自动打包图集。
手动打包图集
LayaAir IDE中的【图集打包工具】会将每个目录打包为一个图集,特效类动画因为每个特效帧数量不多可以将多个特效组合到一张图集资源并存放在一个目录内。通过LayaAir IDE对图集打包后,会生成三个文件分别是.atlas
、.json
、.png
文件。动画类Animation
通过加载.atlas
或.json
文件获取图像资源,建议使用.atlas
文件,因为在使用时无需加入类型设置。对于动画图集资源需要注意的是,针对帧数较多的动画建议一套图片一个资源在命名上根据动作名称_帧序号
的方式命名。
【图集打包工具】位于设计模式 > 菜单 > 工具 > 图集打包
。
如何手动打包图集呢?
存放在资源管理器目录laya/assets
目录下的所有图片资源,在使用快捷键F12
或Ctrl+F12
导出时,会自动根据当前目录名打包为图集。
进入设计模式,按F12
导出,此时IDE会将资源Assets
(对应laya/assets
目录)中的图片打包成图集,打包后的图集会保存到发布目录的bin/res/atlas
目录下,图集会同时生成.png
和.atlas
(JSON)文件。
当用户手动删除了图集文件但并未删除原始资源文件时,如果原始资源文件没有发生改变,直接使用F12
是无法重新导出图集文件的。此时,可以通过Ctrl+F12
清理并导出。或者直接将图集文件删除后再使用F12
导出,即可正常导出图集。
如何修改默认的图集打包后的导出位置呢?
如果想要修改图集默认的导出目录,可以在【设计模式】下按快捷键F9
进入【项目设置】,在【项目设置】面板的【图集设置】的【资源发布目录】选项中修改图集导出路径。同时可以设置图集的最大宽高,以及不准备打包的单图宽高限制等。
进入设计模式,按F9
弹出项目设置,选中图集设置。
如何将未使用的图片资源不打包到图集内呢?
在【资源管理器】中如果存在没有在项目场景中使用的图片,可以通过【菜单】中的【导出】选择-发布(不打包未使用的资源)】功能。将未使用的资源不打包到图集中,以减少图集的大小。这种打包方式由于需要遍历所有资源的使用状态,会导致打包速度缓慢,因此只有在发布线上版本的时候才会使用到。
如何将单张图片资源不打包到图集内呢?
在【设计模式】的【资源管理器】中选中目标图片资源,左键双击或右键选择【设置默认属性】。
在弹出的【资源属性设置】面板中选择下方的【打包类型】中的【不打包】选项,选中的图片资源就不i会被打包到图集中。
如何使用图集资源中指定的图片呢?
例如:项目中如果用到图集中的资源则需要预加载图集资源,然后设置图片的皮肤skin
属性值为 [原小图目录名称/原小图资源名.png
],从图集中取出小图资源其实就是图集打包前对应的目录与资源名称和路径。
class Test {
constructor() {
Laya.init(Laya.Browser.width, Laya.Browser.height, Laya.WebGL);
this.onInit();
}
initStage(){
Laya.stage.alignH = Laya.Stage.ALIGN_CENTER;
Laya.stage.alignV = Laya.Stage.ALIGN_MIDDLE;
Laya.stage.scaleMode = Laya.Stage.SCALE_SHOWALL;
Laya.stage.bgColor = "#000000";
}
onInit(){
this.ATLAS_PATH = "./res/atlas/avatar.atlas";
Laya.loader.load(this.ATLAS_PATH, Laya.Handler.create(this, function(){
let image = new Laya.Image();
image.skin = "avatar/avatar1.png";
Laya.stage.addChild(image);
}));
}
}
//启动
new Test();
自动打包图集
- Laya会将小于512*512的图片打入自动大图集中,如果图片被打入自动图集中,图片的内存就会交由Laya自动处理,开发者不能手工删除。
- Laya最多能生成6张2048*2048的自动图集,3D为2张,可通过
AtlasResourceManager.maxTextureCount
设置。 - 使用自动图集可以减少
drawcall
,缺点是部分资源释放不了,只有当自动图集全部被占满时才能释放部分资源。
若不想将图片打入自动图集,有三种方法实现:
- 获取到图片的纹理
texture
关闭合并到图集的开关
let texture = Laya.loader.getRes(url);//获取图片的纹理
texture.bitmap.enableMergeInAtlas = false;//关闭合并到图集
- 关闭自动图集功能
Config.atlasEnable = false;
laya.webgl.atlas.AtlasResourceManagerAtlasResourceManager._disable();
- 设置图集限制大小
//大图合计管理器
// laya.webgl.atlas.AtlasResourceManager
//设置进入大图合集的最大尺寸
laya.webgl.atlas.AtlasResourceManager.atlasLimitWidth = 256;
laya.webgl.atlas.AtlasResourceManager.atlasLimitHeight = 256;
动画基类
Laya提供的Animation
动画类使用多种动画资源生成游戏动画,使用LayaAir IDE创建时间轴动画的方式生成文件后缀名为.ani
的动画资源,也可以使用图集打包动画帧图片的方式,创建文件名为.atlas
的图集资源,然后赋给动画类去加载使用。
结构 | 描述 |
---|---|
Package | laya.display.Animation |
Class | Laya.Animation |
Hierarchy | Animation / AnimationBase |
Animation
动画类继承自AnimationBase
动画基类,动画基类提供了基础的动画播放控制方法和帧标签事件等相关功能。动画基类可以被继承,但不能直接被实例化,因为动画基类中的部分方法需要子类去实现。
结构 | 描述 |
---|---|
Package | laya.display.AnimationBase |
Hierarchy | AnimationBase / Sprite |
动画基类AnimationBase
提供了两个子类,分别是Animation
动画类和FrameAnimation
帧动画类。
属性 | 描述 |
---|---|
loop:boolean |
是否循环播放,当调用play() 播放动画方法时,可以设置loop 属性为指定的参数。 |
wrapMode:Number = 0 |
动画的播放顺序 |
动画播放顺序wrapMode
分为三种
-
AnimationBase.POSITIVE:number = 0
默认正序播放 -
AnimationBase.WRAP_REVERSE:number = 1
倒序或逆序播放 -
AnimationBase.WRAP_PINGPONG:number = 2
pingpong
播放即按指定顺序播放完结尾后,若要继续播放则会改变播放顺序。
存取器 | 描述 |
---|---|
count |
动画帧的总数 |
index |
动画帧当前的索引 |
interval |
动画帧播放的间隔毫秒数 |
isPlaying |
动画是否正在播放中 |
动画播放的帧间隔毫秒时间interval
默认值依赖于Config.animationInterval = 50
选项,通过配置Config.animationInterval
选项可以修改默认动画帧的间隔毫秒数。如果想要为某动画设置独立的帧间隔时间,可以使用set interval
。需要注意的是如果动画正在播放,设置interval
后会重置帧循环定时器的起始时间为当前时间,也就是说,如果频繁的设置interval
将会导致动画帧更新的时间间隔比预想的要慢,甚至会不更新。
方法 | 描述 |
---|---|
addLabel |
增加帧标签到指定索引的帧上 |
removeLabel |
删除指定帧标签 |
gotoAndStop |
将动画切换到指定帧并停留在那里 |
play |
开始播放动画 |
stop |
停止播放动画 |
clear |
停止播放动画并清理对象属性 |
动画类
创建动画Animation
类的实例
let ani = new Laya.Animation();
Animation
类是Graphics
动画类,其实现是基于Graphics
的动画创建、播放和控制的接口。Animation
类使用了动画模板缓存池,以一定的内存开销来节省CPU开销。当相同的动画模板被多次重复使用时,相比每次都创建新的动画模板,使用动画模板池只需创建一次,缓存之后可以多次使用,从而节省了动画模板创建的开销。动画模板缓存池是以key-value
键值对的形式进行存储,键名key
可以自定义,也可以从指定的配置文件中读取。键值value
是对应的动画模板,是一个Graphics
对象数组,每个Graphics
对象对应着一个帧图像,动画的播放实际上是定时切换Graphics
对象。