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