mirror of
https://github.com/Phantop/LADXHD.git
synced 2024-11-01 04:14:22 +00:00
735 lines
39 KiB
C#
735 lines
39 KiB
C#
using System;
|
|
using System.IO;
|
|
using Microsoft.Xna.Framework;
|
|
using Microsoft.Xna.Framework.Content;
|
|
using Microsoft.Xna.Framework.Graphics;
|
|
using ProjectZ.Base;
|
|
using ProjectZ.Base.UI;
|
|
using ProjectZ.InGame.GameObjects.Base;
|
|
using ProjectZ.InGame.SaveLoad;
|
|
using ProjectZ.InGame.Things;
|
|
#if WINDOWS
|
|
using System.Windows.Forms;
|
|
#endif
|
|
|
|
namespace ProjectZ.Editor
|
|
{
|
|
internal class AnimationScreen : InGame.Screens.Screen
|
|
{
|
|
private readonly EditorCamera _camera = new EditorCamera();
|
|
|
|
private Animator _animator = new Animator();
|
|
private Animator _overlayAnimator;
|
|
private Texture2D _sprAnimator;
|
|
|
|
private Point _currentPosition, _selectionStart, _selectionEnd;
|
|
private UiNumberInput _animationInput, _frameInput, _numberInputX, _numberInputY, _numberInputWidth, _numberInputHeight;
|
|
private UiNumberInput _niOffsetX, _niOffsetY, _niAnOffsetX, _niAnOffsetY, _fpsInput, _loopCountInput;
|
|
private UiTextInput _animationName, _nextAnimationName;
|
|
private UiLabel _animationUiLabel, _frameUiLabel;
|
|
private UiCheckBox _checkBoxLoop, _cbFrameMirroredV, _cbFrameMirroredH;
|
|
|
|
private string _sprPath;
|
|
private string _lastFileName;
|
|
private const float MinScale = 1;
|
|
private const float MaxScale = 10;
|
|
private const int LeftBarWidth = 200;
|
|
private const int RightBarWidth = 300;
|
|
private const int TileSize = 2;
|
|
private int _selectedAnimation, _selectedFrame;
|
|
private bool _selecting;
|
|
private bool _collisionRectangleMode;
|
|
private bool _isPlaying;
|
|
private bool _showAllSelections;
|
|
|
|
public AnimationScreen(string screenId) : base(screenId) { }
|
|
|
|
public override void Load(ContentManager content)
|
|
{
|
|
var buttonDist = 5;
|
|
var buttonWidth = LeftBarWidth - buttonDist * 2;
|
|
var buttonWidthHalf = (LeftBarWidth - buttonDist * 3) / 2;
|
|
var buttonHeight = 30;
|
|
var labelHeight = Resources.EditorFontHeight;
|
|
var buttonQWidth = LeftBarWidth - 15 - buttonHeight;
|
|
var posY = Values.ToolBarHeight + buttonDist;
|
|
|
|
var screenId = Values.EditorUiAnimation;
|
|
|
|
Game1.EditorUi.AddElement(new UiRectangle(new Rectangle(0, 0, 0, 0), "leftBackground", screenId, Values.ColorBackgroundLight, Color.White,
|
|
ui => { ui.Rectangle = new Rectangle(0, Values.ToolBarHeight, LeftBarWidth, Game1.WindowHeight - Values.ToolBarHeight); }));
|
|
|
|
Game1.EditorUi.AddElement(new UiRectangle(new Rectangle(0, 0, 0, 0), "rightBackground", screenId, Values.ColorBackgroundLight, Color.White,
|
|
ui => { ui.Rectangle = new Rectangle(Game1.WindowWidth - RightBarWidth, Values.ToolBarHeight, RightBarWidth, Game1.WindowHeight - Values.ToolBarHeight - RightBarWidth); }));
|
|
// animation background
|
|
Game1.EditorUi.AddElement(new UiRectangle(new Rectangle(0, 0, 0, 0), "rightAnimationBackground", screenId, Color.White * 0.5f, Color.White,
|
|
ui => { ui.Rectangle = new Rectangle(Game1.WindowWidth - RightBarWidth, Game1.WindowHeight - RightBarWidth, RightBarWidth, RightBarWidth); }));
|
|
|
|
// right toolbar
|
|
Game1.EditorUi.AddElement(new UiButton(Rectangle.Empty, Resources.EditorFont, "load overlay", "bt1", screenId,
|
|
ui => { ui.Rectangle = new Rectangle(Game1.WindowWidth - RightBarWidth + 5, Values.ToolBarHeight + buttonDist, buttonWidth, buttonHeight); },
|
|
ui => { LoadOverlayAnimation(); }));
|
|
|
|
Game1.EditorUi.AddElement(new UiButton(Rectangle.Empty, Resources.EditorFont, "play/pause", "bt1", screenId,
|
|
ui => { ui.Rectangle = new Rectangle(Game1.WindowWidth - RightBarWidth + 5, Values.ToolBarHeight + buttonDist * 2 + buttonHeight, buttonWidth, buttonHeight); },
|
|
ui => { _isPlaying = !_isPlaying; }));
|
|
|
|
posY = Values.ToolBarHeight + buttonDist;
|
|
|
|
// load button
|
|
Game1.EditorUi.AddElement(new UiButton(new Rectangle(5, posY, buttonWidth, buttonHeight), Resources.EditorFont,
|
|
"load", "bt1", screenId, null, ui => { LoadAnimation(); }));
|
|
|
|
// save button
|
|
Game1.EditorUi.AddElement(new UiButton(new Rectangle(5, posY += buttonHeight + buttonDist, buttonWidth, buttonHeight), Resources.EditorFont,
|
|
"save as...", "bt1", screenId, null, ui => { SaveAnimationDialog(); }));
|
|
Game1.EditorUi.AddElement(new UiButton(new Rectangle(5, posY += buttonHeight + buttonDist, buttonWidth, buttonHeight), Resources.EditorFont,
|
|
"save...", "bt1", screenId, null, ui => { SaveAnimation(); }));
|
|
|
|
Game1.EditorUi.AddElement(new UiButton(new Rectangle(5, posY += buttonHeight + buttonDist, buttonWidth, buttonHeight), Resources.EditorFont,
|
|
"updated animations", "bt1", screenId, null, ui => { UpdateAnimations(); }));
|
|
|
|
// load image
|
|
Game1.EditorUi.AddElement(new UiButton(new Rectangle(5, posY += buttonHeight + buttonDist, buttonWidth, buttonHeight), Resources.EditorFont,
|
|
"load image", "bt1", screenId, null, ui => { LoadImage(); }));
|
|
// clear animation
|
|
Game1.EditorUi.AddElement(new UiButton(new Rectangle(5, posY += buttonHeight + buttonDist, buttonWidth, buttonHeight), Resources.EditorFont,
|
|
"clear animator", "bt1", screenId, null, ui => { CreateAnimator(); }));
|
|
|
|
Game1.EditorUi.AddElement(new UiCheckBox(new Rectangle(5, posY += buttonHeight + buttonDist, buttonWidth, buttonHeight),
|
|
Resources.EditorFont, "show all selections", "showAllSelections", screenId, false, null,
|
|
ui => { _showAllSelections = ((UiCheckBox)ui).CurrentState; }));
|
|
|
|
Game1.EditorUi.AddElement(new UiLabel(new Rectangle(buttonDist, posY += buttonHeight + buttonDist * 3, buttonWidth, labelHeight),
|
|
Resources.EditorFont, "Animation", "frameHeader", screenId, null));
|
|
|
|
_animationUiLabel = new UiLabel(new Rectangle(buttonDist, posY += labelHeight + buttonDist, buttonWidthHalf, buttonHeight),
|
|
Resources.EditorFont, "animation", "flable", screenId, ui => { ui.Label = "[" + (_selectedAnimation + 1) + "/" + _animator.Animations.Count + "]"; });
|
|
Game1.EditorUi.AddElement(_animationUiLabel);
|
|
_animationInput = new UiNumberInput(new Rectangle(buttonDist * 2 + buttonWidthHalf, posY, buttonWidthHalf, buttonHeight),
|
|
Resources.EditorFont, 1, 1, 1, 1, "numberX", screenId,
|
|
ui => { ((UiNumberInput)ui).MaxValue = _animator.Animations.Count; },
|
|
ui => { ChangeAnimation((int)((UiNumberInput)ui).Value - 1); });
|
|
Game1.EditorUi.AddElement(_animationInput);
|
|
|
|
// add animation
|
|
Game1.EditorUi.AddElement(new UiButton(new Rectangle(buttonDist, posY += buttonHeight + buttonDist, buttonWidthHalf, buttonHeight),
|
|
Resources.EditorFont, "add", "bt1", screenId, null, ui => { AddAnimation(); }));
|
|
Game1.EditorUi.AddElement(new UiButton(new Rectangle(buttonDist * 2 + buttonWidthHalf, posY, buttonWidthHalf, buttonHeight),
|
|
Resources.EditorFont, "remove", "bt1", screenId, null, ui => { RemoveAnimation(); }));
|
|
|
|
// animation name
|
|
var animationNameLabel = new UiLabel(new Rectangle(buttonDist, posY += buttonHeight + buttonDist, buttonWidth, labelHeight),
|
|
Resources.EditorFont, "name", "lableX", screenId, null);
|
|
Game1.EditorUi.AddElement(animationNameLabel);
|
|
_animationName = new UiTextInput(new Rectangle(buttonDist, posY += labelHeight, buttonWidth, buttonHeight),
|
|
Resources.EditorFontMonoSpace, 20, "animationName", screenId, null, ui => { _animator.Animations[_selectedAnimation].Id = ((UiTextInput)ui).StrValue; });
|
|
Game1.EditorUi.AddElement(_animationName);
|
|
|
|
// next animation
|
|
var nextAnimationLabel = new UiLabel(new Rectangle(buttonDist, posY += buttonHeight + buttonDist, buttonWidth, labelHeight),
|
|
Resources.EditorFont, "next animation", "lableX", screenId, null);
|
|
Game1.EditorUi.AddElement(nextAnimationLabel);
|
|
_nextAnimationName = new UiTextInput(new Rectangle(buttonDist, posY += labelHeight, buttonWidth, buttonHeight),
|
|
Resources.EditorFontMonoSpace, 20, "nextAnimationName", screenId, null,
|
|
ui => { _animator.Animations[_selectedAnimation].NextAnimation = ((UiTextInput)ui).StrValue; });
|
|
Game1.EditorUi.AddElement(_nextAnimationName);
|
|
|
|
// collision
|
|
Game1.EditorUi.AddElement(new UiButton(new Rectangle(5, posY += buttonHeight + buttonDist, buttonWidth, buttonHeight), Resources.EditorFont,
|
|
"collision mode", "bt1", screenId, ui => { ((UiButton)ui).Marked = _collisionRectangleMode; },
|
|
ui => { _collisionRectangleMode = !_collisionRectangleMode; }));
|
|
|
|
//// loop checkbox
|
|
//_checkBoxLoop = new CheckBox(new Rectangle(5, posY += buttonHeight + buttonDist, buttonWidth, buttonHeight), Resources.EditorFont,
|
|
// "loop", "cbloop", screenId, false, ui => { ((CheckBox)ui).CurrentState = _animator.CurrentAnimation.Looping; },
|
|
// ui => { _animator.CurrentAnimation.Looping = ((CheckBox)ui).CurrentState; });
|
|
//Game1.EditorUi.AddElement(_checkBoxLoop);
|
|
|
|
Game1.EditorUi.AddElement(new UiLabel(new Rectangle(buttonDist, posY += buttonHeight + buttonDist, buttonWidthHalf, buttonHeight),
|
|
Resources.EditorFont, "Loops", "flable", screenId, null));
|
|
_loopCountInput = new UiNumberInput(new Rectangle(buttonDist * 2 + buttonWidthHalf, posY, buttonWidthHalf, buttonHeight),
|
|
Resources.EditorFont, 1, -1, 999, 1, "loopCount", screenId, null,
|
|
ui => _animator.Animations[_selectedAnimation].LoopCount = (int)((UiNumberInput)ui).Value);
|
|
Game1.EditorUi.AddElement(_loopCountInput);
|
|
|
|
|
|
Game1.EditorUi.AddElement(new UiLabel(new Rectangle(buttonDist, posY += buttonHeight + buttonDist * 3, buttonWidth, labelHeight),
|
|
Resources.EditorFont, "Frame", "frameHeader", screenId, null));
|
|
|
|
// frame information
|
|
Game1.EditorUi.AddElement(new UiLabel(new Rectangle(buttonDist, posY += labelHeight + buttonDist, buttonWidthHalf, buttonHeight),
|
|
Resources.EditorFont, "frame", "flable", screenId,
|
|
ui => { ui.Label = "frame [" + (_selectedFrame + 1) + "/" + _animator.Animations[_selectedAnimation].Frames.Length + "]"; }));
|
|
_frameInput = new UiNumberInput(new Rectangle(buttonDist * 2 + buttonWidthHalf, posY, buttonWidthHalf, buttonHeight),
|
|
Resources.EditorFont, 1, 1, 1, 1, "numberX", screenId,
|
|
ui => { ((UiNumberInput)ui).MaxValue = _animator.Animations[_selectedAnimation].Frames.Length; },
|
|
ui => { ChangeFrame((int)((UiNumberInput)ui).Value - 1); });
|
|
Game1.EditorUi.AddElement(_frameInput);
|
|
|
|
// add remove frame
|
|
Game1.EditorUi.AddElement(new UiButton(new Rectangle(buttonDist, posY += buttonHeight + buttonDist, buttonWidthHalf, buttonHeight), Resources.EditorFont,
|
|
"add", "addFrame", screenId, null, ui => { AddFrame(); }));
|
|
Game1.EditorUi.AddElement(new UiButton(new Rectangle(buttonDist * 2 + buttonWidthHalf, posY, buttonWidthHalf, buttonHeight), Resources.EditorFont,
|
|
"delete", "deleteFrame", screenId, null, ui => { DeleteFrame(); }));
|
|
|
|
_cbFrameMirroredV = (UiCheckBox)Game1.EditorUi.AddElement(new UiCheckBox(new Rectangle(5, posY += buttonHeight + buttonDist, buttonWidth, buttonHeight),
|
|
Resources.EditorFont, "mirrored V", "cbmirrored", screenId, false, null,
|
|
ui => { _animator.Animations[_selectedAnimation].Frames[_selectedFrame].MirroredV = ((UiCheckBox)ui).CurrentState; }));
|
|
_cbFrameMirroredH = (UiCheckBox)Game1.EditorUi.AddElement(new UiCheckBox(new Rectangle(5, posY += buttonHeight + buttonDist, buttonWidth, buttonHeight),
|
|
Resources.EditorFont, "mirrored H", "cbmirrored", screenId, false, null,
|
|
ui => { _animator.Animations[_selectedAnimation].Frames[_selectedFrame].MirroredH = ((UiCheckBox)ui).CurrentState; }));
|
|
|
|
Game1.EditorUi.AddElement(new UiLabel(new Rectangle(buttonDist, posY += buttonHeight + buttonDist * 2, buttonWidth, labelHeight),
|
|
Resources.EditorFont, "fps", "flable", screenId, null));
|
|
_fpsInput = new UiNumberInput(new Rectangle(buttonDist, posY += labelHeight + buttonDist, buttonWidthHalf, buttonHeight),
|
|
Resources.EditorFont, 1, 1, 1000, 1, "numberX", screenId, null,
|
|
ui => { _animator.SetFrameFps(_selectedAnimation, _selectedFrame, (int)((UiNumberInput)ui).Value); });
|
|
Game1.EditorUi.AddElement(_fpsInput);
|
|
Game1.EditorUi.AddElement(new UiButton(new Rectangle(buttonDist * 2 + buttonWidthHalf, posY, buttonWidthHalf, buttonHeight),
|
|
Resources.EditorFont, "to all", "toall", screenId, null,
|
|
ui => { _animator.SetAnimationFps(_selectedAnimation, (int)_fpsInput.Value); }));
|
|
|
|
// animation offset
|
|
Game1.EditorUi.AddElement(new UiLabel(new Rectangle(buttonDist, posY += buttonHeight + buttonDist,
|
|
buttonWidth, labelHeight), Resources.EditorFont, "animation offset", "lableX", screenId, null));
|
|
//Game1.EditorUi.AddElement(new UiLabel(new Rectangle(buttonDist, posY += Resources.EditorFontHeight + buttonDist,
|
|
// buttonWidthHalf, labelHeight), Resources.EditorFont, "x", "lableX", screenId, null));
|
|
//Game1.EditorUi.AddElement(new UiLabel(new Rectangle(buttonDist * 2 + buttonWidthHalf, posY,
|
|
// buttonWidthHalf, labelHeight), Resources.EditorFont, "y", "lableX", screenId, null));
|
|
_niAnOffsetX = new UiNumberInput(new Rectangle(buttonDist, posY += labelHeight + buttonDist, buttonWidthHalf, buttonHeight),
|
|
Resources.EditorFont, 0, -100, 100, 1, "animationWidth", screenId, null,
|
|
ui => { _animator.Animations[_selectedAnimation].Offset.X = (int)((UiNumberInput)ui).Value; });
|
|
_niAnOffsetY = new UiNumberInput(new Rectangle(buttonDist * 2 + buttonWidthHalf, posY, buttonWidthHalf, buttonHeight),
|
|
Resources.EditorFont, 0, -100, 100, 1, "animationWidth", screenId, null,
|
|
ui => { _animator.Animations[_selectedAnimation].Offset.Y = (int)((UiNumberInput)ui).Value; });
|
|
Game1.EditorUi.AddElement(_niAnOffsetX);
|
|
Game1.EditorUi.AddElement(_niAnOffsetY);
|
|
|
|
// rectangle
|
|
// labels
|
|
Game1.EditorUi.AddElement(new UiLabel(new Rectangle(buttonDist, posY += buttonHeight + buttonDist,
|
|
buttonWidth, labelHeight), Resources.EditorFont, "rectangle", "rectangle", screenId, null));
|
|
//Game1.EditorUi.AddElement(new UiLabel(new Rectangle(buttonDist * 2 + buttonWidthHalf, posY,
|
|
// buttonWidthHalf, labelHeight), Resources.EditorFont, "y", "lableX", screenId, null));
|
|
// number picker
|
|
_numberInputX = new UiNumberInput(new Rectangle(buttonDist, posY += labelHeight + buttonDist, buttonWidthHalf, buttonHeight),
|
|
Resources.EditorFont, 0, 0, 1000, 1, "numberX", screenId, null,
|
|
ui =>
|
|
{
|
|
_animator.Animations[_selectedAnimation].Frames[_selectedFrame].SourceRectangle.X = (int)((UiNumberInput)ui).Value;
|
|
UpdateCurrentFrame();
|
|
});
|
|
_numberInputY = new UiNumberInput(new Rectangle(buttonDist * 2 + buttonWidthHalf, posY, buttonWidthHalf, buttonHeight),
|
|
Resources.EditorFont, 0, 0, 1000, 1, "numberY", screenId, null,
|
|
ui =>
|
|
{
|
|
_animator.Animations[_selectedAnimation].Frames[_selectedFrame].SourceRectangle.Y = (int)((UiNumberInput)ui).Value;
|
|
UpdateCurrentFrame();
|
|
});
|
|
Game1.EditorUi.AddElement(_numberInputX);
|
|
Game1.EditorUi.AddElement(_numberInputY);
|
|
//// labels
|
|
//Game1.EditorUi.AddElement(new UiLabel(new Rectangle(buttonDist, posY += buttonHeight + buttonDist,
|
|
// buttonWidthHalf, labelHeight), Resources.EditorFont, "width", "lableX", screenId, null));
|
|
//Game1.EditorUi.AddElement(new UiLabel(new Rectangle(buttonDist * 2 + buttonWidthHalf, posY,
|
|
// buttonWidthHalf, labelHeight), Resources.EditorFont, "height", "lableX", screenId, null));
|
|
// number picker
|
|
_numberInputWidth = new UiNumberInput(new Rectangle(buttonDist, posY += buttonHeight + buttonDist, buttonWidthHalf, buttonHeight),
|
|
Resources.EditorFont, 0, 0, 1000, 1, "numberWidth", screenId, null, ui =>
|
|
{
|
|
_animator.Animations[_selectedAnimation].Frames[_selectedFrame].SourceRectangle.Width = (int)((UiNumberInput)ui).Value;
|
|
UpdateCurrentFrame();
|
|
});
|
|
_numberInputHeight = new UiNumberInput(new Rectangle(buttonDist * 2 + buttonWidthHalf, posY, buttonWidthHalf, buttonHeight),
|
|
Resources.EditorFont, 0, 0, 1000, 1, "numberHeight", screenId, null, ui =>
|
|
{
|
|
_animator.Animations[_selectedAnimation].Frames[_selectedFrame].SourceRectangle.Height = (int)((UiNumberInput)ui).Value;
|
|
UpdateCurrentFrame();
|
|
});
|
|
Game1.EditorUi.AddElement(_numberInputWidth);
|
|
Game1.EditorUi.AddElement(_numberInputHeight);
|
|
|
|
// offset
|
|
// labels
|
|
Game1.EditorUi.AddElement(new UiLabel(new Rectangle(buttonDist, posY += buttonHeight + buttonDist,
|
|
buttonWidth, labelHeight), Resources.EditorFont, "frame offset", "lableX", screenId, null));
|
|
//Game1.EditorUi.AddElement(new UiLabel(new Rectangle(buttonDist, posY += buttonHeight / 2,
|
|
// buttonWidthHalf, labelHeight), Resources.EditorFont, "x", "lableX", screenId, null));
|
|
//Game1.EditorUi.AddElement(new UiLabel(new Rectangle(buttonDist * 2 + buttonWidthHalf, posY,
|
|
// buttonWidthHalf, labelHeight), Resources.EditorFont, "y", "lableX", screenId, null));
|
|
// number picker
|
|
_niOffsetX = new UiNumberInput(new Rectangle(buttonDist, posY += labelHeight + buttonDist, buttonWidthHalf, buttonHeight),
|
|
Resources.EditorFont, 0, -100, 100, 1, "numberX", screenId, null, ui =>
|
|
{
|
|
_animator.Animations[_selectedAnimation].Frames[_selectedFrame].Offset.X = (int)((UiNumberInput)ui).Value;
|
|
UpdateCurrentFrame();
|
|
});
|
|
_niOffsetY = new UiNumberInput(new Rectangle(buttonDist * 2 + buttonWidthHalf, posY, buttonWidthHalf, buttonHeight),
|
|
Resources.EditorFont, 0, -100, 100, 1, "numberY", screenId, null, ui =>
|
|
{
|
|
_animator.Animations[_selectedAnimation].Frames[_selectedFrame].Offset.Y = (int)((UiNumberInput)ui).Value;
|
|
UpdateCurrentFrame();
|
|
});
|
|
Game1.EditorUi.AddElement(_niOffsetX);
|
|
Game1.EditorUi.AddElement(_niOffsetY);
|
|
|
|
// create empty animation
|
|
CreateAnimator();
|
|
}
|
|
|
|
public override void Update(GameTime gameTime)
|
|
{
|
|
Game1.EditorUi.CurrentScreen = Values.EditorUiAnimation;
|
|
|
|
if (_sprAnimator == null)
|
|
return;
|
|
|
|
var mousePosition = InputHandler.MousePosition();
|
|
|
|
if (_isPlaying && !_animator.IsPlaying)
|
|
{
|
|
_animator.Play(_selectedAnimation);
|
|
}
|
|
|
|
if (_isPlaying)
|
|
_animator.Update();
|
|
else
|
|
{
|
|
_animator.SetFrame(_selectedFrame);
|
|
}
|
|
|
|
// update tileset scale
|
|
if (InputHandler.MouseIntersect(new Rectangle(LeftBarWidth, Values.ToolBarHeight,
|
|
Game1.WindowWidth - LeftBarWidth - RightBarWidth, Game1.WindowHeight - Values.ToolBarHeight)))
|
|
{
|
|
_currentPosition = new Point(
|
|
(int)((InputHandler.MousePosition().X - _camera.Location.X) / _camera.Scale),
|
|
(int)((InputHandler.MousePosition().Y - _camera.Location.Y) / _camera.Scale));
|
|
|
|
if (InputHandler.MouseLeftStart())
|
|
{
|
|
_selecting = true;
|
|
_selectionStart = _currentPosition;
|
|
}
|
|
if (InputHandler.MouseLeftDown() && _selecting)
|
|
{
|
|
_selectionEnd = _currentPosition;
|
|
|
|
var selectionStart1 = new Point(Math.Min(_selectionStart.X, _selectionEnd.X), Math.Min(_selectionStart.Y, _selectionEnd.Y));
|
|
var selectionEnd1 = new Point(Math.Max(_selectionStart.X, _selectionEnd.X) + 1, Math.Max(_selectionStart.Y, _selectionEnd.Y) + 1);
|
|
|
|
if (_collisionRectangleMode)
|
|
_animator.Animations[_selectedAnimation].Frames[_selectedFrame].CollisionRectangle =
|
|
new Rectangle(
|
|
selectionStart1.X - _animator.Animations[_selectedAnimation].Frames[_selectedFrame].SourceRectangle.X,
|
|
selectionStart1.Y - _animator.Animations[_selectedAnimation].Frames[_selectedFrame].SourceRectangle.Y,
|
|
selectionEnd1.X - selectionStart1.X, selectionEnd1.Y - selectionStart1.Y);
|
|
else
|
|
{
|
|
_animator.Animations[_selectedAnimation].Frames[_selectedFrame].SourceRectangle =
|
|
new Rectangle(selectionStart1.X, selectionStart1.Y, selectionEnd1.X - selectionStart1.X,
|
|
selectionEnd1.Y - selectionStart1.Y);
|
|
UpdateCurrentFrame();
|
|
}
|
|
|
|
UpdateInputUi();
|
|
}
|
|
if (InputHandler.MouseLeftReleased())
|
|
{
|
|
_selecting = false;
|
|
}
|
|
|
|
if (InputHandler.MouseRightPressed())
|
|
{
|
|
if (_collisionRectangleMode)
|
|
_animator.Animations[_selectedAnimation].Frames[_selectedFrame].CollisionRectangle = Rectangle.Empty;
|
|
}
|
|
|
|
if (InputHandler.MouseWheelUp())
|
|
_camera.Zoom(1, mousePosition);
|
|
if (InputHandler.MouseWheelDown())
|
|
_camera.Zoom(-1, mousePosition);
|
|
}
|
|
|
|
if (!InputHandler.MouseMiddleStart() && InputHandler.MouseMiddleDown())
|
|
_camera.Location += mousePosition - InputHandler.LastMousePosition();
|
|
}
|
|
|
|
public override void Draw(SpriteBatch spriteBatch)
|
|
{
|
|
if (_sprAnimator == null)
|
|
return;
|
|
|
|
spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointWrap, null, null, null, _camera.TransformMatrix);
|
|
|
|
// draw the tiled background
|
|
spriteBatch.Draw(Resources.SprTiledBlock, new Rectangle(0, 0, _sprAnimator.Width, _sprAnimator.Height),
|
|
new Rectangle(0, 0,
|
|
(int)(_sprAnimator.Width / (float)TileSize * 2),
|
|
(int)(_sprAnimator.Height / (float)TileSize * 2)), Color.White);
|
|
|
|
// draw the sprite
|
|
spriteBatch.Draw(_sprAnimator, new Rectangle(0, 0, _sprAnimator.Width, _sprAnimator.Height), Color.White);
|
|
|
|
// draw current position of the mouse
|
|
spriteBatch.Draw(Resources.SprWhite, new Rectangle(_currentPosition.X, _currentPosition.Y, 1, 1), Color.Red * 0.5f);
|
|
|
|
// show all source rectangles of all animations
|
|
if (_showAllSelections)
|
|
{
|
|
foreach (var animation in _animator.Animations)
|
|
for (var i = 0; i < animation.Frames.Length; i++)
|
|
spriteBatch.Draw(Resources.SprWhite, animation.Frames[i].SourceRectangle, Color.HotPink * 0.25f);
|
|
}
|
|
|
|
// draw the selection
|
|
for (var i = 0; i < _animator.Animations[_selectedAnimation].Frames.Length; i++)
|
|
{
|
|
spriteBatch.Draw(Resources.SprWhite, _animator.Animations[_selectedAnimation].Frames[i].SourceRectangle, _selectedFrame == i ? Color.Red * 0.5f : Color.Red * 0.25f);
|
|
}
|
|
|
|
spriteBatch.Draw(Resources.SprWhite, new Rectangle(
|
|
_animator.Animations[_selectedAnimation].Frames[_selectedFrame].CollisionRectangle.X +
|
|
_animator.Animations[_selectedAnimation].Frames[_selectedFrame].SourceRectangle.X,
|
|
_animator.Animations[_selectedAnimation].Frames[_selectedFrame].CollisionRectangle.Y +
|
|
_animator.Animations[_selectedAnimation].Frames[_selectedFrame].SourceRectangle.Y,
|
|
_animator.Animations[_selectedAnimation].Frames[_selectedFrame].CollisionRectangle.Width,
|
|
_animator.Animations[_selectedAnimation].Frames[_selectedFrame].CollisionRectangle.Height), Color.Green * 0.5f);
|
|
|
|
spriteBatch.End();
|
|
}
|
|
|
|
public override void DrawTop(SpriteBatch spriteBatch)
|
|
{
|
|
if (_sprAnimator == null)
|
|
return;
|
|
|
|
float drawScale = 2;
|
|
|
|
if (_animator.CurrentAnimation.AnimationWidth > 0 && _animator.CurrentAnimation.AnimationHeight > 0)
|
|
{
|
|
if (_animator.CurrentAnimation.AnimationWidth > _animator.CurrentAnimation.AnimationHeight)
|
|
drawScale = (int)(RightBarWidth / (float)(_animator.CurrentAnimation.AnimationWidth + 2));
|
|
else
|
|
drawScale = (int)(RightBarWidth / (float)(_animator.CurrentAnimation.AnimationHeight + 2));
|
|
}
|
|
|
|
var drawOffsetX = Game1.WindowWidth - RightBarWidth / 2 -
|
|
(int)((_animator.CurrentAnimation.AnimationWidth + 2) * drawScale) / 2;
|
|
var drawOffsetY = Game1.WindowHeight - RightBarWidth / 2 -
|
|
(int)((_animator.CurrentAnimation.AnimationHeight + 2) * drawScale) / 2;
|
|
|
|
var drawPositionX = drawOffsetX + (int)drawScale +
|
|
(int)((_animator.CurrentFrame.Offset.X - _animator.CurrentAnimation.AnimationLeft) * drawScale);
|
|
var drawPositionY = drawOffsetY + (int)drawScale +
|
|
(int)((_animator.CurrentFrame.Offset.Y - _animator.CurrentAnimation.AnimationTop) * drawScale);
|
|
|
|
// draw the tiled background
|
|
spriteBatch.Draw(Resources.SprTiledBlock, new Rectangle(
|
|
drawOffsetX, drawOffsetY,
|
|
(int)((_animator.CurrentAnimation.AnimationWidth + 2) * drawScale),
|
|
(int)((_animator.CurrentAnimation.AnimationHeight + 2) * drawScale)),
|
|
new Rectangle(0, 0,
|
|
(int)((_animator.CurrentAnimation.AnimationWidth + 2) / (float)TileSize * 2),
|
|
(int)((_animator.CurrentAnimation.AnimationHeight + 2) / (float)TileSize * 2)), Color.White * 0.5f);
|
|
|
|
DrawOverlayAnimation(spriteBatch, drawOffsetX, drawOffsetY, drawScale);
|
|
|
|
// draw the current animation sprite
|
|
spriteBatch.Draw(_sprAnimator, new Rectangle(
|
|
drawPositionX, drawPositionY, (int)(drawScale * _animator.FrameWidth), (int)(drawScale * _animator.FrameHeight)),
|
|
_animator.CurrentFrame.SourceRectangle, Color.White, 0, Vector2.Zero,
|
|
(_animator.CurrentFrame.MirroredV ? SpriteEffects.FlipVertically : SpriteEffects.None) |
|
|
(_animator.CurrentFrame.MirroredH ? SpriteEffects.FlipHorizontally : SpriteEffects.None), 0);
|
|
|
|
// draw the origin xy axis
|
|
var originPosition = new Vector2(
|
|
drawPositionX + (-_animator.CurrentAnimation.Offset.X - _animator.CurrentFrame.Offset.X) * drawScale,
|
|
drawPositionY + (-_animator.CurrentAnimation.Offset.Y - _animator.CurrentFrame.Offset.Y) * drawScale);
|
|
spriteBatch.Draw(Resources.SprWhite, new Vector2(originPosition.X - 1, originPosition.Y - 10), new Rectangle(0, 0, 2, 20), Color.Green);
|
|
spriteBatch.Draw(Resources.SprWhite, new Vector2(originPosition.X - 10, originPosition.Y - 1), new Rectangle(0, 0, 20, 2), Color.Red);
|
|
}
|
|
|
|
private void DrawOverlayAnimation(SpriteBatch spriteBatch, int drawOffsetX, int drawOffsetY, float drawScale)
|
|
{
|
|
if (_overlayAnimator != null && _overlayAnimator.GetAnimationIndex(_animator.CurrentAnimation.Id) >= 0)
|
|
{
|
|
_overlayAnimator.Play(_animator.CurrentAnimation.Id);
|
|
// find the matching frame
|
|
var frameIndex = GetOverlayFrame();
|
|
|
|
_overlayAnimator.SetFrame(frameIndex);
|
|
|
|
var drawPositionX = drawOffsetX + (int)drawScale +
|
|
(int)((_overlayAnimator.CurrentFrame.Offset.X -
|
|
_animator.CurrentAnimation.AnimationLeft +
|
|
_overlayAnimator.CurrentAnimation.Offset.X -
|
|
_animator.CurrentAnimation.Offset.X) * drawScale);
|
|
var drawPositionY = drawOffsetY + (int)drawScale +
|
|
(int)((_overlayAnimator.CurrentFrame.Offset.Y -
|
|
_animator.CurrentAnimation.AnimationTop +
|
|
_overlayAnimator.CurrentAnimation.Offset.Y -
|
|
_animator.CurrentAnimation.Offset.Y) * drawScale);
|
|
|
|
spriteBatch.Draw(_overlayAnimator.SprTexture, new Rectangle(
|
|
drawPositionX, drawPositionY, (int)(drawScale * _overlayAnimator.FrameWidth),
|
|
(int)(drawScale * _overlayAnimator.FrameHeight)),
|
|
_overlayAnimator.CurrentFrame.SourceRectangle, Color.White, 0, Vector2.Zero,
|
|
(_overlayAnimator.CurrentFrame.MirroredV ? SpriteEffects.FlipVertically : SpriteEffects.None) |
|
|
(_overlayAnimator.CurrentFrame.MirroredH ? SpriteEffects.FlipHorizontally : SpriteEffects.None), 0);
|
|
}
|
|
}
|
|
|
|
private int GetOverlayFrame()
|
|
{
|
|
if (_overlayAnimator.CurrentAnimation.Frames.Length <= 0)
|
|
return 0;
|
|
|
|
// time to reach the selected frame
|
|
var frameTime = 0;
|
|
for (var i = 0; i < _animator.CurrentFrameIndex; i++)
|
|
frameTime += _animator.CurrentAnimation.Frames[i].FrameTime;
|
|
|
|
var index = 0;
|
|
while (frameTime >= 0)
|
|
{
|
|
frameTime -= _overlayAnimator.CurrentAnimation.Frames[index].FrameTime;
|
|
if (frameTime < 0)
|
|
return index;
|
|
|
|
if (_overlayAnimator.CurrentAnimation.Frames.Length > index + 1)
|
|
index++;
|
|
// loop animation
|
|
else
|
|
index = 0;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
private void UpdateCurrentFrame()
|
|
{
|
|
// update the size of the animation
|
|
_animator.RecalculateAnimationSize(_selectedAnimation);
|
|
}
|
|
|
|
public void CreateAnimator()
|
|
{
|
|
// create empty animator with one animation and frame
|
|
_animator = new Animator();
|
|
AddAnimation();
|
|
|
|
_animator.SpritePath = _sprPath;
|
|
}
|
|
|
|
public void AddAnimation()
|
|
{
|
|
var newAnimation = new Animation("a" + _animator.Animations.Count) { NextAnimation = "" };
|
|
|
|
_animator.AddAnimation(newAnimation);
|
|
_animator.AddFrame(_animator.Animations.Count - 1, 0, new Frame() { FrameTimeFps = 5 });
|
|
|
|
ChangeAnimation(_animator.Animations.Count - 1);
|
|
}
|
|
|
|
private void RemoveAnimation()
|
|
{
|
|
if (_animator.Animations.Count <= 1)
|
|
return;
|
|
|
|
_animator.Animations.Remove(_animator.Animations[_selectedAnimation]);
|
|
ChangeAnimation(_selectedAnimation % _animator.Animations.Count);
|
|
}
|
|
|
|
public void AddFrame()
|
|
{
|
|
var newFrame = new Frame()
|
|
{
|
|
SourceRectangle = _animator.Animations[_selectedAnimation].Frames[_selectedFrame].SourceRectangle,
|
|
Offset = _animator.Animations[_selectedAnimation].Frames[_selectedFrame].Offset,
|
|
FrameTimeFps = 5
|
|
};
|
|
|
|
_animator.AddFrame(_selectedAnimation, _selectedFrame + 1, newFrame);
|
|
|
|
_selectedFrame++;
|
|
UpdateInputUi();
|
|
}
|
|
|
|
public void DeleteFrame()
|
|
{
|
|
// cant delete the last frame
|
|
if (_animator.Animations[_selectedAnimation].Frames.Length <= 1)
|
|
return;
|
|
|
|
_animator.Stop();
|
|
|
|
// create new frame array without the selected frame
|
|
var newFrames = new Frame[_animator.Animations[_selectedAnimation].Frames.Length - 1];
|
|
var newIndex = 0;
|
|
for (var i = 0; i < _animator.Animations[_selectedAnimation].Frames.Length; i++)
|
|
if (i != _selectedFrame)
|
|
{
|
|
newFrames[newIndex] = _animator.Animations[_selectedAnimation].Frames[i];
|
|
newIndex++;
|
|
}
|
|
_animator.Animations[_selectedAnimation].Frames = newFrames;
|
|
|
|
if (_selectedFrame > 0)
|
|
_selectedFrame--;
|
|
|
|
UpdateInputUi();
|
|
}
|
|
|
|
public void ChangeAnimation(int nextAnimation)
|
|
{
|
|
_selectedAnimation = nextAnimation;
|
|
_selectedFrame = 0;
|
|
_animator.Play(_selectedAnimation);
|
|
|
|
UpdateInputUi();
|
|
}
|
|
|
|
public void ChangeFrame(int nextFrame)
|
|
{
|
|
_selectedFrame = nextFrame;
|
|
UpdateInputUi();
|
|
}
|
|
|
|
public void UpdateInputUi()
|
|
{
|
|
_animationInput.Value = _selectedAnimation + 1;
|
|
_frameInput.Value = _selectedFrame + 1;
|
|
|
|
_loopCountInput.Value = _animator.Animations[_selectedAnimation].LoopCount;
|
|
_fpsInput.Value = _animator.Animations[_selectedAnimation].Frames[_selectedFrame].FrameTimeFps;
|
|
|
|
_animationName.StrValue = _animator.Animations[_selectedAnimation].Id;
|
|
_nextAnimationName.StrValue = _animator.Animations[_selectedAnimation].NextAnimation;
|
|
|
|
_niAnOffsetX.Value = _animator.CurrentAnimation.Offset.X;
|
|
_niAnOffsetY.Value = _animator.CurrentAnimation.Offset.Y;
|
|
|
|
_numberInputX.Value = _animator.Animations[_selectedAnimation].Frames[_selectedFrame].SourceRectangle.X;
|
|
_numberInputY.Value = _animator.Animations[_selectedAnimation].Frames[_selectedFrame].SourceRectangle.Y;
|
|
_numberInputWidth.Value = _animator.Animations[_selectedAnimation].Frames[_selectedFrame].SourceRectangle.Width;
|
|
_numberInputHeight.Value = _animator.Animations[_selectedAnimation].Frames[_selectedFrame].SourceRectangle.Height;
|
|
|
|
_niOffsetX.Value = _animator.Animations[_selectedAnimation].Frames[_selectedFrame].Offset.X;
|
|
_niOffsetY.Value = _animator.Animations[_selectedAnimation].Frames[_selectedFrame].Offset.Y;
|
|
|
|
_cbFrameMirroredV.CurrentState = _animator.Animations[_selectedAnimation].Frames[_selectedFrame].MirroredV;
|
|
_cbFrameMirroredH.CurrentState = _animator.Animations[_selectedAnimation].Frames[_selectedFrame].MirroredH;
|
|
}
|
|
|
|
public void SaveAnimationDialog()
|
|
{
|
|
#if WINDOWS
|
|
var saveFileDialog = new SaveFileDialog()
|
|
{
|
|
RestoreDirectory = true,
|
|
Filter = "animator files (*.ani)|*.ani",
|
|
};
|
|
|
|
if (_lastFileName != null)
|
|
{
|
|
saveFileDialog.FileName = Path.GetFileName(_lastFileName);
|
|
saveFileDialog.InitialDirectory = Path.GetFullPath(Path.GetDirectoryName(_lastFileName));
|
|
}
|
|
|
|
if (saveFileDialog.ShowDialog() == DialogResult.OK)
|
|
AnimatorSaveLoad.SaveAnimator(saveFileDialog.FileName, _animator);
|
|
#endif
|
|
}
|
|
|
|
public void SaveAnimation()
|
|
{
|
|
AnimatorSaveLoad.SaveAnimator(_lastFileName, _animator);
|
|
}
|
|
|
|
public void LoadAnimation()
|
|
{
|
|
#if WINDOWS
|
|
var openFileDialog = new OpenFileDialog()
|
|
{
|
|
Filter = "animator files (*.ani)|*.ani"
|
|
};
|
|
|
|
if (openFileDialog.ShowDialog() != DialogResult.OK)
|
|
return;
|
|
|
|
EditorLoadAnimation(openFileDialog.FileName);
|
|
#endif
|
|
}
|
|
|
|
public void EditorLoadAnimation(string filePath)
|
|
{
|
|
_selectedAnimation = 0;
|
|
_selectedFrame = 0;
|
|
_lastFileName = filePath;
|
|
_animator = AnimatorSaveLoad.LoadAnimatorFile(filePath);
|
|
_sprAnimator = _animator.SprTexture;
|
|
|
|
UpdateInputUi();
|
|
}
|
|
|
|
private void LoadOverlayAnimation()
|
|
{
|
|
#if WINDOWS
|
|
var openFileDialog = new OpenFileDialog()
|
|
{
|
|
Filter = "animator files (*.ani)|*.ani"
|
|
};
|
|
|
|
if (openFileDialog.ShowDialog() != DialogResult.OK) return;
|
|
|
|
_overlayAnimator = AnimatorSaveLoad.LoadAnimatorFile(openFileDialog.FileName);
|
|
#endif
|
|
}
|
|
|
|
public void UpdateAnimations()
|
|
{
|
|
#if WINDOWS
|
|
var openFileDialog = new OpenFileDialog()
|
|
{
|
|
Filter = "animator files (*.ani)|*.ani",
|
|
Multiselect = true
|
|
};
|
|
|
|
if (openFileDialog.ShowDialog() != DialogResult.OK) return;
|
|
|
|
foreach (var fileName in openFileDialog.FileNames)
|
|
{
|
|
_animator = AnimatorSaveLoad.LoadAnimatorFile(fileName);
|
|
AnimatorSaveLoad.SaveAnimator(fileName, _animator);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
public void LoadImage()
|
|
{
|
|
#if WINDOWS
|
|
var openFileDialog = new OpenFileDialog()
|
|
{
|
|
Filter = "png files (*.png)|*.png"
|
|
};
|
|
|
|
if (openFileDialog.ShowDialog() != DialogResult.OK) return;
|
|
|
|
try
|
|
{
|
|
using (var stream = File.OpenRead(openFileDialog.FileName))
|
|
{
|
|
_sprAnimator = Texture2D.FromStream(Game1.Graphics.GraphicsDevice, stream);
|
|
_sprPath = Path.GetFileName(openFileDialog.FileName);
|
|
_animator.SpritePath = _sprPath;
|
|
}
|
|
}
|
|
catch { }
|
|
#endif
|
|
}
|
|
|
|
}
|
|
}
|