1 module prova.assets.sprites.asespritesheet;
2 
3 import prova.assets;
4 import std.json;
5 import std.file;
6 import std.path;
7 
8 /// Uses sprite sheets generated from Aseprite
9 class AseSpriteSheet : SpriteSheet
10 {
11   /**
12    * JSON file should have the same name and be in the same folder
13    * 
14    * Params:
15    *   path = Path of the image file
16    */
17   this(string path)
18   {
19     string jsonPath = stripExtension(path) ~ ".json";
20     string jsonString = readText(jsonPath);
21     JSONValue json = parseJSON(jsonString);
22 
23     JSONValue framesObject = json["frames"];
24     JSONValue metaObject = json["meta"].object;
25     JSONValue frameTagsObject = metaObject["frameTags"];
26 
27     frames = getFrames(framesObject);
28     animations = getAnimations(frameTagsObject, frames);
29     texture = new Texture(path);
30   }
31 
32   private SpriteFrame[] getFrames(JSONValue framesObject)
33   {
34     SpriteFrame[] frames;
35 
36     if(framesObject.type != JSON_TYPE.ARRAY)
37       throw new Exception("\"frames\" should be an array");
38 
39     foreach(JSONValue frameObject; framesObject.array)
40       frames ~= readFrame(frameObject);
41 
42     return frames;
43   }
44 
45   private SpriteFrame readFrame(JSONValue frameObject)
46   {
47     SpriteFrame frame;
48 
49     JSONValue clipObject = frameObject["frame"];
50 
51     frame.clip.left = clipObject["x"].integer;
52     frame.clip.top = clipObject["y"].integer;
53     frame.clip.width = clipObject["w"].integer;
54     frame.clip.height = clipObject["h"].integer;
55 
56     frame.duration = frameObject["duration"].integer / 1000f;
57 
58     return frame;
59   }
60 
61   private SpriteAnimation[string] getAnimations(JSONValue frameTagsObject, SpriteFrame[] frames)
62   {
63     SpriteAnimation[string] animations;
64 
65     foreach(JSONValue value; frameTagsObject.array)
66     {
67       string name = value["name"].str;
68       long start = value["from"].integer;
69       long end = value["to"].integer + 1;
70 
71       animations[name] = new SpriteAnimation(name, frames[start .. end]);
72     }
73 
74     return animations;
75   }
76 }