
本文目录
精灵图(sprite sheet)把一段动画的所有帧放进同一张图片,通常按网格排列,再配一个小数据文件,记录每一帧在图中的位置和显示时长。游戏引擎只加载这一张图,播放时每次画出其中一格。
具体怎么做,取决于手里已经有什么。帧已经是一张张独立的 PNG,只需要拼起来;动作在一段视频里,要先选出范围再按帧率取帧;如果只有一张角色图,就得先把动画做出来。
2026 年 10 月 8 日,我们用可下载的真实文件把三种情况都走了一遍:在免费的 sprite sheet maker 里拼合 16 帧橙色机器人跑步动画;用免费的 视频转精灵图工具 转换一段 4 秒透明 WebM;再回头说明这组机器人帧最初是怎样用 AI 生成的。两个免费工具都在浏览器里运行,文件不离开你的电脑,也不需要注册。工具界面目前为英文。
精灵图文件里有什么
机器人跑步共 16 帧,每帧 376 × 280 像素。每行放 4 帧,得到一张 1504 × 1120 的 PNG。
单看 PNG,无法知道一帧在哪里结束、下一帧从哪里开始,这要靠旁边的 JSON。下面是 sprite sheet maker 导出文件中第六帧的条目和整张图的信息:
{
"frames": {
"frame_0005.png": {
"frame": { "x": 376, "y": 280, "w": 376, "h": 280 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 376, "h": 280 },
"sourceSize": { "w": 376, "h": 280 },
"duration": 42
}
},
"meta": {
"image": "robot-run-spritesheet.png",
"size": { "w": 1504, "h": 1120 },
"frameTags": [{ "name": "robot-run", "from": 0, "to": 15, "direction": "forward" }],
"animgen": { "frameCount": 16, "frameDurationMs": 42, "durationMs": 672, "fps": 23.81, "loop": true }
}
}
frame是要从图中切出的矩形,以左上角为原点,单位为像素。duration是这一帧停留的毫秒数。frameTags把一段连续帧命名为一个动作。一张图里有多个动作时,每个动作各有一个标签。spriteSourceSize和sourceSize只在帧被裁切过时起作用,用来告诉引擎把裁切后的帧放回原画布的哪个位置。
字段名与 Aseprite 的 hash 格式 JSON 导出一致,已经能读取 Aseprite 精灵图的代码可以直接读取它。animgen 是附加信息,可以忽略。
时长以整数毫秒保存。24 FPS 下每帧约 41.67 毫秒,写入时取整为 42,所以 16 帧合计 672 毫秒,而不是 667 毫秒,这也是 fps 显示 23.81 的原因。一个循环相差 5 毫秒。如果动画需要和音效或其他动画严格同步,就在引擎里把片段速度直接设为 24 FPS,不要累加每帧时长。
用现成的帧拼成精灵图
这条路线适合动画已经是一张张独立图片的情况:Krita 用「渲染动画」导出的图像序列、AnimGen 导出的 PNG 帧 ZIP、3D 软件的渲染结果,或者别人发来的一整个文件夹。如果你在 Aseprite 里绘制,它自带的 File → Export Sprite Sheet 能直接写出 PNG 和 JSON,不必再用拼图工具。
想跟着做,可以下载这 16 帧机器人素材(ZIP,700 KB)。文件名是 robot-run-1.png 到 robot-run-16.png,序号没有补零,很多真实导出就是这样命名的。
- 打开 sprite sheet maker,拖入文件,或者直接选择整个文件夹。
- 检查顺序。按字母排序时,
robot-run-10.png会紧跟在robot-run-1.png后面;这个工具按文件名中的数字排序,实测排出的顺序是 1 到 16。帧也可以拖动调整、删除或整体倒序。 - 设置速度。它决定预览速度,也决定写进 JSON 的时长。我们用的是 24 FPS,也就是这段机器人动画生成时的帧率。
- 设置列数。16 帧默认 4 列,得到方正的 4 × 4 网格。
- 下载精灵图 PNG 和 JSON。同一组帧还能导出动图 GIF,方便分享。
我们把导出的精灵图解码后,逐格和对应源帧比较:16 帧的 Alpha 完全一致,所有完全不透明像素的颜色也完全一致;半透明边缘像素的颜色最多相差 1 级(满级 255),原因是浏览器画布按预乘 Alpha 保存颜色。导出的 PNG、对应的 JSON 和带 SHA-256 的测量记录都可以下载核对。
如果动画是 GIF 动图,也可以直接拖进这个工具:GIF 的每一帧成为一格,速度取自 GIF 的帧延迟。
帧共用同一画布时,不要勾选裁切
工具里的 Trim empty space around each frame 选项会裁掉每帧周围的空白。用在这组机器人帧上,每格缩小到 163 × 190,整张图变成 652 × 760,像素数减少 71%。PNG 文件却只从 785.0 KB 降到 736.7 KB,因为完全透明的区域本来就几乎不占压缩后的体积。
裁切会把每一帧按各自的包围盒裁小,再按底部居中对齐。这段跑步里机器人有离地的瞬间,身体最低点在各帧之间有 22 像素的起伏。裁切之后每一帧都贴着格子底边,弹跳感消失;手臂和腿摆动时包围盒宽度在变,身体还会左右偏移,最多 16 像素。
同一个动画软件导出的帧通常共用一块画布,这块画布本身就记录了角色站在哪里,应当保留。裁切适合尺寸各不相同的帧,例如从旧精灵图里抠出来的素材,这时底部居中对齐能让脚重新落在同一条线上。
2 的幂尺寸与间距
勾选 Round the sheet up to power-of-two sizes(按 2 的幂取整)后,1504 × 1120 变成 2048 × 2048。PNG 只从 785.0 KB 增加到 843.6 KB,但按每像素 4 字节解码后,纹理从 6.4 MiB 增加到 16 MiB。只有目标平台需要时才打开,例如旧款 iOS 设备上的 PVRTC 压缩,或 WebGL 1 中的 mipmap。现在的大多数 2D 引擎都接受任意尺寸。
间距会在格子之间加入透明像素。开启线性过滤或 mipmap 时,GPU 可能越过格子边界采样一两个像素,在边缘显示出相邻帧的细线。这组机器人帧四周至少有 39 像素的透明边,间距为 0 没有问题。如果帧裁得很紧,就加两三像素间距,并在引擎切图时填写同样的分隔值。
把视频片段转成精灵图
这条路线适合动作存在于视频中的情况:录屏、渲染出的片段、绿幕视频,或者保存成 MP4、WebM 的生成动画。
我们使用转换工具自带的示例:一段 640 × 640 的 WebM,青色小人在跑,时长 4.00 秒,背景透明(源视频)。
- 打开 视频转精灵图工具,拖入视频,时间线会显示缩略图。
- 拖动两端手柄框住需要的动作,按 Play range 循环预览。我们保留了 2.50 到 3.83 秒的跑步。
- 选择帧率和帧宽。12 FPS 下,这 1.33 秒得到 16 帧;帧宽 256 像素时,输出 4 × 4 网格、1024 × 1024 像素、560.1 KB 的精灵图。
- 下载精灵图 PNG 和 JSON,或者带编号的 PNG 帧 ZIP。
源视频是 24 FPS,选 12 FPS 相当于隔一帧取一帧;选 24 FPS 会保留全部帧,帧数翻倍为 32。做循环动画时,在 Play range 里留意最后一帧跳回第一帧的那一下:如果有明显卡顿,就把起点或终点前后挪一帧。
这段 WebM 自带透明通道,取出的帧会保留透明;MP4 没有 Alpha 通道。如果视频是在纯色或绿幕背景前拍的,工具会识别这个颜色并可以去除,提供容差和边缘清理等控制。头发、烟雾、动态模糊这类细节在绿幕上需要真正的抠像,免费工具做不到。
从一张角色图生成动画
第三条路线的起点只有一张图,没有任何动作。上面用到的机器人帧就是这样做出来的:一张 1254 × 1254 的机器人 PNG,提示词要求角色朝右持续原地跑步,镜头固定、比例一致。请求使用 Seedance 2.0 Fast、4 秒、480p 和 Alpha Key,2026 年 10 月 3 日实际花费 36 积分,返回 752 × 560、24 FPS、共 97 帧的视频。
我们从这 97 帧里选了第 44 到 59 帧作为循环,为本文缩小一半到 376 × 280。可操作角色那篇文章 提供了完整提示词、原始键色视频,以及循环范围是怎么选出来的;行走循环那篇 更详细地讲了如何找到干净的循环。
在 AnimGen 里生成的动画,导出时就能直接得到带 JSON 的精灵图,或者 Godot、Unity、Unreal Paper2D、Cocos Creator、Construct 3 的资源包(见输出格式)。只有在别处先修改过帧时,才需要再用免费拼图工具。积分消耗随模型和设置变化,生成前请以页面显示的报价和当前价格为准。
把精灵图导入 Godot 4 或 Unity
Godot 4。 添加一个 AnimatedSprite2D 节点,在它的 Sprite Frames 属性里新建 SpriteFrames 资源。在编辑器底部的 SpriteFrames 面板中点 Add frames from a Sprite Sheet,选择 PNG,把 Horizontal 和 Vertical 都设为 4。用了间距的话,把它填进 Separation。选中 16 格,点 Add 16 frames,再把动画速度设为 24 FPS 并打开循环。Godot 的 2D 精灵动画教程 里有同一个对话框。间距为 0 的精灵图也可以用普通 Sprite2D,设 hframes = 4、vframes = 4,再在代码里切换 frame。
Unity。 选中 PNG,把 Texture Type 设为 Sprite (2D and UI),Sprite Mode 设为 Multiple;像素画还要把 Filter Mode 设为 Point。打开 Sprite Editor,选择 Slice,Type 设为 Grid By Cell Size,尺寸 376 × 280,轴点设为底部中心,然后应用。按顺序选中 16 个 sprite,建立一个每秒 24 采样的动画片段。Unity 的 Sprite Editor 指南 介绍了各种切图选项。
如果最后一行没有排满,比如 15 帧放进 4 × 4 网格,两个引擎都会为空位生成一格,别把它加进动画。AnimGen 自己的 Godot 和 Unity 资源包省去了这一步手动操作,Godot 4 导入实测 在真实运行的项目里检查过其中一个。
使用精灵图之前要检查的问题
| 看到的现象 | 可能原因 | 处理方法 |
|---|---|---|
| 帧的播放顺序乱了 | 文件名序号没有补零,又按字母排序 | 按文件名中的数字排序,或导出时使用 run_0001.png 这样补零的名字 |
| 角色左右滑动或失去弹跳 | 每帧单独裁切并重新居中 | 帧共用同一画布时关闭裁切 |
| 边缘出现相邻帧的细线 | 没有间距,线性过滤跨格采样 | 加间距并在引擎里填写相同分隔值,像素画改用点过滤 |
| 部分设备拒绝加载或显示空白 | 纹理超过设备允许的最大尺寸 | 缩小帧宽、减少帧数,或把动画拆成几张精灵图 |
| 每个循环卡一下 | 首尾两帧是同一个姿势,或范围截在半步上 | 删掉重复帧,或把范围挪动一帧 |
关于尺寸上限:4096 × 4096 是移动端和 WebGL 常用的保守上限。精灵图与 PNG 序列对比 实测了一张超过这个上限的 5120 × 5120 精灵图,并给出了拆分方法。
关于制作精灵图的常见问题
有免费的精灵图制作工具吗?
本文用到的 sprite sheet maker 和视频转精灵图工具 都免费,在浏览器中运行,不需要账号。其他免费精灵图工具 可以转换 GIF、把现有精灵图切开,或者把精灵图转回 GIF。如果你本来就用 Aseprite,它自带的导出功能就能完成拼图。商业图集打包软件 TexturePacker 提供多边形打包和针对各引擎的导出器,这些功能在打包大量不同精灵的大图集时更有用,单个动画用不太到。
ChatGPT 能做精灵图吗?
图像模型可以在一张图里按网格画出角色的多个姿势。本文没有测试 ChatGPT。使用这种图片之前,请检查:每格尺寸是否相同,角色在各格之间的比例和体型是否一致,姿势有没有伸进相邻格子,背景是否透明或是能去掉的单一颜色。精灵图切割工具 可以把这类图片切成独立的帧,并按统一帧尺寸重新排列。如果想从角色图生成真正连续的动作并导出为帧,请走上文的 AI 路线。
精灵图是什么格式?
通常是 PNG,因为它能保留透明且不损失细节,再加一个数据文件。自写代码和网页游戏最常用 JSON;各引擎也有自己的格式,例如带切片矩形的 Unity .meta 文件、Godot 的 SpriteFrames 资源、Cocos Creator 的 .plist。选择你的引擎或加载器能读取的格式,并让 PNG 和数据文件始终放在一起。
想完整走一遍,可以下载机器人帧素材,在 sprite sheet maker 里拼成精灵图,再按上面的步骤导入你的引擎。如果手上只有角色、还没有动画,可以从 AnimGen 工作台 开始,在那里直接导出精灵图。