|
|
@ -24,24 +24,24 @@ namespace SemiColinGames { |
|
|
|
struct SpriteAnimation { |
|
|
|
public readonly int Start; |
|
|
|
public readonly int End; |
|
|
|
public readonly int DurationMs; |
|
|
|
public readonly double Duration; |
|
|
|
public readonly AnimationDirection Direction; |
|
|
|
|
|
|
|
public SpriteAnimation(int start, int end, int durationMs, AnimationDirection direction) { |
|
|
|
public SpriteAnimation(int start, int end, double duration, AnimationDirection direction) { |
|
|
|
Start = start; |
|
|
|
End = end; |
|
|
|
DurationMs = durationMs; |
|
|
|
Duration = duration; |
|
|
|
Direction = direction; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
struct Frame { |
|
|
|
public readonly Rectangle Source; |
|
|
|
public readonly int DurationMs; |
|
|
|
public readonly double Duration; |
|
|
|
|
|
|
|
public Frame(Rectangle source, int durationMs) { |
|
|
|
public Frame(Rectangle source, double duration) { |
|
|
|
Source = source; |
|
|
|
DurationMs = durationMs; |
|
|
|
Duration = duration; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@ -64,9 +64,8 @@ namespace SemiColinGames { |
|
|
|
child.SelectToken("frame.y").Value<int>(), |
|
|
|
child.SelectToken("frame.w").Value<int>(), |
|
|
|
child.SelectToken("frame.h").Value<int>()); |
|
|
|
// TODO: convert all durations to floats.
|
|
|
|
int durationMs = child.SelectToken("duration").Value<int>(); |
|
|
|
frames.Add(new Frame(source, durationMs)); |
|
|
|
double duration = child.SelectToken("duration").Value<double>() / 1000; |
|
|
|
frames.Add(new Frame(source, duration)); |
|
|
|
} |
|
|
|
|
|
|
|
JToken frameTags = json.SelectToken("meta.frameTags"); |
|
|
@ -77,25 +76,25 @@ namespace SemiColinGames { |
|
|
|
string directionString = child.SelectToken("direction").Value<string>(); |
|
|
|
AnimationDirection direction = directionString == "pingpong" ? |
|
|
|
AnimationDirection.PingPong : AnimationDirection.Forward; |
|
|
|
int durationMs = 0; |
|
|
|
double duration = 0; |
|
|
|
for (int i = start; i <= end; i++) { |
|
|
|
durationMs += frames[i].DurationMs; |
|
|
|
duration += frames[i].Duration; |
|
|
|
} |
|
|
|
// A PingPong animation repeats every frame but the first and last.
|
|
|
|
// Therefore its duration is 2x, minus the duration of the first and last frames.
|
|
|
|
if (direction == AnimationDirection.PingPong) { |
|
|
|
durationMs = durationMs * 2 - frames[start].DurationMs - frames[end].DurationMs; |
|
|
|
duration = duration * 2 - frames[start].Duration - frames[end].Duration; |
|
|
|
} |
|
|
|
|
|
|
|
animations[name] = new SpriteAnimation(start, end, durationMs, direction); |
|
|
|
animations[name] = new SpriteAnimation(start, end, duration, direction); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public Rectangle GetTextureSource(string animationName, int timeMs) { |
|
|
|
public Rectangle GetTextureSource(string animationName, double time) { |
|
|
|
SpriteAnimation animation = animations[animationName]; |
|
|
|
int time = timeMs % animation.DurationMs; |
|
|
|
time %= animation.Duration; |
|
|
|
for (int i = animation.Start; i <= animation.End; i++) { |
|
|
|
int frameTime = frames[i].DurationMs; |
|
|
|
double frameTime = frames[i].Duration; |
|
|
|
if (time < frameTime) { |
|
|
|
return frames[i].Source; |
|
|
|
} |
|
|
@ -103,7 +102,7 @@ namespace SemiColinGames { |
|
|
|
} |
|
|
|
if (animation.Direction == AnimationDirection.PingPong) { |
|
|
|
for (int i = animation.End - 1; i > animation.Start; i--) { |
|
|
|
int frameTime = frames[i].DurationMs; |
|
|
|
double frameTime = frames[i].Duration; |
|
|
|
if (time < frameTime) { |
|
|
|
return frames[i].Source; |
|
|
|
} |
|
|
|