/// <summary> /// Updates this form's reprensentation of the given AnimationSheet /// </summary> /// <param name="sheet">The AnimationSheet to update the representation of</param> public void UpdateAnimationSheet(AnimationSheet sheet) { // Seek the TreeView and update the treenode TreeNode node = GetTreeNodeFor(sheet); node.Text = sheet.Name; }
public bool TryGetSheet(AvatarAnimation animation, out AnimationSheet sheet) { sheet = animation == AvatarAnimation.Unknown ? default : animations[(int)animation]; 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); }
private void InvalidateSheetNode(AnimationSheet sheet) { // Verify progress for this sheet has changed float cur; if (!_progressTrack.TryGetValue(sheet.ID, out cur)) { return; } float real = _exporter.ProgressForAnimationSheet(sheet); if (Math.Abs(real - 1) < float.Epsilon || Math.Abs(cur - real) < float.Epsilon) { return; } _progressTrack[sheet.ID] = real; // Invalidate bounds for redrawing of tree view var node = NodeForSheet(sheet); if (node == null) { return; } var bounds = node.Bounds; bounds.X = bounds.Right; bounds.Width = tv_sheets.Width - bounds.Left; tv_sheets.Invalidate(bounds); }
/// <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); }
// // TreeView Key Down event handler // private void tv_bundleAnimations_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Enter) { OpenSelectedNode(); tv_bundleAnimations.Focus(); } if (e.KeyCode == Keys.Delete) { var nodeType = GetTypeForSelectedNode(); if (nodeType == null) { return; } switch (nodeType.Value) { case TreeViewNodeType.Animation: // Get the currently selected Animation node Animation anim = tv_bundleAnimations.SelectedNode.Tag as Animation; ConfirmDeleteAnimation(anim); break; case TreeViewNodeType.AnimationSheet: // Get the currently selected AnimationSheet node AnimationSheet sheet = tv_bundleAnimations.SelectedNode.Tag as AnimationSheet; ConfirmDeleteAnimationSheet(sheet); break; } } }
public Jumper() { Collision = CollisionType.A; MaxVelocity = new Vector2 { X = 300, Y = 450 }; Animations = new AnimationSheet(@"Textures\player", 64, 64); Animations.Add("idle", 1f, true, 0, 1); Animations.Add("run", 0.07f, true, 12, 13, 14, 15, 16, 17, 18, 19, 20); Animations.Add("jump", 0.09f, false, 21, 22); Animations.Add("wallSlide", 1f, true, 2); Index = PlayerIndex.One; // our player only has horizontal friction Friction = new Vector2(2000, 0); Settings["_feDrawBox"] = "true"; BoundingBox = new HitBox { Height = 64, Width = 64 }; }
/// <summary> /// Adds the given Animation Sheet to this form /// </summary> /// <param name="sheet">The animation to add</param> /// <param name="selectOnAdd">Whether to select the sheet's node after it's added to the interface</param> public void AddAnimationSheet(AnimationSheet sheet, bool selectOnAdd = false) { TreeNode bundleNode = _rootNode; // Find a new valid node position for the animation sheet int nodePos; for (nodePos = 0; nodePos < bundleNode.Nodes.Count; nodePos++) { if (bundleNode.Nodes[nodePos].Tag is Animation) { break; } } // Create the tree node now TreeNode sheetNode = bundleNode.Nodes.Insert(nodePos, sheet.Name); sheetNode.Tag = sheet; sheetNode.ImageIndex = sheetNode.SelectedImageIndex = 1; if (selectOnAdd) { // Select the new animation sheet node tv_bundleAnimations.SelectedNode = sheetNode; tv_bundleAnimations.SelectedNode.EnsureVisible(); } }
/// <summary> /// Validates the given AnimationSheet field, and returns a string based on the validation results. /// If the validation fails, an error string is returned, if it succeeds, an empty string is returned. /// </summary> /// <param name="name">The AnimationSheet name to validate</param> /// <param name="sheet">The AnimationSheet the field is coming from</param> /// <returns>The result of the validation. An empty string if the field is valid, or an error message if it's invalid.</returns> public string ValidateAnimationSheetName(string name, AnimationSheet sheet = null) { if (name.Trim() == "") { return("The name of the animation sheet cannot be empty"); } string validate = IsStringValidFileName(name); if (validate != "") { return(validate); } // Check any case of repeated animation sheet name if (_controller.CurrentBundle != null) { if (_controller.CurrentBundle.AnimationSheets.Any(csheet => csheet.Name == name && !ReferenceEquals(csheet, sheet))) { return("The name '" + name + "' conflicts with another animation sheet in the project"); } } return(""); }
/// <summary> /// Initializes a new instance of the SheetExportProgressView class /// </summary> /// <param name="sheet">The animation sheet to export</param> /// <param name="savePath">The path to save the animation sheet to</param> /// <param name="exporter">The exporter to use when exporting the animation sheet</param> public SheetExportProgressView(AnimationSheet sheet, string savePath, IBundleExporter exporter) { InitializeComponent(); _sheet = sheet; _savePath = savePath; _exporter = exporter; }
/// <summary> /// Creates and returns a new Animation Sheet /// </summary> /// <param name="name">The name for the animation sheet</param> /// <param name="openOnForm">Whether to open the newly added animation sheet on the main form</param> public AnimationSheet CreateAnimationSheet(string name, bool openOnForm) { AnimationSheet sheet = new AnimationSheet(name); AddAnimationSheet(sheet, openOnForm); return(sheet); }
/// <summary> /// Generates a TextureAtlas from the given AnimationSheet object /// </summary> /// <param name="sheet">The AnimationSheet to generate the TextureAtlas of</param> /// <param name="cancellationToken">A cancelation token that is passed to the exporters and can be used to cancel the export process mid-way</param> /// <param name="progressHandler">Optional event handler for reporting the export progress</param> /// <returns>A TextureAtlas generated from the given AnimationSheet</returns> public async Task <TextureAtlas> GenerateAtlasFromAnimationSheet(AnimationSheet sheet, CancellationToken cancellationToken = new CancellationToken(), BundleExportProgressEventHandler progressHandler = null) { return(await GenerateAtlasFromAnimations(sheet.ExportSettings, sheet.Animations, sheet.Name, cancellationToken, args => { progressHandler?.Invoke(args); _sheetProgress[sheet.ID] = (float)args.StageProgress / 100; })); }
// // Edit Sheet Properties context menu button click // private void tsm_editSheetPropertiesClick(object sender, EventArgs e) { // Get the currently selected AnimationSheet node AnimationSheet sheet = (AnimationSheet)tv_bundleAnimations.SelectedNode.Tag; if (sheet != null) { OpenViewForAnimationSheet(sheet); } }
// // Export Animation Sheet context menu click // private void tsm_exportSheetImage_Click(object sender, EventArgs e) { // Get the currently selected AnimationSheet node AnimationSheet sheet = (AnimationSheet)tv_bundleAnimations.SelectedNode.Tag; if (sheet != null) { Controller.ShowExportAnimationSheetImage(sheet); } }
// // Duplicate Animation Sheet context menu click // private void tsm_duplicateSheet_Click(object sender, EventArgs e) { // Get the currently selected AnimationSheet node AnimationSheet sheet = (AnimationSheet)tv_bundleAnimations.SelectedNode.Tag; if (sheet != null) { Controller.ShowDuplicateAnimationSheet(sheet); } }
// // Delete Animation Sheet context menu button click // private void cmb_deleteSheet_Click(object sender, EventArgs e) { // Get the currently selected AnimationSheet node AnimationSheet sheet = tv_bundleAnimations.SelectedNode.Tag as AnimationSheet; if (sheet != null) { ConfirmDeleteAnimationSheet(sheet); } }
/// <summary> /// Creates a new NewAnimationView form /// </summary> /// <param name="controller">The controller that owns this view</param> /// <param name="parentSheet">Optional AnimationSheet that will own the newly created Animation</param> public NewAnimationView(Controller controller, AnimationSheet parentSheet = null) { _controller = controller; _parentSheet = parentSheet; InitializeComponent(); txt_animationName.Text = controller.GetUniqueUntitledAnimationName(); ValidateFields(); }
public Character(Game game, AnimationSheet animationSheet, float x, float y, float width, float height) : base(game, x, y, width, height, false, true) { this.animationSheet = animationSheet; Acceleration.Y = 6000; MaxRunningSpeed = 600; RunningAcceleration = MaxRunningSpeed * 8; JumpingAcceleration = 1750; }
/// <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); }
// // Import Animation menu bar button click // private void tsb_importAnimation_Click(object sender, EventArgs e) { // Get the currently selected AnimationSheet node AnimationSheet sheet = tv_bundleAnimations.SelectedNode?.Tag as AnimationSheet; if (sheet == null && tv_bundleAnimations.SelectedNode?.Tag is Animation) { sheet = Controller.GetOwningAnimationSheet((Animation)tv_bundleAnimations.SelectedNode.Tag); } Controller.ShowImportAnimation(sheet); }
private TreeNode NodeForSheet(AnimationSheet sheet) { // ReSharper disable once LoopCanBeConvertedToQuery foreach (var node in tv_sheets.Nodes) { if (Equals((node as TreeNode)?.Tag as AnimationSheet, sheet)) { return((TreeNode)node); } } return(null); }
/// <summary> /// Exports the given animations into a BundleSheetExport and returns the created sheet /// </summary> /// <param name="sheet">The sheet to export</param> /// <param name="cancellationToken">A cancelation token that is passed to the exporters and can be used to cancel the export process mid-way</param> /// <param name="progressHandler">Optional event handler for reporting the export progress</param> /// <returns>A BundleSheetExport representing the animation sheet passed ready to be saved to disk</returns> public async Task <BundleSheetExport> ExportBundleSheet(AnimationSheet sheet, CancellationToken cancellationToken = new CancellationToken(), BundleExportProgressEventHandler progressHandler = null) { // // 1. Generate texture atlas // using (var atlas = await GenerateAtlasFromAnimationSheet(sheet, cancellationToken, progressHandler)) { // // 2. Generate an export sheet from the texture atlas // return(BundleSheetExport.FromAtlas(atlas)); } }
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"); }
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> /// Adds the given Animation to this form /// </summary> /// <param name="animation">The animation to add</param> /// <param name="selectOnAdd">Whether to select the sheet's node after it's added to the interface</param> public void AddAnimation(Animation animation, bool selectOnAdd = false) { TreeNode parentNode = _rootNode; // If the animation is owned by a sheet, set the sheet's tree node as the parent for the animation node AnimationSheet sheet = Controller.GetOwningAnimationSheet(animation); if (sheet != null) { parentNode = GetTreeNodeFor(sheet); } // Create the tree node now if (animation.FrameCount > 0) { il_treeView.Images.Add(animation.Name + animation.ID, animation.GetFrameAtIndex(0).GenerateThumbnail(16, 16, true, true, Color.White)); } int addIndex = Controller.GetAnimationIndex(animation); // If the target node is the bundle root, add the index of the animation sheets to the target add index if (parentNode.Tag is Bundle) { foreach (TreeNode node in _rootNode.Nodes) { if (node.Tag is AnimationSheet) { addIndex++; } else { break; } } } TreeNode animNode = parentNode.Nodes.Insert(addIndex, animation.Name); animNode.Tag = animation; animNode.ImageKey = animNode.SelectedImageKey = animation.Name + animation.ID; if (selectOnAdd) { // Select the new animation node tv_bundleAnimations.SelectedNode = animNode; tv_bundleAnimations.SelectedNode.EnsureVisible(); } }
/// <summary> /// Shows an interface to duplicate the given AnimationSheet object /// </summary> /// <param name="sheet">The animation sheet to duplicate</param> public void ShowDuplicateAnimationSheet(AnimationSheet sheet) { AnimationSheet dup = CurrentBundle.DuplicateAnimationSheet(sheet); _mainForm.AddAnimationSheet(dup, true); _mainForm.OpenViewForAnimationSheet(dup); // Add the cloned animations as well foreach (Animation anim in dup.Animations) { _mainForm.AddAnimation(anim); } MarkUnsavedChanges(true); }
/// <summary> /// Intiializes a new instance of the ImportAnimationView class /// </summary> /// <param name="controller">The controller owning this form</param> /// <param name="parentSheet">Optional AnimationSheet that will own the newly created animation</param> public ImportAnimationView(Controller controller, AnimationSheet parentSheet = null) { _controller = controller; _parentSheet = parentSheet; InitializeComponent(); cpb_sheetPreview.HookToControl(this); cpb_sheetPreview.Importer = controller.DefaultImporter; _spriteSheet = null; _sheetSettings = new SheetSettings(false, 32, 32); ValidateFields(); }
/// <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> /// Initializes a new instance of the AnimationSheetEditor class /// </summary> /// <param name="controller">The controller that owns this form</param> /// <param name="sheetToEdit">The sheet to edit on this form. Leave null to show an interface to create a new sheet</param> public AnimationSheetView(Controller controller, AnimationSheet sheetToEdit = null) { InitializeComponent(); zpb_sheetPreview.HookToControl(this); _controller = controller; _sheetToEdit = sheetToEdit; if (sheetToEdit != null) { _exportSettings = sheetToEdit.ExportSettings; } InitializeFiends(); ValidateFields(); }
/// <summary> /// Removes the given AnimationSheet's representation from this form /// </summary> /// <param name="sheet">The sheet to remove</param> public void RemoveAnimationSheet(AnimationSheet sheet) { foreach (Form curView in MdiChildren) { var view = curView as AnimationSheetView; if (view != null && ReferenceEquals(view.CurrentSheet, sheet)) { view.Close(); break; } } // Remove the sheet's treenode TreeNode sheetNode = GetTreeNodeFor(sheet); sheetNode.Remove(); }