新动画核心

This commit is contained in:
ZouJin 2023-03-27 09:35:19 +11:00
parent 9603cfaeb8
commit 47c1721134
11 changed files with 228 additions and 201 deletions

View File

@ -62,11 +62,17 @@ namespace VPet_Simulator.Core
}
var ig = Core.Graph.FindGraph(GraphCore.GraphType.StartUP, core.Save.Mode);
PetGrid.Child = ig.This;
var ig2 = Core.Graph.FindGraph(GraphCore.GraphType.Default, core.Save.Mode);
PetGrid2.Child = ig2.This; //用于缓存
//var ig2 = Core.Graph.FindGraph(GraphCore.GraphType.Default, core.Save.Mode);
PetGrid2.Visibility = Visibility.Collapsed;
ig.WaitForReadyRun(DisplayNomal);
ig.WaitForReadyRun(PetGrid,()=> {
Dispatcher.Invoke(() => {
PetGrid.Tag = ig;
PetGrid2.Tag = ig;
});
DisplayNomal();
});
EventTimer.Elapsed += EventTimer_Elapsed;

View File

@ -1085,60 +1085,54 @@ namespace VPet_Simulator.Core
// Dispatcher.Invoke(() => Say(graph.GraphType.ToString()));
//}
DisplayType = graph.GraphType;
if (PetGrid.Child == graph.This)
var PetGridTag = Dispatcher.Invoke(() => PetGrid.Tag);
var PetGrid2Tag = Dispatcher.Invoke(() => PetGrid2.Tag);
if (PetGridTag == graph)
{
petgridcrlf = true;
((IGraph)(PetGrid2.Child)).Stop(true);
((IGraph)(PetGrid2Tag)).Stop(true);
Dispatcher.Invoke(() =>
{
PetGrid.Visibility = Visibility.Visible;
PetGrid2.Visibility = Visibility.Hidden;
});
graph.Run(EndAction);
graph.Run(PetGrid, EndAction);//(x) => PetGrid.Child = x
return;
}
else if (PetGrid2.Child == graph.This)
else if (PetGrid2Tag == graph)
{
petgridcrlf = false;
((IGraph)(PetGrid.Child)).Stop(true);
((IGraph)(PetGridTag)).Stop(true);
Dispatcher.Invoke(() =>
{
PetGrid2.Visibility = Visibility.Visible;
PetGrid.Visibility = Visibility.Hidden;
});
graph.Run(EndAction);
graph.Run(PetGrid2, EndAction);
return;
}
graph.Run(EndAction);
if (petgridcrlf)
{
((IGraph)(PetGrid.Child)).Stop(true);
((IGraph)(PetGridTag)).Stop(true);
Dispatcher.Invoke(() =>
{
PetGrid2.Child = graph.This;
PetGrid.Visibility = Visibility.Hidden;
PetGrid2.Visibility = Visibility.Visible;
//PetGrid2.Tag = graph;
});
//Task.Run(() =>
//{
// Thread.Sleep(25);
// Dispatcher.Invoke(() => PetGrid.Child = null);
//});
graph.Run(PetGrid2, EndAction);
}
else
{
((IGraph)(PetGrid2.Child)).Stop(true);
((IGraph)(PetGrid2Tag)).Stop(true);
Dispatcher.Invoke(() =>
{
PetGrid.Child = graph.This;
PetGrid2.Visibility = Visibility.Hidden;
PetGrid.Visibility = Visibility.Visible;
//PetGrid.Tag = graph;
});
//Task.Run(() =>
//{
// Thread.Sleep(25);
// Dispatcher.Invoke(() => PetGrid2.Child = null);
//});
graph.Run(PetGrid, EndAction);
}
petgridcrlf = !petgridcrlf;

View File

@ -3,7 +3,6 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:VPet_Simulator.Core.Graph"
mc:Ignorable="d" d:DesignHeight="500" d:DesignWidth="500">
<Grid>

View File

