1. 引言
在 Cocos Creator 中,图集(Atlas)是提升渲染性能、减少 Draw Call 的关键手段。本文以 Cocos Creator 2.2.2 为例。为什么用2.2.2举例,因为本人现在修改的是一款很老的棋牌项目,所以就顺便了,从图片资源准备、图集配置、生成与使用、动态合图四个方面,完整讲解图集的制作流程。
2. 图集的基本概念
图集是将多张零散的小图合并到一张大图上,并配套生成一份描述每张小图位置、尺寸、旋转等信息的元数据文件。渲染时,引擎只需一次性提交这张大图,就能绘制多个小图,从而显著减少 Draw Call。
在 Cocos Creator 2.2.2 中,图集由以下两部分组成:
- 纹理文件:合并后的大图,常见格式为 PNG 或 JPG。
- 图集元数据:记录每张小图在大图中的矩形区域、旋转状态、是否镂空等信息,通常以 .plist 或 .json 格式保存。
3. 图片资源准备
在制作图集之前,需要先整理好散图资源。建议遵循以下规范:
- 所有小图统一放在同一个目录下,例如 assets/textures/ui。
- 小图尺寸尽量规整,避免出现过大或过小的极端尺寸。
- 图片命名使用英文小写加下划线,例如 btn_start.png、icon_coin.png。
- 避免使用重复名称,防止图集生成时互相覆盖。
准备好散图后,在 Cocos Creator 2.2.2 的资源管理器中选中这些图片,即可开始配置图集。
4. 创建图集资源
在 Cocos Creator 中,创建图集有两种常用方式:自动图集和手动图集。下面分别介绍它们的制作步骤和关键参数。
4.1 自动图集
自动图集是最常用的方式,操作步骤如下:


自动图集配置的核心参数说明如下:
| 包含文件夹 | 指定需要打包进图集的图片目录,可添加多个。拖入目录后,该目录下的所有散图都会参与合图。 |
| 最大宽度 / 最大高度 | 图集纹理的最大尺寸,默认 2048 x 2048。当散图总尺寸超出限制时,引擎会自动拆分为多张图集。 |
| 内边距 | 每张小图之间的间距,建议设置为 2。过小的内边距会导致相邻小图采样时发生边缘渗色,出现黑边或白边。 |
| 允许旋转 | 是否允许小图旋转 90 度以提升空间利用率,默认开启。开启后能更紧凑地排列小图,减少图集面积浪费。 |
| 输出格式 | 支持 png、jpg 等格式。包含透明通道的 UI 图标建议使用 png,纯不透明的大图可考虑 jpg 以减小体积。 |
4.2 手动图集
手动图集适合对图集布局有特殊要求的场景,例如需要精确控制某张图的位置。操作步骤如下:
手动图集适合小规模、需要精细控制的资源,日常开发中更推荐使用自动图集。
5. 图集生成与验证

在构建之后生成的图就是图集了

