一套用于快速构造、分析、修改动画数据的代码,本来应该是作为库提供的,但是本人太懒导致一直没有进度,所以先将源代码发出来供大家参考。
下面的代码仅作为示例,如果有什么其他需要的功能可以在 Issue 里面提。
目前暂时不支持动画中直接使用 & 字符,请遵循 xml 规范。
下面的代码会将名字为 anim_ 开头的轨道作为控制轨道,然后依次分析所有的图层是否在每个控制轨道下第一帧和最后一帧相同,不同的图层和轨道名会显示在黑窗口中。
if (!Analyzer.Analyze(path))
{
Console.WriteLine("The input reanim has no error!");
}下面的代码会创造逐帧动画,动画帧率和图像名字按自己动画的格式准备就行了。
ReanimatorDefinition aReanim = new ReanimatorDefinition();
aReanim.Fps = 12f;
Analyzer.AttachFrameAnimation(aReanim, "anim_idle", [.. from i in Enumerable.Range(0, 20) select $"IMAGE_REANIM_PEASHOOTER_IDLE_{i:000}"], new Vector2(-30f, -20f), new Vector2(0.6f, 0.6f));
Analyzer.AttachFrameAnimation(aReanim, "anim_shooting", [.. from i in Enumerable.Range(0, 35) where i is not (> 5 and < 15) select $"IMAGE_REANIM_PEASHOOTER_SHOOTING_{i:000}"], new Vector2(-20f, -10f), new Vector2(0.7f, 0.7f));
using FileStream fs = File.Create(path);
XmlReanimCoder.Encode(aReanim, fs);AttachFrameAnimation 传入的两个向量分别代表位置和缩放倍率。
此场景假设你将某动画在游戏内使用的图像宽度和高度分别修改为现有的 2 倍,然后通过下面的代码修改动画里面写的缩放倍率。
ReanimatorDefinition aReanim = XmlReanimCoder.Decode(path);
Analyzer.ScaleTrack(aReanim, 0.5f, static t => true);
XmlReanimCoder.Encode(aReanim, path);ScaleTrack 传入的委托可以用来决定每个图层是否被缩放。缩放中心为每个图像的左上角。如果需要以图像其他位置作为中心进行缩放,请自行读取图像的宽度和高度,并对图像位置进行重新计算。
下面的代码会给动画创建一个新的控制轨道。
ReanimatorDefinition aReanim = XmlReanimCoder.Decode(path);
Analyzer.AttachAnimAnimation(aReanim, "anim_idle", 0, 30);
XmlReanimCoder.Encode(aReanim, path);下面的代码会将图层向右平移 2 个单位长度,然后将名称不为 Head 的图层位置缩放到原来的 0.5 倍。
ReanimatorDefinition aReanim = XmlReanimCoder.Decode(path);
Analyzer.MoveTrackTransform(aReanim, 2, 0, static t => true);
Analyzer.ScaleTrackTransform(aReanim, 0.5f, static t => t.Name != "Head");
XmlReanimCoder.Encode(aReanim, path);位置缩放倍率和缩放倍率的区别是,前者只针对位置进行缩放而不改变图像大小,后者只针对图像大小进行缩放而不改变位置。前者的缩放中心点是坐标原点,如果需要以其他点作为中心进行缩放,请先将缩放中心平移到原点,再进行缩放,然后反向平移相同的距离。
下面的代码将动画中的第 0 帧复制到第 60 帧,原来的第 60 帧和后续帧会向后移动 1 帧。
ReanimatorDefinition aReanim = XmlReanimCoder.Decode(path);
Analyzer.CopyFrame(aReanim, 0, 60);
XmlReanimCoder.Encode(aReanim, path);下面的代码将一张图像(僵尸下巴)向左平移 10 个单位,这 10 个单位是相对于这张图自己的坐标系而言的,而不是相对于动画坐标系,利用这种方法可以很快将一个动画里的某张图向左或向上进行扩展。其中 FillInMissingData 函数填充轨道的缺省数据,DeleteRepeatData 函数重新将可缺省的数据设置为缺省。具体原理是借助矩阵,这里使用行向量,仿射变换矩阵需要通过右乘来叠加。先创建一个表示向左平移 10 个单位的矩阵,再右乘原仿射变换矩阵,即可将图像在自己的坐标系下向左平移 10 个单位。
ReanimatorDefinition aReanim = XmlReanimCoder.Decode(path);
var track = aReanim.Tracks.Find(t => t.Name == "anim_head2")!;
ReanimHelper.FillInMissingData(track);
foreach (var transform in track.Transforms)
{
Matrix3x2 aMat = transform.ToMatrix();
aMat = Matrix3x2.CreateTranslation(-10, 0) * aMat;
transform.SetValue(ref aMat);
}
ReanimHelper.DeleteRepeatData(track);
XmlReanimCoder.Encode(aReanim, path);