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);
        }
Exemple #3
0
        /// <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);
        }
Exemple #4
0
        /// <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");
        }
Exemple #6
0
        /// <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);
        }
Exemple #7
0
        /// <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);
        }