@ -6,6 +6,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;
namespace VPet_Simulator.Core
{
@ -14,6 +15,8 @@ namespace VPet_Simulator.Core
/// </summary>
public class GraphCore
{
public GraphCore()
{
if (!Directory.Exists(CachePath))
@ -289,7 +292,14 @@ namespace VPet_Simulator.Core
/// 图像字典
/// </summary>
public Dictionary<GraphType, List<IGraph>> Graphs = new Dictionary<GraphType, List<IGraph>>();
/// <summary>
/// 通用UI资源
/// </summary>
public Dictionary<string, UIElement> CommUIElements = new Dictionary<string, UIElement>();
/// <summary>
/// 通用设置属性/方法
/// </summary>
public Dictionary<string, dynamic> CommConfig = new Dictionary<string, dynamic>();
/// <summary>
/// 添加动画
/// </summary>
@ -324,10 +334,10 @@ namespace VPet_Simulator.Core
if (paths.Length == 0)
return;
if (paths.Length == 1)
AddGraph(new Picture(paths[0].FullName, modetype, graphtype,
AddGraph(new Picture(this, paths[0].FullName, modetype, graphtype,
int.Parse(paths[0].Name.Split('.').Reverse().ToArray()[1].Split('_').Last())), graphtype);
else
AddGraph(new PNGAnimation(path, paths, modetype, graphtype), graphtype);
AddGraph(new PNGAnimation(this, path, paths, modetype, graphtype), graphtype);
}
/// <summary>
/// 随机数字典(用于确保随机动画不会错位)

View File

@ -4,6 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using static VPet_Simulator.Core.GraphCore;
namespace VPet_Simulator.Core
@ -16,7 +17,7 @@ namespace VPet_Simulator.Core
/// <summary>
/// 从0开始运行该动画
/// </summary>
void Run(Action EndAction = null);
void Run(Border parant, Action EndAction = null);
/// <summary>
/// 当前动画播放状态
/// </summary>
@ -32,7 +33,7 @@ namespace VPet_Simulator.Core
/// <summary>
/// 从0开始运行该动画, 等待部署完成后执行
/// </summary>
void WaitForReadyRun(Action EndAction = null);
void WaitForReadyRun(Border parant, Action EndAction = null);
///// <summary>//经过测试,储存到内存好处多多,不储存也要占用很多内存,干脆存了吧
///// 是否储存到内存以支持快速显示
///// </summary>
@ -46,10 +47,6 @@ namespace VPet_Simulator.Core
/// </summary>
GraphType GraphType { get; }
/// <summary>
/// 当前UI
/// </summary>
UIElement This { get; }
/// <summary>
/// 停止动画
/// </summary>
/// <param name="StopEndAction">停止动画时是否允许执行停止帧</param>

View File

@ -28,7 +28,7 @@ namespace VPet_Simulator.Core
/// <summary>
/// PNGAnimation.xaml 的交互逻辑
/// </summary>
public partial class PNGAnimation : System.Windows.Controls.Image, IGraph
public partial class PNGAnimation : IGraph
{
/// <summary>
/// 所有动画帧
@ -50,15 +50,6 @@ namespace VPet_Simulator.Core
/// 是否循环播放
/// </summary>
public bool IsContinue { get; set; } = false;
///// <summary>
///// 是否重置状态从0开始播放
///// </summary>
//public bool IsResetPlay { get; set; } = false;
///// <summary>//经过测试,储存到内存好处多多,不储存也要占用很多内存,干脆存了吧
///// 是否储存到内存以支持快速显示
///// </summary>
//public bool StoreMemory { get; private set; }
public UIElement This => this;
public Save.ModeType ModeType { get; private set; }
@ -76,28 +67,29 @@ namespace VPet_Simulator.Core
/// 图片资源
/// </summary>
public MemoryStream stream;
/// <summary>
/// 回收图片资源Timer
/// </summary>
public System.Timers.Timer GCTimer = new System.Timers.Timer()
{
Interval = 10000,
AutoReset = false,
};
private GraphCore GraphCore;
/// <summary>
/// 新建 PNG 动画
/// </summary>
/// <param name="path">文件夹位置</param>
/// <param name="paths">文件内容列表</param>
/// <param name="isLoop">是否循环</param>
public PNGAnimation(string path, FileInfo[] paths, Save.ModeType modetype, GraphCore.GraphType graphtype, bool isLoop = false)
public PNGAnimation(GraphCore graphCore, string path, FileInfo[] paths, Save.ModeType modetype, GraphCore.GraphType graphtype, bool isLoop = false)
{
InitializeComponent();
Animations = new List<Animation>();
IsLoop = isLoop;
//StoreMemory = storemem;
GraphType = graphtype;
ModeType = modetype;
GraphCore = graphCore;
if (!GraphCore.CommConfig.ContainsKey("PA_Setup"))
{
GraphCore.CommConfig["PA_Setup"] = true;
GraphCore.CommUIElements["Image1.PNGAnimation"] = new System.Windows.Controls.Image() { Height = 500 };
GraphCore.CommUIElements["Image2.PNGAnimation"] = new System.Windows.Controls.Image() { Height = 500 };
GraphCore.CommUIElements["Image3.PNGAnimation"] = new System.Windows.Controls.Image() { Height = 500 };
}
Task.Run(() => startup(path, paths));
//if (storemem)
//foreach (var file in paths)
@ -163,20 +155,22 @@ namespace VPet_Simulator.Core
// , () => imgs[last % 3].Visibility = Visibility.Hidden));
//}
}
public double Width;
private void startup(string path, FileInfo[] paths)
{
//新方法:加载大图片
//生成大文件加载非常慢,先看看有没有缓存能用
string cp = GraphCore.CachePath + $"\\{Sub.GetHashCode(path)}_{paths.Length}.png";
Dispatcher.Invoke(() => Width = 500 * (paths.Length + 1));
Width = 500 * (paths.Length + 1);
if (File.Exists(cp))
{
for (int i = 0; i < paths.Length; i++)
{
FileInfo file = paths[i];
int time = int.Parse(file.Name.Split('.').Reverse().ToArray()[1].Split('_').Last());
int wxi = -500 * i;
Animations.Add(new Animation(this, time, () => Margin = new Thickness(wxi, 0, 0, 0)));
Animations.Add(new Animation(this, time, -500 * i));
}
}
else
@ -193,8 +187,7 @@ namespace VPet_Simulator.Core
FileInfo file = paths[i];
int time = int.Parse(file.Name.Split('.').Reverse().ToArray()[1].Split('_').Last());
graph.DrawImage(imgs[i], w * i, 0, w, h);
int wxi = -500 * i;
Animations.Add(new Animation(this, time, () => Margin = new Thickness(wxi, 0, 0, 0)));
Animations.Add(new Animation(this, time, -500 * i));
}
joinedBitmap.Save(cp);
graph.Dispose();
@ -202,12 +195,6 @@ namespace VPet_Simulator.Core
imgs.ForEach(x => x.Dispose());
}
stream = new MemoryStream(File.ReadAllBytes(cp));
//GCTimer
GCTimer.Elapsed += (a, b) =>
{
Dispatcher.Invoke(() => Source = null);
GC.Collect();
};
IsReady = true;
}
@ -218,10 +205,11 @@ namespace VPet_Simulator.Core
public class Animation
{
private PNGAnimation parent;
/// <summary>
/// 显示
/// </summary>
public Action Visible;
public int MarginWIX;
///// <summary>
///// 显示
///// </summary>
//public Action Visible;
///// <summary>
///// 隐藏
///// </summary>
@ -230,20 +218,21 @@ namespace VPet_Simulator.Core
/// 帧时间
/// </summary>
public int Time;
public Animation(PNGAnimation parent, int time, Action visible)//, Action hidden)
public Animation(PNGAnimation parent, int time, int wxi)//, Action hidden)
{
this.parent = parent;
Time = time;
Visible = visible;
//Visible = visible;
//Hidden = hidden;
MarginWIX = wxi;
}
/// <summary>
/// 运行该图层
/// </summary>
public void Run(Action EndAction = null)
public void Run(FrameworkElement This, Action EndAction = null)
{
//先显示该图层
parent.Dispatcher.Invoke(Visible);
This.Dispatcher.Invoke(() => This.Margin = new Thickness(MarginWIX, 0, 0, 0));
//然后等待帧时间毫秒
Thread.Sleep(Time);
//判断是否要下一步
@ -266,7 +255,6 @@ namespace VPet_Simulator.Core
EndAction?.Invoke();//运行结束动画时事件
parent.StopAction?.Invoke();
parent.StopAction = null;
parent.GCTimer.Start();
////延时隐藏
//Task.Run(() =>
//{
@ -278,7 +266,7 @@ namespace VPet_Simulator.Core
//要下一步,现在就隐藏图层
//隐藏该图层
//parent.Dispatcher.Invoke(Hidden);
parent.Animations[parent.nowid].Run(EndAction);
parent.Animations[parent.nowid].Run(This, EndAction);
return;
}
else
@ -289,7 +277,6 @@ namespace VPet_Simulator.Core
EndAction?.Invoke();//运行结束动画时事件
parent.StopAction?.Invoke();
parent.StopAction = null;
parent.GCTimer.Start();
//Task.Run(() =>
//{
// Thread.Sleep(25);
@ -301,7 +288,7 @@ namespace VPet_Simulator.Core
/// <summary>
/// 从0开始运行该动画
/// </summary>
public void Run(Action EndAction = null)
public void Run(Border parant, Action EndAction = null)
{
//if(endwilldo != null && nowid != Animations.Count)
//{
@ -312,27 +299,53 @@ namespace VPet_Simulator.Core
{//如果当前正在运行,重置状态
//IsResetPlay = true;
Stop(true);
StopAction = () => Run(EndAction);
StopAction = () => Run(parant, EndAction);
return;
}
nowid = 0;
PlayState = true;
DoEndAction = true;
GCTimer.Enabled = false;
if (Dispatcher.Invoke<bool>(() => Source == null))
parant.Dispatcher.Invoke(() =>
{
Dispatcher.Invoke(() =>
if (parant.Tag == this)
{
var bitmap = new BitmapImage();
bitmap.BeginInit();
stream.Seek(0, SeekOrigin.Begin);
bitmap.StreamSource = stream;
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.EndInit();
Source = bitmap;
});
}
new Thread(() => Animations[0].Run(EndAction)).Start();
new Thread(() => Animations[0].Run(parant, EndAction)).Start();
return;
}
System.Windows.Controls.Image img;
if (parant.Child == GraphCore.CommUIElements["Image1.PNGAnimation"])
{
img = (System.Windows.Controls.Image)GraphCore.CommUIElements["Image1.PNGAnimation"];
}
else
{
img = (System.Windows.Controls.Image)GraphCore.CommUIElements["Image2.PNGAnimation"];
if (parant.Child != GraphCore.CommUIElements["Image2.PNGAnimation"])
{
if (img.Parent == null)
{
parant.Child = img;
}
else
{
img = (System.Windows.Controls.Image)GraphCore.CommUIElements["Image3.PNGAnimation"];
parant.Child = img;
}
}
}
parant.Tag = this;
var bitmap = new BitmapImage();
bitmap.BeginInit();
stream.Seek(0, SeekOrigin.Begin);
bitmap.StreamSource = stream;
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.EndInit();
img.Source = bitmap;
img.Width = Width;
new Thread(() => Animations[0].Run(parant, EndAction)).Start();
});
}
public void Stop(bool StopEndAction = false)
@ -342,7 +355,7 @@ namespace VPet_Simulator.Core
//IsResetPlay = false;
}
public void WaitForReadyRun(Action EndAction = null)
public void WaitForReadyRun(Border parant, Action EndAction = null)
{
Task.Run(() =>
{
@ -350,7 +363,7 @@ namespace VPet_Simulator.Core
{
Thread.Sleep(100);
}
Run(EndAction);
Run(parant, EndAction);
});
}
}