6. 在代码中使用图集
图集生成后,在场景编辑器或代码中引用小图的方式与普通散图一致。Cocos Creator 2.2.2 会自动将图集中的小图识别为独立资源,开发者无需手动指定图集路径。
在代码中动态加载图集中的小图,可以使用以下方式:
// 加载图集中的小图
cc.resources.load("textures/ui/btn_start/spriteFrame", cc.SpriteFrame, function (err, spriteFrame) {
if (!err) {
this.node.getComponent(cc.Sprite).spriteFrame = spriteFrame;
}
});
需要注意的是,图集中的小图路径以图集内的小图名称为准,而不是散图在项目中的原始路径。
下面给出一个完整的实战示例:动态加载图集并切换多个 Sprite 的 SpriteFrame,包含资源加载、错误处理和内存释放的完整流程。
// SpriteSwitcher.js
// 实战示例:动态加载图集并切换多个 Sprite 的 SpriteFrame
cc.Class({
extends: cc.Component,
properties: {
// 需要切换的 Sprite 节点数组,在编辑器中拖入
spriteNodes: {
default: [],
type: [cc.Node]
},
// 图集中小图名称数组,例如 ["icon_coin", "icon_star", "icon_heart"]
spriteFrameNames: {
default: [],
type: [cc.String]
}
},
onLoad: function () {
// 缓存已加载的 SpriteFrame,避免重复加载
this._spriteFrames = [];
// 当前显示的小图索引
this._currentIndex = 0;
// 标记资源是否已加载完成
this._loaded = false;
// 开始加载图集中的小图
this._loadSpriteFrames();
},
// 加载图集中的所有小图
_loadSpriteFrames: function () {
var self = this;
var names = this.spriteFrameNames;
var loadedCount = 0;
// 遍历所有需要加载的小图名称
for (var i = 0; i < names.length; i++) {
// 拼接图集内小图的完整路径
var path = "textures/ui/" + names[i] + "/spriteFrame";
// 动态加载 SpriteFrame 资源
cc.resources.load(path, cc.SpriteFrame, function (err, spriteFrame) {
if (err) {
// 错误处理:加载失败时打印错误信息
cc.error("加载 SpriteFrame 失败: " + path + ", 错误: " + err);
return;
}
// 加载成功,缓存 SpriteFrame
self._spriteFrames.push(spriteFrame);
loadedCount++;
// 所有资源加载完成后,显示第一张小图
if (loadedCount === names.length) {
self._loaded = true;
self._applySpriteFrame(0);
}
});
}
},
// 将指定索引的 SpriteFrame 应用到所有 Sprite 节点
_applySpriteFrame: function (index) {
if (!this._loaded || index < 0 || index >= this._spriteFrames.length) {
return;
}
var spriteFrame = this._spriteFrames[index];
// 遍历所有 Sprite 节点,切换 SpriteFrame
for (var i = 0; i < this.spriteNodes.length; i++) {
var sprite = this.spriteNodes[i].getComponent(cc.Sprite);
if (sprite) {
sprite.spriteFrame = spriteFrame;
}
}
this._currentIndex = index;
},
// 切换到下一张小图
next: function () {
if (!this._loaded) {
return;
}
var nextIndex = (this._currentIndex + 1) % this._spriteFrames.length;
this._applySpriteFrame(nextIndex);
},
// 切换到上一张小图
prev: function () {
if (!this._loaded) {
return;
}
var prevIndex = (this._currentIndex – 1 + this._spriteFrames.length) % this._spriteFrames.length;
this._applySpriteFrame(prevIndex);
},
// 组件销毁时释放加载的资源,避免内存泄漏
onDestroy: function () {
for (var i = 0; i < this._spriteFrames.length; i++) {
// 释放 SpriteFrame 资源引用
cc.assetManager.releaseAsset(this._spriteFrames[i]);
}
this._spriteFrames = [];
this._loaded = false;
}
});
上述示例的关键步骤说明:
- 资源加载:通过 cc.resources.load 按图集内小图名称拼接路径,逐个加载 SpriteFrame,并缓存到数组中。
- 错误处理:加载回调中判断 err,失败时打印错误日志并返回,避免后续逻辑访问空资源。
- 切换 SpriteFrame:_applySpriteFrame 方法将指定索引的 SpriteFrame 应用到所有目标 Sprite 节点,支持多个 Sprite 同步切换。
- 内存释放:在 onDestroy 中通过 cc.assetManager.releaseAsset 释放已加载的 SpriteFrame,防止组件销毁后资源残留导致内存泄漏。
7. 动态合图
除了预先制作图集,Cocos Creator 2.2.2 还提供了动态合图能力。动态合图会在运行时自动将散图合并到一张动态图集中,适合无法预先确定图片集合的场景。
动态合图默认开启,可以通过以下代码控制:
// 开启动态合图
cc.dynamicAtlasManager.enabled = true;
// 关闭动态合图
cc.dynamicAtlasManager.enabled = false;
动态合图虽然方便,但也有一些限制:
- 动态图集有最大尺寸限制,超出后无法继续合入。
- 动态合图会增加运行时内存占用。
- 部分特殊纹理(如大尺寸图片、带旋转的纹理)可能无法参与动态合图。
因此,对于 UI 界面等固定资源,建议优先使用预先制作的图集;对于运行时动态生成的图片,再考虑动态合图。
8. 常见问题与注意事项
8.1 图集生成后小图显示黑边
这通常是因为内边距设置过小,导致相邻小图采样时发生渗色。解决方法是将「内边距」调整为 2 或更大,然后重新生成图集。
8.2 图集尺寸超出限制
当散图数量较多或单张图片较大时,图集可能超出最大尺寸限制。此时引擎会自动拆分为多张图集,开发者无需手动处理,但需要注意内存占用会相应增加。
8.3 修改散图后图集未更新
修改散图后,需要重新点击「生成」按钮,图集才会更新。如果使用自动图集,也可以在资源管理器中对图集配置执行「重新生成」操作。
8.4 图集与散图同时存在
如果同一张图片既存在于图集中,又作为散图被引用,Cocos Creator 2.2.2 会优先使用图集中的资源。建议在项目规范中明确资源管理方式,避免重复引用。
9. 总结
本文基于 Cocos Creator 2.2.2,介绍了图集制作的核心流程:从散图准备、自动图集与手动图集的创建、参数配置、生成验证,到代码中的使用方式,以及动态合图的适用场景。掌握图集制作,可以有效减少 Draw Call,提升游戏运行性能。
在实际项目中,建议优先使用自动图集管理 UI 资源,并合理设置内边距和最大尺寸,同时结合动态合图处理运行时动态图片,从而在性能和开发效率之间取得平衡。




