mirror of
https://github.com/LorisYounger/VPet.git
synced 2024-08-30 18:42:36 +00:00
284 lines
11 KiB
C#
284 lines
11 KiB
C#
using LinePutScript;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using System.Windows;
|
|
using System.Windows.Controls;
|
|
using System.Windows.Media;
|
|
using System.Windows.Media.Imaging;
|
|
using static VPet_Simulator.Core.IGraph;
|
|
|
|
namespace VPet_Simulator.Core
|
|
{
|
|
/// <summary>
|
|
/// 食物动画 支持显示前中后3层夹心动画
|
|
/// 不一定只用于食物,只是叫这个名字
|
|
/// </summary>
|
|
public class FoodAnimation : IRunImage
|
|
{
|
|
/// <summary>
|
|
/// 创建食物动画 第二层夹心为运行时提供
|
|
/// </summary>
|
|
/// <param name="graphCore">动画核心</param>
|
|
/// <param name="graphinfo">动画信息</param>
|
|
/// <param name="front_Lay">前层 动画名</param>
|
|
/// <param name="back_Lay">后层 动画名</param>
|
|
/// <param name="animations">中间层运动轨迹</param>
|
|
/// <param name="isLoop">是否循环</param>
|
|
public FoodAnimation(GraphCore graphCore, GraphInfo graphinfo, string front_Lay,
|
|
string back_Lay, ILine animations, bool isLoop = false)
|
|
{
|
|
IsLoop = isLoop;
|
|
GraphInfo = graphinfo;
|
|
GraphCore = graphCore;
|
|
Front_Lay = front_Lay;
|
|
Back_Lay = back_Lay;
|
|
Animations = new List<Animation>();
|
|
int i = 0;
|
|
ISub sub = animations.Find("a" + i);
|
|
while (sub != null)
|
|
{
|
|
Animations.Add(new Animation(this, sub));
|
|
sub = animations.Find("a" + ++i);
|
|
}
|
|
IsReady = true;
|
|
}
|
|
|
|
public static void LoadGraph(GraphCore graph, FileSystemInfo path, ILine info)
|
|
{
|
|
bool isLoop = info[(gbol)"loop"];
|
|
FoodAnimation pa = new FoodAnimation(graph, new GraphInfo(path, info), info[(gstr)"front_lay"], info[(gstr)"back_lay"], info, isLoop);
|
|
graph.AddGraph(pa);
|
|
}
|
|
/// <summary>
|
|
/// 前层名字
|
|
/// </summary>
|
|
public string Front_Lay;
|
|
/// <summary>
|
|
/// 后层名字
|
|
/// </summary>
|
|
public string Back_Lay;
|
|
/// <summary>
|
|
/// 所有动画帧
|
|
/// </summary>
|
|
public List<Animation> Animations;
|
|
|
|
/// <summary>
|
|
/// 是否循环播放
|
|
/// </summary>
|
|
public bool IsLoop { get; set; }
|
|
|
|
/// <summary>
|
|
/// 动画信息
|
|
/// </summary>
|
|
public GraphInfo GraphInfo { get; private set; }
|
|
/// <summary>
|
|
/// 是否准备完成
|
|
/// </summary>
|
|
public bool IsReady { get; set; } = false;
|
|
public bool IsFail => false;
|
|
public string FailMessage => "";
|
|
|
|
public TaskControl Control { get; set; }
|
|
|
|
int nowid;
|
|
/// <summary>
|
|
/// 图片资源
|
|
/// </summary>
|
|
public string Path;
|
|
private GraphCore GraphCore;
|
|
/// <summary>
|
|
/// 单帧动画
|
|
/// </summary>
|
|
public class Animation
|
|
{
|
|
private FoodAnimation parent;
|
|
public Thickness MarginWI;
|
|
public double Rotate = 0;
|
|
public double Opacity = 1;
|
|
public bool IsVisiable = true;
|
|
public double Width;
|
|
/// <summary>
|
|
/// 帧时间
|
|
/// </summary>
|
|
public int Time;
|
|
/// <summary>
|
|
/// 创建单帧动画
|
|
/// </summary>
|
|
/// <param name="parent">FoodAnimation</param>
|
|
/// <param name="time">持续时间</param>
|
|
/// <param name="wx"></param>
|
|
public Animation(FoodAnimation parent, int time, Thickness wx, double width, double rotate = 0, bool isVisiable = true, double opacity = 1)
|
|
{
|
|
this.parent = parent;
|
|
Time = time;
|
|
MarginWI = wx;
|
|
Rotate = rotate;
|
|
IsVisiable = isVisiable;
|
|
Width = width;
|
|
Opacity = opacity;
|
|
}
|
|
/// <summary>
|
|
/// 创建单帧动画
|
|
/// </summary>
|
|
public Animation(FoodAnimation parent, ISub sub)
|
|
{
|
|
this.parent = parent;
|
|
var strs = sub.GetInfos();
|
|
Time = int.Parse(strs[0]);//0: Time
|
|
if (strs.Length == 1)
|
|
IsVisiable = false;
|
|
else
|
|
{//1,2: Margin X,Y
|
|
Width = double.Parse(strs[3]);//3:Width
|
|
MarginWI = new Thickness(double.Parse(strs[1]), double.Parse(strs[2]), 0, 0);
|
|
if (strs.Length > 4)
|
|
{
|
|
Rotate = double.Parse(strs[4]);//Rotate
|
|
if (strs.Length > 5)
|
|
Opacity = double.Parse(strs[5]);//Opacity
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 运行该图层
|
|
/// </summary>
|
|
public void Run(FrameworkElement This, TaskControl Control)
|
|
{
|
|
//先显示该图层
|
|
This.Dispatcher.Invoke(() =>
|
|
{
|
|
if (IsVisiable)
|
|
{
|
|
This.Visibility = Visibility.Visible;
|
|
This.Margin = MarginWI;
|
|
This.LayoutTransform = new RotateTransform(Rotate);
|
|
This.Opacity = Opacity;
|
|
This.Width = Width;
|
|
This.Height = Width;
|
|
}
|
|
else
|
|
{
|
|
This.Visibility = Visibility.Collapsed;
|
|
}
|
|
|
|
});
|
|
//然后等待帧时间毫秒
|
|
Thread.Sleep(Time);
|
|
//判断是否要下一步
|
|
switch (Control.Type)
|
|
{
|
|
case TaskControl.ControlType.Stop:
|
|
Control.EndAction?.Invoke();
|
|
return;
|
|
case TaskControl.ControlType.Status_Stoped:
|
|
return;
|
|
case TaskControl.ControlType.Status_Quo:
|
|
case TaskControl.ControlType.Continue:
|
|
if (++parent.nowid >= parent.Animations.Count)
|
|
if (parent.IsLoop)
|
|
{
|
|
parent.nowid = 0;
|
|
//让循环动画重新开始立线程,不stackoverflow
|
|
Task.Run(() => parent.Animations[0].Run(This, Control));
|
|
return;
|
|
}
|
|
else if (Control.Type == TaskControl.ControlType.Continue)
|
|
{
|
|
Control.Type = TaskControl.ControlType.Status_Quo;
|
|
parent.nowid = 0;
|
|
}
|
|
else
|
|
{
|
|
//parent.endwilldo = () => parent.Dispatcher.Invoke(Hidden);
|
|
//parent.Dispatcher.Invoke(Hidden);
|
|
Control.Type = TaskControl.ControlType.Status_Stoped;
|
|
//等待其他两个动画完成
|
|
Control.EndAction?.Invoke(); //运行结束动画时事件
|
|
////延时隐藏
|
|
//Task.Run(() =>
|
|
//{
|
|
// Thread.Sleep(25);
|
|
// parent.Dispatcher.Invoke(Hidden);
|
|
//});
|
|
return;
|
|
}
|
|
//要下一步,现在就隐藏图层
|
|
//隐藏该图层
|
|
//parent.Dispatcher.Invoke(Hidden);
|
|
parent.Animations[parent.nowid].Run(This, Control);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
public static FoodAnimatGrid FoodGrid = new FoodAnimatGrid();
|
|
public class FoodAnimatGrid : Grid
|
|
{
|
|
public FoodAnimatGrid()
|
|
{
|
|
Width = 500;
|
|
Height = 500;
|
|
VerticalAlignment = VerticalAlignment.Top;
|
|
HorizontalAlignment = HorizontalAlignment.Left;
|
|
Front = new Image();
|
|
Back = new Image();
|
|
Food = new Image
|
|
{
|
|
RenderTransformOrigin = new Point(0.5, 0.5),
|
|
VerticalAlignment = VerticalAlignment.Top,
|
|
HorizontalAlignment = HorizontalAlignment.Left,
|
|
Visibility = Visibility.Collapsed,
|
|
};
|
|
this.Children.Add(Back);
|
|
this.Children.Add(Food);
|
|
this.Children.Add(Front);
|
|
}
|
|
public Image Front;
|
|
public Image Food;
|
|
public Image Back;
|
|
}
|
|
|
|
public void Run(Decorator parant, Action EndAction = null) => Run(parant, null, EndAction);
|
|
|
|
public void Run(Decorator parant, ImageSource image, Action EndAction = null)
|
|
{
|
|
if (Control?.PlayState == true)
|
|
{//如果当前正在运行,重置状态
|
|
Control.Stop(() => Run(parant, EndAction));
|
|
return;
|
|
}
|
|
nowid = 0;
|
|
Control = new TaskControl(EndAction);
|
|
parant.Dispatcher.Invoke(() =>
|
|
{
|
|
parant.Tag = this;
|
|
if (parant.Child != FoodGrid)
|
|
{
|
|
if (FoodGrid.Parent != null)
|
|
{
|
|
((Decorator)FoodGrid.Parent).Child = null;
|
|
}
|
|
parant.Child = FoodGrid;
|
|
}
|
|
var FL = GraphCore.FindGraph(Front_Lay, GraphInfo.Animat, GraphInfo.ModeType);
|
|
var BL = GraphCore.FindGraph(Back_Lay, GraphInfo.Animat, GraphInfo.ModeType);
|
|
var t1 = FL?.Run(FoodGrid.Front);
|
|
var t2 = BL?.Run(FoodGrid.Back);
|
|
if (FoodGrid.Food.Source != image)
|
|
{
|
|
if (FoodGrid.Food.Source is BitmapImage bitmapImage)
|
|
{//内存回收
|
|
bitmapImage.StreamSource?.Dispose();
|
|
}
|
|
FoodGrid.Food.Source = image;
|
|
}
|
|
t1?.Start();
|
|
t2?.Start();
|
|
Task.Run(() => Animations[0].Run(FoodGrid.Food, Control));
|
|
});
|
|
}
|
|
}
|
|
}
|