精灵动画预览器
以任意帧率播放精灵图,把循环看清楚,再导出成 GIF 动图—— 而不是等进了引擎才发现第 7 帧偏了一个像素。免费、无需注册, 每一个像素都留在你的浏览器里。
不会上传任何文件——动画在你的浏览器里解码和播放。
怎么预览一段精灵动画
从一张静态的图,到一个你敢用的循环,四步。
- 1载入一张图,或者一组帧单个文件会按网格切开——网格在载入时根据画面内容猜好。多个文件则按名称做数字排序播放, 所以
frame_2排在frame_10前面。 如果连同精灵图一起拖入 Aseprite 的.json, 帧、标签和时长就全都来自那个文件。 - 2猜错了就改一下网格修正列数和行数,给带留白的图补上边距和间距,或者对紧凑图集切到自动识别。 空白格子默认会被跳过。如果导入了 JSON,就没什么可改的—— 文件里已经写明每一帧在哪。
- 3找到合适的帧率和帧范围拖动帧率,直到动作读起来对味,然后收窄帧范围, 把一张塞了好几段动画的图里的某一段单独隔离出来。导入的标签能一次做完这两件事。
- 4导出把这段循环存成 1× 到 8× 的 GIF 动图,或者把当前这一帧单独导成 PNG。
你其实是在检查什么
一张精灵图不告诉你任何关于时间的信息,而动画好不好,大半就取决于时间。 并排看着都没问题的几帧,在 12 fps 下可能读成一顿一顿的,在 24 fps 下又糊成一团。 唯一的判断办法就是让它动起来看。
有三种问题在播放时立刻现形,在静态图上几乎永远看不出来。循环接缝:最后一帧和第一帧太像,于是每转一圈就卡一下。对位错误:某一帧画偏了一个像素,精灵每次转到那儿就抖一下。 以及间隔不匀:两帧干了一帧的活,动作走到一半突然加速。
用左右箭头逐帧点,是找出第二种问题最快的办法。 把帧范围收到两三帧然后让它循环,是找出另外两种最快的办法。
用 Aseprite 自己的时长来播放
帧率是个平均值。Aseprite 存的是每一帧各自的时长,这个差别是看得见的。
在 Aseprite 里走 File → Export Sprite Sheet, 并在 Output 标签页勾上 JSON Data。 把 PNG 和 .json 一起拖进来,会有三件事发生变化。
帧来自文件本身,不是你算出来的网格,也不是一次得靠猜的识别。 帧大小不一、间距不规则、导出时做过裁边——这些都不再要紧。
时长是逐帧的。这一点是单个帧率滑块表达不了的。 走路循环通常会让两个触地帧——脚落地并承重的那两帧——比中间的过渡帧停留更久, 动画师是故意这么做的。用平均 12 fps 播出来,整段就显得很机械。 每一帧停留多久会显示在时间轴对应缩略图的下方, 所以你能看出来是哪几帧被特意多给了时间。
标签会变成动画选择器。选中一个标签会同时设好帧范围和播放方向, 所以乒乓标签直接按乒乓播,倒放标签直接倒着播,你不用去找循环设置。 一张把 idle、walk、attack、hurt 首尾相接塞在一起的图,也不用再手动数帧号。
导出 GIF 时用的是同一套时长,所以下载下来的和你刚才看到的是一致的。 这个格式带来的一个注意点:GIF 的延时以百分之一秒为单位, 所以 Aseprite 里 100ms 的帧是精确的,而 33ms 会被写成 30ms—— 这个取整你不太看得出来,但它确实在。
TexturePacker 的 JSON 也支持。它带帧矩形但没有时长和标签, 所以你能拿到精确的切分,同时保留帧率滑块。
适合像素动画的帧率
大多数手绘像素动画活在 8 到 15 fps 之间。 这不是技术限制,而是一份绘制预算。每一帧都是要有人画出来的, 超过 15 帧之后,多出来的那些不再增加可读的信息,只增加工作量。
快动作是例外:攻击或者冲刺在它持续的那几帧里常跑到 20 至 24 fps, 因为那个动作本来就该显得突兀。待机动作则往另一头走,有时低到 4 至 6 fps。
不管你选了多少,记下来——引擎里要填同一个数。 按 12 fps 做的循环在 Godot 里用 10 fps 播,看着就是有点不对劲, 而你多半会怪到美术头上。
关于 GIF 导出
GIF 就在这个页面里编码,不上传,中间也没有任何服务。 在依赖它之前,这个格式有两个特性值得先知道。
时长被量化到 10ms。GIF 以百分之一秒为单位存每一帧的延时, 所以 10 fps(10cs)和 20 fps(5cs)出来是精确的, 而 12 fps 会被取整成 8cs——在播放器里是 12.5 fps。工具会显示取整后的帧率。 这个格式也快不过 50 fps,而且很多查看器会悄悄把低于 2cs 的延时抬上去。
透明只有一位。一个像素要么完全透明要么完全不透明, 没有半透明。像素画几乎不用半透明,所以这一点很少造成困扰—— 但带柔光或者抗锯齿边缘的精灵,在 GIF 里会出现 PNG 里没有的硬边界。
调色板能放 255 种颜色加一个透明色。像素画通常只用几十种,能原样通过; 带渐变的东西则会被量化下去。
什么时候用得上
检查刚切出来的图
用精灵图切割工具把图拆开之后,在这里播一遍,确认每一刀都落在对的像素上,再导进任何东西。
评估一套素材包
商店的预览图只告诉你帧长什么样,不告诉你它们怎么动。 在围绕它做一个角色之前,先把这张图播一遍。
分享阶段性成果
GIF 在 Discord 里能播,在 issue 里能播,在商店页上也能播。精灵图不能。
隔离出某一段动画
图里常常是 idle、walk、attack 各占一行。 把帧范围收到某一行,一段一段地看。
常见问题
怎么预览精灵图动画?
把图拖进来。网格会根据画面内容猜出来,帧会立刻开始播放,猜错了你再改列数和行数。设好帧率、选好帧范围,在把它塞进引擎之前先把循环看清楚。
能按 Aseprite 原本的逐帧时长播放吗?
能。在 Aseprite 的 Output 标签页勾上 JSON Data 导出,然后把 PNG 和 .json 一起拖进来。每一帧会按 Aseprite 记录的时长停留,而不是套一个平均帧率——这很重要,因为动画师是故意让某些帧停得更久的,走路循环通常会拖长两个触地帧。每一帧停留多久会显示在时间轴缩略图下方,帧标签会变成一个同时设定范围和方向的动画选择器,导出 GIF 时用的也是同一套时长。
能把精灵图转成 GIF 动图吗?
能。设好帧率和帧范围,选一个放大倍数,然后导出。GIF 会无限循环,保留原图的透明通道,并且是在你的浏览器里编码的——文件不会被上传到任何地方。
为什么导出的 GIF 播放速度有点不一样?
GIF 的帧延时以百分之一秒为单位存储,所以它没法精确表达每一种帧率。10 fps 正好是 10cs,出来是准的;12 fps 会被取整成 8cs,也就是 12.5 fps。工具会在导出按钮旁边显示取整后的实际帧率。另外 GIF 最快也只能到 50 fps。
能预览一组单独的帧,而不是一整张图吗?
可以——一次把它们全选进来。它们会按文件名做数字排序,所以就算没补零,frame_2 也排在 frame_10 前面。只拖入一个文件时,它会被当成一张精灵图来处理。
精灵动画该用多少帧率?
手绘像素动画通常在 8 到 15 fps 之间——足以读成连贯动作,帧数又少到画得完。攻击这类快动作常跑到 20 至 24。再高就是在画没人看得见的帧了。
什么是乒乓循环?
动画播到最后一帧后倒着播回开头,而不是直接跳回去。它适合呼吸待机、漂浮平台,以及任何对称的动作,还能把要画的帧数省掉一半。走路循环则不该用它——那种动作需要干净地正向循环。
我的文件会被上传到服务器吗?
不会。这张图的解码、切割、播放和 GIF 编码全部由浏览器 API 完成。什么都不会离开你的电脑,页面加载完之后断网也照样能用。
相关教程
如何把精灵图转成 GIF
网格、逐帧时长、透明通道——以及这个格式本身的硬限制。
如何在 Godot 中导入精灵图
用 AnimatedSprite2D 切帧、关掉模糊,并知道 Godot 什么时候切不动。
如何在 Unity 中导入精灵图
Sprite Mode、Sprite Editor 的三种切法,以及那些会悄悄毁掉像素画的导入设置。
如何在 Phaser 中加载精灵图
spritesheet 与 atlas 之争、以像素为单位的 frameWidth、generateFrameNumbers,以及 file:// 下为什么什么都加载不出来。
怎么修精灵表切图错位
拿第一帧和最后一帧比。误差涨不涨,直接告诉你是四种里的哪一种。