Silverlight 中的 Sprite sheet 动画
Sprite sheet animation in Silverlight
我正在尝试使用 C# 在 Silverlight 中制作精灵 sheet 的动画。
我取得了很大进步,动画效果很好,但问题是它们在 sheet 之间不一致。例如,我有这 3 个 sheets:
http://pokit.org/get/?8fc4562a63e6d7918789b0c84776a751.jpg
http://pokit.org/get/?ff4a073a307d50a7b950ac8dab26d60f.jpg
http://pokit.org/get/?053f25308d6a85a635913eb3f26f1c9f.jpg
前两个动画很好,但是当最后一个动画时,我看到其他帧的部分内容,如下所示:
http://pokit.org/get/?9c0dc2266b0a84a2243daf4db5b7217a.jpg
这是我用来为 sheet 设置动画的代码:(宽度和高度是我之前确定的特定帧的尺寸)
public class Animation
{
private const int timeAnimationConstant = 10;
private const int marginConstant = -11;
private const int divisionConstant = 30;
private const int frameTimeConstantMS = 150;
public Animation() {
}
/* Funkcija koja radi animaciju bilo čega - prima containter(Rectangle s forme), sheet koji animira, sirinu sheeta,
* visinu sheeta, broje frameova u sheetu, i status(statička, dinamička), loop - da li je repeatat?, repetitions koliko puta? */
public void Animate(Rectangle container, AnimationParams parameters) {
// komit komentar
ImageBrush imageBrush = new ImageBrush() { Stretch = Stretch.None, AlignmentX = AlignmentX.Left, AlignmentY = AlignmentY.Top };
imageBrush.Transform = new CompositeTransform();
imageBrush.ImageSource = parameters.Sheet; /* Ovdje pretpostavljam da smo po uzecu iz baze formirali BitmapImage tip i proslijedili */
container.Margin = new Thickness(marginConstant, 0, marginConstant, 0);
container.Width = parameters.Width + parameters.Width/divisionConstant;
container.Height = parameters.Height + parameters.Height/(divisionConstant/3);
container.Stroke = new SolidColorBrush(Colors.Transparent);
container.Fill = imageBrush;
container.RadiusX = 5;
container.RadiusY = 5;
// Storyboard za animaciju
Storyboard sb = new Storyboard();
if(parameters.Loop ) sb.RepeatBehavior = RepeatBehavior.Forever; // odredjujem da li je na repeat
ObjectAnimationUsingKeyFrames frm = new ObjectAnimationUsingKeyFrames(); // inicijaliziram frameove animacije
frm.BeginTime = new TimeSpan(0, 0, 0);
int time = 0; // vrijeme kojim odredjujem trajanja frameova
if (parameters.IsStatic == true)
{
// Statička animacija
for (int j = 0; j < parameters.Repetitions; j++)
{
for (int i = 0; i < parameters.NumberOfFrames; i++)
{
DiscreteObjectKeyFrame dokf = new DiscreteObjectKeyFrame();
dokf.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(time));
dokf.Value = -(i * parameters.Width);
frm.KeyFrames.Add(dokf);
time += parameters.NumberOfFrames * timeAnimationConstant;
}
}
KidCode.Game.isAnimationComplete = true;
}
else {
// Dinamicka animacija
}
Storyboard.SetTarget(frm, container.Fill);
Storyboard.SetTargetProperty(frm, new PropertyPath("(ImageBrush.Transform).(CompositeTransform.TranslateX)"));
sb.Children.Add(frm);
sb.Begin();
}
AnimationParams class,以防万一:
public class AnimationParams
{
public BitmapImage Sheet { get; set; }
public int Width { get; set; }
public int Height { get; set; }
public int NumberOfFrames { get; set;}
public bool IsStatic { get; set; }
public bool Loop { get; set; }
public int Repetitions { get; set; }
public AnimationParams(BitmapImage sheet, int width, int height, int numberOfFrames, bool isStatic, bool loop = false, int repetitions = 1) {
Sheet = sheet;
Width = width;
Height = height;
NumberOfFrames = numberOfFrames;
IsStatic = isStatic;
Loop = loop;
Repetitions = repetitions;
}
}
希望有人能帮助我,在此先感谢。
您的动画代码使用参数中的宽度来了解如何裁剪精灵:
dokf.Value = -(i * parameters.Width);
伪造的 tileset 为 1365 像素宽,9 帧。所以需要设置宽度为1365 / 9 = 151像素。
我认为问题出在图片本身。我试图用相同的宽度绘制每个框架的边框,这是不可能的。
我试过 233 像素宽度:
151 像素(由 KooKiz 建议)也不起作用:
所以,我修改了整个图像,剪切了所有的帧,设置一个宽度(181 像素)并再次加入它们。那是结果:
这是我的解决方案。使用下面的图片(你知道的,右键单击,另存为...)并将框架的宽度设置为 181 像素:
有趣的事实:图像的高度是 170 像素,而不是 218...
我正在尝试使用 C# 在 Silverlight 中制作精灵 sheet 的动画。 我取得了很大进步,动画效果很好,但问题是它们在 sheet 之间不一致。例如,我有这 3 个 sheets:
http://pokit.org/get/?8fc4562a63e6d7918789b0c84776a751.jpg
http://pokit.org/get/?ff4a073a307d50a7b950ac8dab26d60f.jpg
http://pokit.org/get/?053f25308d6a85a635913eb3f26f1c9f.jpg
前两个动画很好,但是当最后一个动画时,我看到其他帧的部分内容,如下所示:
http://pokit.org/get/?9c0dc2266b0a84a2243daf4db5b7217a.jpg
这是我用来为 sheet 设置动画的代码:(宽度和高度是我之前确定的特定帧的尺寸)
public class Animation
{
private const int timeAnimationConstant = 10;
private const int marginConstant = -11;
private const int divisionConstant = 30;
private const int frameTimeConstantMS = 150;
public Animation() {
}
/* Funkcija koja radi animaciju bilo čega - prima containter(Rectangle s forme), sheet koji animira, sirinu sheeta,
* visinu sheeta, broje frameova u sheetu, i status(statička, dinamička), loop - da li je repeatat?, repetitions koliko puta? */
public void Animate(Rectangle container, AnimationParams parameters) {
// komit komentar
ImageBrush imageBrush = new ImageBrush() { Stretch = Stretch.None, AlignmentX = AlignmentX.Left, AlignmentY = AlignmentY.Top };
imageBrush.Transform = new CompositeTransform();
imageBrush.ImageSource = parameters.Sheet; /* Ovdje pretpostavljam da smo po uzecu iz baze formirali BitmapImage tip i proslijedili */
container.Margin = new Thickness(marginConstant, 0, marginConstant, 0);
container.Width = parameters.Width + parameters.Width/divisionConstant;
container.Height = parameters.Height + parameters.Height/(divisionConstant/3);
container.Stroke = new SolidColorBrush(Colors.Transparent);
container.Fill = imageBrush;
container.RadiusX = 5;
container.RadiusY = 5;
// Storyboard za animaciju
Storyboard sb = new Storyboard();
if(parameters.Loop ) sb.RepeatBehavior = RepeatBehavior.Forever; // odredjujem da li je na repeat
ObjectAnimationUsingKeyFrames frm = new ObjectAnimationUsingKeyFrames(); // inicijaliziram frameove animacije
frm.BeginTime = new TimeSpan(0, 0, 0);
int time = 0; // vrijeme kojim odredjujem trajanja frameova
if (parameters.IsStatic == true)
{
// Statička animacija
for (int j = 0; j < parameters.Repetitions; j++)
{
for (int i = 0; i < parameters.NumberOfFrames; i++)
{
DiscreteObjectKeyFrame dokf = new DiscreteObjectKeyFrame();
dokf.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(time));
dokf.Value = -(i * parameters.Width);
frm.KeyFrames.Add(dokf);
time += parameters.NumberOfFrames * timeAnimationConstant;
}
}
KidCode.Game.isAnimationComplete = true;
}
else {
// Dinamicka animacija
}
Storyboard.SetTarget(frm, container.Fill);
Storyboard.SetTargetProperty(frm, new PropertyPath("(ImageBrush.Transform).(CompositeTransform.TranslateX)"));
sb.Children.Add(frm);
sb.Begin();
}
AnimationParams class,以防万一:
public class AnimationParams
{
public BitmapImage Sheet { get; set; }
public int Width { get; set; }
public int Height { get; set; }
public int NumberOfFrames { get; set;}
public bool IsStatic { get; set; }
public bool Loop { get; set; }
public int Repetitions { get; set; }
public AnimationParams(BitmapImage sheet, int width, int height, int numberOfFrames, bool isStatic, bool loop = false, int repetitions = 1) {
Sheet = sheet;
Width = width;
Height = height;
NumberOfFrames = numberOfFrames;
IsStatic = isStatic;
Loop = loop;
Repetitions = repetitions;
}
}
希望有人能帮助我,在此先感谢。
您的动画代码使用参数中的宽度来了解如何裁剪精灵:
dokf.Value = -(i * parameters.Width);
伪造的 tileset 为 1365 像素宽,9 帧。所以需要设置宽度为1365 / 9 = 151像素。
我认为问题出在图片本身。我试图用相同的宽度绘制每个框架的边框,这是不可能的。
我试过 233 像素宽度:
151 像素(由 KooKiz 建议)也不起作用:
所以,我修改了整个图像,剪切了所有的帧,设置一个宽度(181 像素)并再次加入它们。那是结果:
这是我的解决方案。使用下面的图片(你知道的,右键单击,另存为...)并将框架的宽度设置为 181 像素:
有趣的事实:图像的高度是 170 像素,而不是 218...