View File

@ -1,9 +0,0 @@
<Image x:Class="VPet_Simulator.Core.PNGAnimation"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:VPet_Simulator.Core"
mc:Ignorable="d"
d:DesignHeight="500" d:DesignWidth="500">
</Image>

View File

@ -0,0 +1,113 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Media.Imaging;
using System.Windows;
using System.IO;
using System.Windows.Controls;
namespace VPet_Simulator.Core
{
/// <summary>
/// Picture.xaml 的交互逻辑
/// </summary>
public partial class Picture : IGraph
{
/// <summary>
/// 新建新静态图像
/// </summary>
/// <param name="path">图片路径</param>
public Picture(GraphCore graphCore, string path, Save.ModeType modetype, GraphCore.GraphType graphType, int length = 1000, bool isloop = false)
{
ModeType = modetype;
IsLoop = isloop;
Length = length;
GraphCore = graphCore;
stream = new MemoryStream(File.ReadAllBytes(path));
GraphType = graphType;
if (!GraphCore.CommConfig.ContainsKey("PIC_Setup"))
{
GraphCore.CommConfig["PIC_Setup"] = true;
GraphCore.CommUIElements["Image1.Picture"] = new System.Windows.Controls.Image() { Width = 500, Height = 500 };
GraphCore.CommUIElements["Image2.Picture"] = new System.Windows.Controls.Image() { Width = 500, Height = 500 };
GraphCore.CommUIElements["Image3.Picture"] = new System.Windows.Controls.Image() { Width = 500, Height = 500 };
}
}
/// <summary>
/// 图片资源
/// </summary>
public MemoryStream stream;
public Save.ModeType ModeType { get; private set; }
private GraphCore GraphCore;
public bool PlayState { get; set; }
public bool IsLoop { get; set; }
public int Length { get; set; }
//public bool StoreMemory => true;//经过测试,储存到内存好处多多,不储存也要占用很多内存,干脆存了吧
public bool IsContinue { get; set; }
public GraphCore.GraphType GraphType { get; set; }
public void Run(Border parant, Action EndAction = null)
{
PlayState = true;
StopEndAction = false;
if (parant.Tag != this)
{
System.Windows.Controls.Image img;
if (parant.Child == GraphCore.CommUIElements["Image1.Picture"])
{
img = (System.Windows.Controls.Image)GraphCore.CommUIElements["Image1.Picture"];
}
else
{
img = (System.Windows.Controls.Image)GraphCore.CommUIElements["Image2.Picture"];
if (parant.Child != GraphCore.CommUIElements["Image2.Picture"])
{
if (img.Parent == null)
{
parant.Child = img;
}
else
{
img = (System.Windows.Controls.Image)GraphCore.CommUIElements["Image3.Picture"];
parant.Child = img;
}
}
}
var bitmap = new BitmapImage();
bitmap.BeginInit();
stream.Seek(0, SeekOrigin.Begin);
bitmap.StreamSource = stream;
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.EndInit();
img.Source = bitmap;
parant.Tag = this;
}
Task.Run(() =>
{
Thread.Sleep(Length);
if (IsLoop && PlayState)
{
Run(parant, EndAction);
}
else
{
PlayState = false;
if (!StopEndAction)
EndAction?.Invoke();//运行结束动画时事件
}
});
}
bool StopEndAction = false;
public void Stop(bool StopEndAction = false)
{
PlayState = false;
this.StopEndAction = StopEndAction;
}
public void WaitForReadyRun(Border parant, Action EndAction = null) => Run(parant, EndAction);
}
}

