mirror of
https://github.com/LorisYounger/VPet.ModMaker.git
synced 2024-08-30 18:22:21 +00:00
#更新
- 宠物动画延迟加载, 大幅提高启动性能
This commit is contained in:
parent
a3c15260b8
commit
7a2fa5c261
@ -2,6 +2,7 @@
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using HKW.HKWUtils.Extensions;
|
||||
using HKW.HKWUtils.Observable;
|
||||
using VPet_Simulator.Core;
|
||||
|
||||
@ -22,10 +23,9 @@ public class AnimeModel : ObservableObjectX, ICloneable<AnimeModel>
|
||||
var info = Path.GetFileNameWithoutExtension(file).Split(NativeUtils.Separator);
|
||||
ID = info[0];
|
||||
var duration = info.Last();
|
||||
var imageModel = new ImageModel(
|
||||
NativeUtils.LoadImageToMemoryStream(file),
|
||||
int.Parse(duration)
|
||||
);
|
||||
if (int.TryParse(duration, out var result) is false)
|
||||
result = 100;
|
||||
var imageModel = new ImageModel(file, result);
|
||||
Images.Add(imageModel);
|
||||
}
|
||||
}
|
||||
@ -63,6 +63,14 @@ public class AnimeModel : ObservableObjectX, ICloneable<AnimeModel>
|
||||
/// </summary>
|
||||
public ObservableList<ImageModel> Images { get; } = new();
|
||||
|
||||
public void LoadAnime()
|
||||
{
|
||||
if (Images.HasValue() is false || Images.First().Image is not null)
|
||||
return;
|
||||
foreach (var image in Images)
|
||||
image.LoadImage();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 复制
|
||||
/// </summary>
|
||||
|
@ -180,6 +180,18 @@ public class AnimeTypeModel : ObservableObjectX
|
||||
}
|
||||
}
|
||||
|
||||
public void LoadTypeAnime()
|
||||
{
|
||||
foreach (var anime in HappyAnimes)
|
||||
anime.LoadAnime();
|
||||
foreach (var anime in NomalAnimes)
|
||||
anime.LoadAnime();
|
||||
foreach (var anime in PoorConditionAnimes)
|
||||
anime.LoadAnime();
|
||||
foreach (var anime in IllAnimes)
|
||||
anime.LoadAnime();
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
foreach (var anime in HappyAnimes)
|
||||
@ -194,6 +206,7 @@ public class AnimeTypeModel : ObservableObjectX
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
Close();
|
||||
HappyAnimes.Clear();
|
||||
NomalAnimes.Clear();
|
||||
PoorConditionAnimes.Clear();
|
||||
@ -435,14 +448,14 @@ public class AnimeTypeModel : ObservableObjectX
|
||||
or GraphInfo.GraphType.Shutdown
|
||||
or GraphInfo.GraphType.StartUP
|
||||
)
|
||||
SaveDefault(path, this);
|
||||
SaveDefault(path);
|
||||
else if (
|
||||
GraphType
|
||||
is GraphInfo.GraphType.Touch_Head
|
||||
or GraphInfo.GraphType.Touch_Body
|
||||
or GraphInfo.GraphType.Sleep
|
||||
)
|
||||
SaveMultiType(path, this);
|
||||
SaveMultiType(path);
|
||||
else if (
|
||||
GraphType
|
||||
is GraphInfo.GraphType.Switch_Up
|
||||
@ -450,55 +463,52 @@ public class AnimeTypeModel : ObservableObjectX
|
||||
or GraphInfo.GraphType.Switch_Thirsty
|
||||
or GraphInfo.GraphType.Switch_Hunger
|
||||
)
|
||||
SaveSwitch(path, this);
|
||||
SaveSwitch(path);
|
||||
else if (
|
||||
GraphType is GraphInfo.GraphType.Raised_Dynamic or GraphInfo.GraphType.Raised_Static
|
||||
)
|
||||
SaveRaised(path, this);
|
||||
SaveRaised(path);
|
||||
else if (GraphType is GraphInfo.GraphType.StateONE or GraphInfo.GraphType.StateTWO)
|
||||
SaveState(path, this);
|
||||
SaveState(path);
|
||||
else if (GraphType is GraphInfo.GraphType.Common)
|
||||
SaveCommon(path, this);
|
||||
SaveCommon(path);
|
||||
else if (GraphType.IsHasNameAnime())
|
||||
SaveHasNameAnime(path, this);
|
||||
SaveHasNameAnime(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存为带有名称的动画样式
|
||||
/// </summary>
|
||||
/// <param name="path">路径</param>
|
||||
/// <param name="animeTypeModel">动画模型</param>
|
||||
void SaveHasNameAnime(string path, AnimeTypeModel animeTypeModel)
|
||||
void SaveHasNameAnime(string path)
|
||||
{
|
||||
var animeTypePath = Path.Combine(path, animeTypeModel.GraphType.ToString());
|
||||
var animeTypePath = Path.Combine(path, GraphType.ToString());
|
||||
Directory.CreateDirectory(animeTypePath);
|
||||
var animePath = Path.Combine(animeTypePath, animeTypeModel.Name);
|
||||
var animePath = Path.Combine(animeTypePath, Name);
|
||||
Directory.CreateDirectory(animePath);
|
||||
SaveWithModeType(animePath, animeTypeModel);
|
||||
SaveWithModeType(animePath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存为通用样式
|
||||
/// </summary>
|
||||
/// <param name="path">路径</param>
|
||||
/// <param name="animeTypeModel">模型</param>
|
||||
void SaveCommon(string path, AnimeTypeModel animeTypeModel)
|
||||
void SaveCommon(string path)
|
||||
{
|
||||
var animePath = Path.Combine(path, animeTypeModel.Name);
|
||||
var animePath = Path.Combine(path, Name);
|
||||
Directory.CreateDirectory(animePath);
|
||||
SaveWithModeType(animePath, animeTypeModel);
|
||||
SaveWithModeType(animePath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存为 <see cref="GraphInfo.GraphType.StateONE"/> 或 <see cref="GraphInfo.GraphType.StateTWO"/> 样式
|
||||
/// </summary>
|
||||
/// <param name="path">路径</param>
|
||||
/// <param name="animeTypeModel">模型</param>
|
||||
void SaveState(string path, AnimeTypeModel animeTypeModel)
|
||||
void SaveState(string path)
|
||||
{
|
||||
var animePath = Path.Combine(path, "State");
|
||||
Directory.CreateDirectory(animePath);
|
||||
SaveMultiType(animePath, animeTypeModel);
|
||||
SaveMultiType(animePath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -506,14 +516,14 @@ public class AnimeTypeModel : ObservableObjectX
|
||||
/// </summary>
|
||||
/// <param name="path">路径</param>
|
||||
/// <param name="animeTypeModel">模型</param>
|
||||
void SaveRaised(string path, AnimeTypeModel animeTypeModel)
|
||||
void SaveRaised(string path)
|
||||
{
|
||||
var animePath = Path.Combine(path, "Raise");
|
||||
Directory.CreateDirectory(animePath);
|
||||
if (animeTypeModel.GraphType is GraphInfo.GraphType.Raised_Dynamic)
|
||||
SaveDefault(animePath, animeTypeModel);
|
||||
else if (animeTypeModel.GraphType is GraphInfo.GraphType.Raised_Static)
|
||||
SaveMultiType(animePath, animeTypeModel);
|
||||
if (GraphType is GraphInfo.GraphType.Raised_Dynamic)
|
||||
SaveDefault(animePath);
|
||||
else if (GraphType is GraphInfo.GraphType.Raised_Static)
|
||||
SaveMultiType(animePath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -521,12 +531,12 @@ public class AnimeTypeModel : ObservableObjectX
|
||||
/// </summary>
|
||||
/// <param name="path">路径</param>
|
||||
/// <param name="animeTypeModel">模型</param>
|
||||
void SaveSwitch(string path, AnimeTypeModel animeTypeModel)
|
||||
void SaveSwitch(string path)
|
||||
{
|
||||
var animePath = Path.Combine(path, "Switch");
|
||||
Directory.CreateDirectory(animePath);
|
||||
var switchName = animeTypeModel.GraphType.ToString().Split(NativeUtils.Separator).Last();
|
||||
SaveWithAnimeType(Path.Combine(animePath, switchName), animeTypeModel);
|
||||
var switchName = GraphType.ToString().Split(NativeUtils.Separator).Last();
|
||||
SaveWithAnimeType(Path.Combine(animePath, switchName));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -534,11 +544,11 @@ public class AnimeTypeModel : ObservableObjectX
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="animeTypeModel"></param>
|
||||
static void SaveDefault(string path, AnimeTypeModel animeTypeModel)
|
||||
void SaveDefault(string path)
|
||||
{
|
||||
var animePath = Path.Combine(path, animeTypeModel.GraphType.ToString());
|
||||
var animePath = Path.Combine(path, GraphType.ToString());
|
||||
Directory.CreateDirectory(animePath);
|
||||
SaveWithAnimeType(animePath, animeTypeModel);
|
||||
SaveWithAnimeType(animePath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -546,11 +556,11 @@ public class AnimeTypeModel : ObservableObjectX
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="animeTypeModel"></param>
|
||||
static void SaveMultiType(string path, AnimeTypeModel animeTypeModel)
|
||||
void SaveMultiType(string path)
|
||||
{
|
||||
var animePath = Path.Combine(path, animeTypeModel.GraphType.ToString());
|
||||
var animePath = Path.Combine(path, GraphType.ToString());
|
||||
Directory.CreateDirectory(animePath);
|
||||
SaveWithModeType(animePath, animeTypeModel);
|
||||
SaveWithModeType(animePath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -558,27 +568,27 @@ public class AnimeTypeModel : ObservableObjectX
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="animeTypeModel"></param>
|
||||
static void SaveWithModeType(string path, AnimeTypeModel animeTypeModel)
|
||||
void SaveWithModeType(string path)
|
||||
{
|
||||
if (animeTypeModel.HappyAnimes.Count > 0)
|
||||
if (HappyAnimes.Count > 0)
|
||||
{
|
||||
var modePath = Path.Combine(path, nameof(ModeType.Happy));
|
||||
SaveAnimes(modePath, animeTypeModel.HappyAnimes);
|
||||
SaveAnimes(modePath, HappyAnimes);
|
||||
}
|
||||
if (animeTypeModel.NomalAnimes.Count > 0)
|
||||
if (NomalAnimes.Count > 0)
|
||||
{
|
||||
var modePath = Path.Combine(path, nameof(ModeType.Nomal));
|
||||
SaveAnimes(modePath, animeTypeModel.NomalAnimes);
|
||||
SaveAnimes(modePath, NomalAnimes);
|
||||
}
|
||||
if (animeTypeModel.PoorConditionAnimes.Count > 0)
|
||||
if (PoorConditionAnimes.Count > 0)
|
||||
{
|
||||
var modePath = Path.Combine(path, nameof(ModeType.PoorCondition));
|
||||
SaveAnimes(modePath, animeTypeModel.PoorConditionAnimes);
|
||||
SaveAnimes(modePath, PoorConditionAnimes);
|
||||
}
|
||||
if (animeTypeModel.IllAnimes.Count > 0)
|
||||
if (IllAnimes.Count > 0)
|
||||
{
|
||||
var modePath = Path.Combine(path, nameof(ModeType.Ill));
|
||||
SaveAnimes(modePath, animeTypeModel.IllAnimes);
|
||||
SaveAnimes(modePath, IllAnimes);
|
||||
}
|
||||
|
||||
static void SaveAnimes(string animePath, ObservableList<AnimeModel> animes)
|
||||
@ -619,27 +629,27 @@ public class AnimeTypeModel : ObservableObjectX
|
||||
/// </summary>
|
||||
/// <param name="animePath"></param>
|
||||
/// <param name="animeType"></param>
|
||||
static void SaveWithAnimeType(string animePath, AnimeTypeModel animeType)
|
||||
void SaveWithAnimeType(string animePath)
|
||||
{
|
||||
if (animeType.HappyAnimes.Count > 0)
|
||||
if (HappyAnimes.Count > 0)
|
||||
{
|
||||
var modePath = Path.Combine(animePath, nameof(ModeType.Happy));
|
||||
SaveAnimes(modePath, animeType.HappyAnimes);
|
||||
SaveAnimes(modePath, HappyAnimes);
|
||||
}
|
||||
if (animeType.NomalAnimes.Count > 0)
|
||||
if (NomalAnimes.Count > 0)
|
||||
{
|
||||
var modePath = Path.Combine(animePath, nameof(ModeType.Nomal));
|
||||
SaveAnimes(modePath, animeType.NomalAnimes);
|
||||
SaveAnimes(modePath, NomalAnimes);
|
||||
}
|
||||
if (animeType.PoorConditionAnimes.Count > 0)
|
||||
if (PoorConditionAnimes.Count > 0)
|
||||
{
|
||||
var modePath = Path.Combine(animePath, nameof(ModeType.PoorCondition));
|
||||
SaveAnimes(modePath, animeType.PoorConditionAnimes);
|
||||
SaveAnimes(modePath, PoorConditionAnimes);
|
||||
}
|
||||
if (animeType.IllAnimes.Count > 0)
|
||||
if (IllAnimes.Count > 0)
|
||||
{
|
||||
var modePath = Path.Combine(animePath, nameof(ModeType.Ill));
|
||||
SaveAnimes(modePath, animeType.IllAnimes);
|
||||
SaveAnimes(modePath, IllAnimes);
|
||||
}
|
||||
static void SaveAnimes(string animePath, ObservableList<AnimeModel> animes)
|
||||
{
|
||||
@ -659,9 +669,15 @@ public class AnimeTypeModel : ObservableObjectX
|
||||
Directory.CreateDirectory(imagesPath);
|
||||
foreach ((var index, var image) in model.Images.EnumerateIndex())
|
||||
{
|
||||
image.Image.SaveToPng(
|
||||
Path.Combine(imagesPath, $"{model.ID}_{index:000}_{image.Duration}.png")
|
||||
);
|
||||
var path = Path.Combine(imagesPath, $"{model.ID}_{index:000}_{image.Duration}.png");
|
||||
if (image.Image is not null)
|
||||
{
|
||||
image.Image.SaveToPng(path);
|
||||
}
|
||||
else if (Path.Exists(image.ImageFile))
|
||||
{
|
||||
File.Copy(image.ImageFile, path, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
@ -6,6 +6,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using HKW.HKWUtils.Extensions;
|
||||
using HKW.HKWUtils.Observable;
|
||||
using LinePutScript;
|
||||
using VPet_Simulator.Core;
|
||||
@ -22,7 +23,6 @@ public class FoodAnimeModel : ObservableObjectX, ICloneable<FoodAnimeModel>
|
||||
{
|
||||
foreach (var item in line.Where(i => i.Name.StartsWith('a')))
|
||||
{
|
||||
//var index = int.Parse(item.Name.Substring(1));
|
||||
var infos = item.Info.Split(',');
|
||||
var foodLocationInfo = new FoodAnimeLocationModel();
|
||||
foodLocationInfo.Duration = int.Parse(infos[0]);
|
||||
@ -71,6 +71,20 @@ public class FoodAnimeModel : ObservableObjectX, ICloneable<FoodAnimeModel>
|
||||
/// </summary>
|
||||
public ObservableList<FoodAnimeLocationModel> FoodLocations { get; } = new();
|
||||
|
||||
public void LoadAnime()
|
||||
{
|
||||
if (BackImages.FirstOrDefault()?.Image is null)
|
||||
{
|
||||
foreach (var image in BackImages)
|
||||
image.LoadImage();
|
||||
}
|
||||
if (FrontImages.FirstOrDefault()?.Image is null)
|
||||
{
|
||||
foreach (var image in FrontImages)
|
||||
image.LoadImage();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 复制
|
||||
/// </summary>
|
||||
|
@ -43,7 +43,7 @@ public class FoodAnimeTypeModel : ObservableObjectX
|
||||
|
||||
#region ID
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _id;
|
||||
private string _id = string.Empty;
|
||||
|
||||
public string ID
|
||||
{
|
||||
@ -54,7 +54,7 @@ public class FoodAnimeTypeModel : ObservableObjectX
|
||||
|
||||
#region Name
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private string _name;
|
||||
private string _name = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 名称
|
||||
@ -91,6 +91,18 @@ public class FoodAnimeTypeModel : ObservableObjectX
|
||||
/// </summary>
|
||||
public ObservableList<FoodAnimeModel> IllAnimes { get; } = new();
|
||||
|
||||
public void LoadTypeAnime()
|
||||
{
|
||||
foreach (var anime in HappyAnimes)
|
||||
anime.LoadAnime();
|
||||
foreach (var anime in NomalAnimes)
|
||||
anime.LoadAnime();
|
||||
foreach (var anime in PoorConditionAnimes)
|
||||
anime.LoadAnime();
|
||||
foreach (var anime in IllAnimes)
|
||||
anime.LoadAnime();
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
foreach (var anime in HappyAnimes)
|
||||
@ -255,9 +267,9 @@ public class FoodAnimeTypeModel : ObservableObjectX
|
||||
return new(
|
||||
Directory
|
||||
.EnumerateFiles(Path.Combine(path, pngAnimeInfo.Path))
|
||||
.Select(i => new ImageModel(
|
||||
NativeUtils.LoadImageToMemoryStream(i),
|
||||
int.Parse(Path.GetFileNameWithoutExtension(i).Split('_')[2])
|
||||
.Select(f => new ImageModel(
|
||||
f,
|
||||
int.Parse(Path.GetFileNameWithoutExtension(f).Split('_')[2])
|
||||
))
|
||||
);
|
||||
}
|
||||
@ -329,17 +341,29 @@ public class FoodAnimeTypeModel : ObservableObjectX
|
||||
var backLayPath = Path.Combine(indexPath, BackLayName);
|
||||
Directory.CreateDirectory(frontLayPath);
|
||||
Directory.CreateDirectory(backLayPath);
|
||||
foreach ((var index, var frontImage) in anime.FrontImages.EnumerateIndex())
|
||||
foreach ((var index, var image) in anime.FrontImages.EnumerateIndex())
|
||||
{
|
||||
frontImage.Image.SaveToPng(
|
||||
Path.Combine(frontLayPath, $"{anime.ID}_{index:000}_{frontImage.Duration}.png")
|
||||
);
|
||||
var path = Path.Combine(frontLayPath, $"{anime.ID}_{index:000}_{image.Duration}.png");
|
||||
if (image.Image is not null)
|
||||
{
|
||||
image.Image.SaveToPng(path);
|
||||
}
|
||||
else if (Path.Exists(image.ImageFile))
|
||||
{
|
||||
File.Copy(image.ImageFile, path, true);
|
||||
}
|
||||
}
|
||||
foreach ((var index, var backImage) in anime.BackImages.EnumerateIndex())
|
||||
foreach ((var index, var image) in anime.BackImages.EnumerateIndex())
|
||||
{
|
||||
backImage.Image.SaveToPng(
|
||||
Path.Combine(backLayPath, $"{anime.ID}_{backImage:000}_{backImage.Duration}.png")
|
||||
);
|
||||
var path = Path.Combine(backLayPath, $"{anime.ID}_{index:000}_{image.Duration}.png");
|
||||
if (image.Image is not null)
|
||||
{
|
||||
image.Image.SaveToPng(path);
|
||||
}
|
||||
else if (Path.Exists(image.ImageFile))
|
||||
{
|
||||
File.Copy(image.ImageFile, path, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -384,16 +408,9 @@ public class FoodAnimeTypeModel : ObservableObjectX
|
||||
}
|
||||
}
|
||||
|
||||
public class PNGAnimeInfo
|
||||
public class PNGAnimeInfo(string name, string path, IGameSave.ModeType mode)
|
||||
{
|
||||
public string Name { get; }
|
||||
public string Path { get; }
|
||||
public ModeType Mode { get; }
|
||||
|
||||
public PNGAnimeInfo(string name, string path, ModeType mode)
|
||||
{
|
||||
Name = name;
|
||||
Path = path;
|
||||
Mode = mode;
|
||||
}
|
||||
public string Name { get; } = name;
|
||||
public string Path { get; } = path;
|
||||
public ModeType Mode { get; } = mode;
|
||||
}
|
||||
|
@ -15,12 +15,23 @@ namespace VPet.ModMaker.Models.ModModel;
|
||||
/// </summary>
|
||||
public class ImageModel : ObservableObjectX, ICloneable<ImageModel>
|
||||
{
|
||||
public ImageModel(string imageFile, int duration = 100)
|
||||
{
|
||||
ImageFile = imageFile;
|
||||
Duration = duration;
|
||||
}
|
||||
|
||||
public ImageModel(BitmapImage image, int duration = 100)
|
||||
{
|
||||
Image = image;
|
||||
Duration = duration;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 图片路径
|
||||
/// </summary>
|
||||
public string ImageFile { get; set; } = string.Empty;
|
||||
|
||||
#region Image
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private BitmapImage _image = null!;
|
||||
@ -48,9 +59,18 @@ public class ImageModel : ObservableObjectX, ICloneable<ImageModel>
|
||||
set => SetProperty(ref _duration, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public void LoadImage()
|
||||
{
|
||||
Image = NativeUtils.LoadImageToMemoryStream(ImageFile);
|
||||
}
|
||||
|
||||
public ImageModel Clone()
|
||||
{
|
||||
var model = new ImageModel(Image.CloneStream(), Duration);
|
||||
var model = new ImageModel(
|
||||
Image?.CloneStream() ?? NativeUtils.LoadImageToMemoryStream(ImageFile),
|
||||
Duration
|
||||
);
|
||||
return model;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user