mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/PCK-Studio.git
synced 2026-05-24 08:26:08 +00:00
147 lines
4.1 KiB
C#
147 lines
4.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Drawing;
|
|
using PckStudio.Classes.Extentions;
|
|
using System.Text;
|
|
|
|
|
|
// TODO: change namespace
|
|
namespace PckStudio.Forms.Editor
|
|
{
|
|
sealed class Animation
|
|
{
|
|
public const int MinimumFrameTime = 1;
|
|
|
|
public int FrameCount => frames.Count;
|
|
|
|
public int TextureCount => frameTextures.Count;
|
|
|
|
public Frame this[int frameIndex] => frames[frameIndex];
|
|
|
|
// TODO: implement this
|
|
public bool Interpolate { get; set; } = false;
|
|
|
|
private readonly List<Image> frameTextures;
|
|
|
|
private readonly List<Frame> frames = new List<Frame>();
|
|
|
|
|
|
public Animation(IEnumerable<Image> image)
|
|
{
|
|
frameTextures = new List<Image>(image);
|
|
}
|
|
|
|
public Animation(IEnumerable<Image> frameTextures, string ANIM) : this(frameTextures)
|
|
{
|
|
ParseAnim(ANIM);
|
|
}
|
|
|
|
public struct Frame
|
|
{
|
|
public readonly Image Texture;
|
|
public int Ticks;
|
|
|
|
public Frame(Image texture) : this(texture, MinimumFrameTime)
|
|
{ }
|
|
|
|
public Frame(Image texture, int frameTime)
|
|
{
|
|
Texture = texture;
|
|
Ticks = frameTime;
|
|
}
|
|
}
|
|
|
|
private void ParseAnim(string ANIM)
|
|
{
|
|
_ = ANIM ?? throw new ArgumentNullException(nameof(ANIM));
|
|
ANIM = (Interpolate = ANIM.StartsWith("#")) ? ANIM.Substring(1) : ANIM;
|
|
string[] animData = ANIM.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
|
int lastFrameTime = MinimumFrameTime;
|
|
if (animData.Length <= 0)
|
|
for (int i = 0; i < TextureCount; i++)
|
|
{
|
|
AddFrame(i);
|
|
}
|
|
|
|
foreach (string frameInfo in animData)
|
|
{
|
|
string[] frameData = frameInfo.Split('*');
|
|
//if (frameData.Length < 2)
|
|
// continue; // shouldn't happen
|
|
int currentFrameIndex = 0;
|
|
int.TryParse(frameData[0], out currentFrameIndex);
|
|
|
|
// Some textures like the Halloween 2015's Lava texture don't have a
|
|
// frame time parameter for certain frames.
|
|
// This will detect that and place the last frame time in its place.
|
|
// This is accurate to console edition behavior.
|
|
// - MattNL
|
|
int currentFrameTime = string.IsNullOrEmpty(frameData[1]) ? lastFrameTime : int.Parse(frameData[1]);
|
|
AddFrame(currentFrameIndex, currentFrameTime);
|
|
lastFrameTime = currentFrameTime;
|
|
}
|
|
}
|
|
|
|
public Frame AddFrame(int frameTextureIndex) => AddFrame(frameTextureIndex, MinimumFrameTime);
|
|
public Frame AddFrame(int frameTextureIndex, int frameTime)
|
|
{
|
|
if (frameTextureIndex < 0 || frameTextureIndex >= frameTextures.Count)
|
|
throw new ArgumentOutOfRangeException(nameof(frameTextureIndex));
|
|
Frame f = new Frame(frameTextures[frameTextureIndex], frameTime);
|
|
frames.Add(f);
|
|
return f;
|
|
}
|
|
|
|
public bool RemoveFrame(int frameIndex)
|
|
{
|
|
frames.RemoveAt(frameIndex);
|
|
return true;
|
|
}
|
|
|
|
public Frame GetFrame(int index) => frames[index];
|
|
|
|
public List<Frame> GetFrames()
|
|
{
|
|
return frames;
|
|
}
|
|
|
|
public List<Image> GetFrameTextures()
|
|
{
|
|
return frameTextures;
|
|
}
|
|
|
|
public int GetTextureIndex(Image frameTexture)
|
|
{
|
|
_ = frameTexture ?? throw new ArgumentNullException(nameof(frameTexture));
|
|
return frameTextures.IndexOf(frameTexture);
|
|
}
|
|
|
|
public void SetFrame(Frame frame, int frameTextureIndex, int frameTime = MinimumFrameTime)
|
|
=> SetFrame(frames.IndexOf(frame), frameTextureIndex, frameTime);
|
|
public void SetFrame(int frameIndex, int frameTextureIndex, int frameTime = MinimumFrameTime)
|
|
{
|
|
frames[frameIndex] = new Frame(frameTextures[frameTextureIndex], frameTime);
|
|
}
|
|
|
|
public string BuildAnim()
|
|
{
|
|
StringBuilder stringBuilder = new StringBuilder(Interpolate ? "#" : string.Empty);
|
|
foreach (var frame in frames)
|
|
stringBuilder.Append($"{GetTextureIndex(frame.Texture)}*{frame.Ticks},");
|
|
return stringBuilder.ToString(0, stringBuilder.Length - 1);
|
|
}
|
|
|
|
public Image BuildTexture(bool isClockOrCompass, List<Image> linearImages = default!)
|
|
{
|
|
int width = frameTextures[0].Width;
|
|
int height = frameTextures[0].Height;
|
|
if (width != height)
|
|
throw new Exception("Invalid size");
|
|
|
|
var textures = isClockOrCompass ? linearImages : frameTextures;
|
|
|
|
return ImageExtentions.ImageFromImageArray(textures.ToArray(), ImageExtentions.ImageLayoutDirection.Vertical);
|
|
}
|
|
}
|
|
}
|