View File

@ -1,6 +0,0 @@
<Image x:Class="VPet_Simulator.Core.Picture" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:VPet_Simulator.Core" mc:Ignorable="d" Height="500" Width="500">
</Image>

View File

@ -1,78 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace VPet_Simulator.Core
{
/// <summary>
/// Picture.xaml 的交互逻辑
/// </summary>
public partial class Picture : Image, IGraph
{
/// <summary>
/// 新建新静态图像
/// </summary>
/// <param name="path">图片路径</param>
public Picture(string path, Save.ModeType modetype, GraphCore.GraphType graphType, int length = 1000, bool isloop = false)
{
InitializeComponent();
ModeType = modetype;
IsLoop = isloop;
Length = length;
Source = new BitmapImage(new Uri(path));
GraphType = graphType;
}
public Save.ModeType ModeType { get; private set; }
public bool PlayState { get; set; }
public bool IsLoop { get; set; }
public int Length { get; set; }
//public bool StoreMemory => true;//经过测试,储存到内存好处多多,不储存也要占用很多内存,干脆存了吧
public UIElement This => this;
public bool IsContinue { get; set; }
public GraphCore.GraphType GraphType { get; set; }
public void Run(Action EndAction = null)
{
PlayState = true;
StopEndAction = false;
Task.Run(() =>
{
Thread.Sleep(Length);
if (IsLoop && PlayState)
{
Run(EndAction);
}
else
{
PlayState = false;
if (!StopEndAction)
EndAction?.Invoke();//运行结束动画时事件
}
});
}
bool StopEndAction = false;
public void Stop(bool StopEndAction = false)
{
PlayState = false;
this.StopEndAction = StopEndAction;
}
public void WaitForReadyRun(Action EndAction = null) => Run(EndAction);
}
}

View File

@ -127,14 +127,6 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Graph\Picture.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Graph\PNGAnimation.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Compile Include="Display\MainDisplay.cs" />
@ -153,12 +145,8 @@
<DependentUpon>EyeTracking.xaml</DependentUpon>
</Compile>
<Compile Include="Graph\IGraph.cs" />
<Compile Include="Graph\Picture.xaml.cs">
<DependentUpon>Picture.xaml</DependentUpon>
</Compile>
<Compile Include="Graph\PNGAnimation.xaml.cs">
<DependentUpon>PNGAnimation.xaml</DependentUpon>
</Compile>
<Compile Include="Graph\Picture.cs" />
<Compile Include="Graph\PNGAnimation.cs" />
<Compile Include="Handle\Function.cs" />
<Compile Include="Handle\GameCore.cs" />
<Compile Include="Handle\IController.cs" />