Colin McMillen
4 years ago
4 changed files with 95 additions and 7 deletions
@ -0,0 +1,89 @@ |
|||||
|
using Microsoft.Xna.Framework; |
||||
|
using Microsoft.Xna.Framework.Content; |
||||
|
using Newtonsoft.Json.Linq; |
||||
|
using System.Collections.Generic; |
||||
|
|
||||
|
namespace SemiColinGames { |
||||
|
struct SpriteAnimation { |
||||
|
public readonly int Start; |
||||
|
public readonly int End; |
||||
|
public readonly int DurationMs; |
||||
|
|
||||
|
public SpriteAnimation(int start, int end, int durationMs) { |
||||
|
Start = start; |
||||
|
End = end; |
||||
|
DurationMs = durationMs; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
struct Frame { |
||||
|
public readonly Rectangle Source; |
||||
|
public readonly int DurationMs; |
||||
|
|
||||
|
public Frame(Rectangle source, int durationMs) { |
||||
|
Source = source; |
||||
|
DurationMs = durationMs; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
class Sprite { |
||||
|
public readonly TextureRef Texture; |
||||
|
|
||||
|
private readonly Dictionary<string, SpriteAnimation> animations; |
||||
|
private readonly List<Frame> frames; |
||||
|
|
||||
|
public Sprite(TextureRef texture, string metadataJson) { |
||||
|
Texture = texture; |
||||
|
animations = new Dictionary<string, SpriteAnimation>(); |
||||
|
|
||||
|
JObject json = JObject.Parse(metadataJson); |
||||
|
|
||||
|
frames = new List<Frame>(); |
||||
|
foreach (JToken child in json.SelectToken("frames").Children()) { |
||||
|
Rectangle source = new Rectangle( |
||||
|
child.SelectToken("frame.x").Value<int>(), |
||||
|
child.SelectToken("frame.y").Value<int>(), |
||||
|
child.SelectToken("frame.w").Value<int>(), |
||||
|
child.SelectToken("frame.h").Value<int>()); |
||||
|
int durationMs = child.SelectToken("duration").Value<int>(); |
||||
|
frames.Add(new Frame(source, durationMs)); |
||||
|
} |
||||
|
|
||||
|
// TODO: handle ping-pong animations.
|
||||
|
JToken frameTags = json.SelectToken("meta.frameTags"); |
||||
|
foreach (JToken child in frameTags.Children()) { |
||||
|
string name = child.SelectToken("name").Value<string>(); |
||||
|
int start = child.SelectToken("from").Value<int>(); |
||||
|
int end = child.SelectToken("to").Value<int>(); |
||||
|
int durationMs = 0; |
||||
|
for (int i = start; i <= end; i++) { |
||||
|
durationMs += frames[i].DurationMs; |
||||
|
} |
||||
|
animations[name] = new SpriteAnimation(start, end, durationMs); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public Rectangle GetTextureSource(string animationName, int timeMs) { |
||||
|
SpriteAnimation animation = animations[animationName]; |
||||
|
int time = timeMs % animation.DurationMs; |
||||
|
for (int i = animation.Start; i <= animation.End; i++) { |
||||
|
int frameTime = frames[i].DurationMs; |
||||
|
if (time < frameTime) { |
||||
|
return frames[i].Source; |
||||
|
} |
||||
|
time -= frameTime; |
||||
|
} |
||||
|
// We shouldn't get here, but if we did, the last frame is a fine thing to return.
|
||||
|
return frames[animation.End].Source; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
static class Sprites { |
||||
|
public static Sprite Executioner; |
||||
|
|
||||
|
public static void Load(ContentManager content) { |
||||
|
Executioner = new Sprite( |
||||
|
Textures.Executioner, content.Load<string>("sprites/ccg/executioner_female_json")); |
||||
|
} |
||||
|
} |
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue