public void TestAnimationIndex() { var sheet = new AnimationSheet("TestSheet"); var anim1 = new Animation("TestAnim1", 16, 16); var anim2 = new Animation("TestAnim2", 16, 16); var anim3 = new Animation("TestAnim2", 16, 16); sheet.AddAnimation(anim1); sheet.AddAnimation(anim2); Assert.AreEqual(0, sheet.IndexOfAnimation(anim1), "The IndexOfAnimation() must return the index at which the specified animation is on the sprite sheet's internal container"); Assert.AreEqual(1, sheet.IndexOfAnimation(anim2), "The IndexOfAnimation() must return the index at which the specified animation is on the sprite sheet's internal container"); Assert.AreEqual(-1, sheet.IndexOfAnimation(anim3), "The IndexOfAnimation() must return -1 to animations that the sheet doesn't contain"); }
/// <summary> /// Loads an AnimationSheet from the given stream, using the specified version /// number when reading properties /// </summary> /// <param name="stream">The stream to load the animation sheet from</param> /// <returns>The Animation object loaded</returns> protected AnimationSheet LoadAnimationSheetFromStream(Stream stream) { BinaryReader reader = new BinaryReader(stream); // Load the animation sheet data int id = reader.ReadInt32(); string name = reader.ReadString(); AnimationExportSettings settings = LoadExportSettingsFromStream(stream); // Create the animation sheet AnimationSheet sheet = new AnimationSheet(name) { ID = id, ExportSettings = settings }; // Load the animation indices int animCount = reader.ReadInt32(); for (int i = 0; i < animCount; i++) { Animation anim = owningFile.LoadedBundle.GetAnimationByID(reader.ReadInt32()); if (anim != null) { sheet.AddAnimation(anim); } else { throw new Exception(@"The animation referenced by an animation sheet stored is invalid. This may be due to a corrupted file."); } } return(sheet); }
/// <summary> /// Loads an AnimationSheet from the given stream, using the specified version /// number when reading properties /// </summary> /// <param name="stream">The stream to load the animation sheet from</param> /// <param name="parentBundle">The bundle that will contain this AnimationSheet</param> /// <param name="version">The version that the stream was written on</param> /// <returns>The Animation object loaded</returns> public static AnimationSheet LoadAnimationSheetFromStream(Stream stream, Bundle parentBundle, int version) { BinaryReader reader = new BinaryReader(stream); // Load the animation sheet data int id = reader.ReadInt32(); string name = reader.ReadString(); AnimationExportSettings settings = LoadExportSettingsFromStream(stream, version); // Create the animation sheet AnimationSheet sheet = new AnimationSheet(name) { ID = id, ExportSettings = settings }; // Load the animation indices int animCount = reader.ReadInt32(); for (int i = 0; i < animCount; i++) { Animation anim = parentBundle.GetAnimationByID(reader.ReadInt32()); if (anim != null) { sheet.AddAnimation(anim); } } return(sheet); }
/// <summary> /// Generates an AnimationSheet with a given set of parameters. /// </summary> /// <param name="name">The name of the animation sheet to generate</param> /// <param name="animationCount">The number of animations to generate in the sheet</param> /// <param name="animationWidth">The width of the animations to generate</param> /// <param name="animationHeight">The height of the animations to generate</param> /// <param name="frameCount">The number of frames to add to each animation generated</param> /// <param name="seed">The seed for the animations' frames, used to seed the random number generator that will generate each of the frame's contents</param> /// <returns>An animation sheet with the passed parameters</returns> public static AnimationSheet GenerateAnimationSheet(string name, int animationCount, int animationWidth, int animationHeight, int frameCount, int seed = -1) { AnimationSheet sheet = new AnimationSheet(name); for (int i = 0; i < animationCount; i++) { sheet.AddAnimation(AnimationGenerator.GenerateAnimation(name + "Animation" + i, animationWidth, animationHeight, frameCount, seed == -1 ? seed : seed + i * frameCount)); } return(sheet); }
public void TestAnimationInsert() { var sheet = new AnimationSheet("TestSheet"); var anim1 = new Animation("TestAnim1", 16, 16); var anim2 = new Animation("TestAnim2", 16, 16); var anim3 = new Animation("TestAnim3", 16, 16); sheet.AddAnimation(anim1); sheet.InsertAnimation(anim2, 0); sheet.InsertAnimation(anim3, 0); Assert.AreEqual(2, sheet.IndexOfAnimation(anim1), "The InsertAnimation() method must bump the animations forward one index"); Assert.AreEqual(0, sheet.IndexOfAnimation(anim3), "The InsertAnimation() method must insert animations in the specified position"); }
/// <summary> /// Tests a sheet export procedure with a given export settings struct /// </summary> /// <param name="settings">The export settings to use in this test</param> /// <param name="failMessage">The message to print if the test fails</param> private void TestSheetExportWithSettings(AnimationExportSettings settings, string failMessage = "Exported animation sheets should be equivalent to their original sheets") { // In theory, if you export a sheet and import it back just the way it was described on the generated json file, it will equal the original sheet completely OriginalSheet = new AnimationSheet("Sheet1") { ExportSettings = settings }; for (int i = 0; i < 10; i++) { int animationWidth = 12 + i / 2; int animationHeight = 12 + i / 2; OriginalSheet.AddAnimation(AnimationGenerator.GenerateAnimation("Anim" + OriginalSheet.AnimationCount, animationWidth, animationHeight, 10, OriginalSheet.AnimationCount * 2)); } // Generate export path _tempExportPath = Path.GetTempPath() + Path.DirectorySeparatorChar + Path.GetRandomFileName(); Directory.CreateDirectory(_tempExportPath); string exportPath = _tempExportPath + Path.DirectorySeparatorChar + OriginalSheet.Name; string jsonPath = exportPath + ".json"; // Export and save to disk IBundleExporter exporter = new DefaultPngExporter(); exporter.ExportBundleSheet(OriginalSheet.ExportSettings, OriginalSheet.Animations).Result .SaveToDisk(_tempExportPath + Path.DirectorySeparatorChar + OriginalSheet.Name); // Export sheet temporarely for (int i = 0; i < OriginalSheet.Animations.Length; i++) { var animation = OriginalSheet.Animations[i]; var image = exporter.GenerateSpriteStrip(animation); var path = _tempExportPath + Path.DirectorySeparatorChar + OriginalSheet.Name + "_" + i + ".png"; image.Save(path, ImageFormat.Png); } // Import it back up SheetFromDisk = (AnimationSheet)ImportSheetFile(jsonPath); SheetFromDisk.ExportSettings = OriginalSheet.ExportSettings; Assert.AreEqual(OriginalSheet, SheetFromDisk, failMessage); }
/// <summary> /// Imports a bundle composed from the given Texture2D and JObject (json) file /// </summary> /// <param name="texture">The Texture2D sheet</param> /// <param name="json">The .json sheet description</param> public static AnimationSheet ImportAnimationSheet(Bitmap texture, JObject json) { // Impors a JSON formatted as follows: /* * { * "sprite_image": "<name>.png", * "animations": [ * { * "name": "<name>", * "width": 24, * "height": 23, * "fps": 14, * "frameskip": false, * "frames": [ * { * "sheet": { * "x": 58, * "y": 47, * "width": 15, * "height": 21 * }, * "frame": { * "x": 3, * "y": 2, * "width": 15, * "height": 21 * } * } * ] * } * ] * } */ AnimationSheet sheet = new AnimationSheet(Path.GetFileNameWithoutExtension((string)json.SelectToken("sprite_image"))); foreach (var child in json.SelectToken("animations").Children()) { // Load the animation properties string animName = (string)child.SelectToken("name"); int animWidth = (int)child.SelectToken("width"); int animHeight = (int)child.SelectToken("height"); int fps = (int)child.SelectToken("fps"); bool frameskip = (bool)child.SelectToken("frameskip"); Animation anim = new Animation(animName, animWidth, animHeight); var playbackSettings = anim.PlaybackSettings; playbackSettings.FPS = fps; playbackSettings.FrameSkip = frameskip; anim.PlaybackSettings = playbackSettings; foreach (var frameNode in child.SelectToken("frames").Children()) { var frameSheet = frameNode.SelectToken("sheet"); var frameLocal = frameNode.SelectToken("frame"); int sheetX = (int)frameSheet.SelectToken("x"); int sheetY = (int)frameSheet.SelectToken("y"); int sheetW = (int)frameSheet.SelectToken("width"); int sheetH = (int)frameSheet.SelectToken("height"); int frameX = (int)frameLocal.SelectToken("x"); int frameY = (int)frameLocal.SelectToken("y"); int frameW = (int)frameLocal.SelectToken("width"); int frameH = (int)frameLocal.SelectToken("height"); Rectangle bounds = new Rectangle(sheetX, sheetY, sheetW, sheetH); Rectangle origins = new Rectangle(frameX, frameY, frameW, frameH); Bitmap frame = SliceImage(texture, new Size(animWidth, animHeight), bounds, origins); anim.CreateFrame().SetFrameBitmap(frame); } sheet.AddAnimation(anim); } return(sheet); }