VPet/VPet-Simulator.Core/Display/Main.xaml.cs
2023-09-24 12:22:08 +08:00

453 lines
17 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using LinePutScript;
using LinePutScript.Localization.WPF;
using Panuon.WPF.UI;
using System;
using System.Linq;
using System.Media;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using static VPet_Simulator.Core.GraphInfo;
namespace VPet_Simulator.Core
{
/// <summary>
/// Main.xaml 的交互逻辑
/// </summary>
public partial class Main : ContentControlX, IDisposable
{
/// <summary>
/// 游戏核心
/// </summary>
public GameCore Core;
/// <summary>
/// 菜单栏
/// </summary>
public ToolBar ToolBar;
/// <summary>
/// 消息栏
/// </summary>
public MessageBar MsgBar;
/// <summary>
/// 工作显示栏
/// </summary>
public WorkTimer WorkTimer;
/// <summary>
/// 刷新时间时会调用该方法
/// </summary>
public event Action<Main> TimeHandle;
/// <summary>
/// 刷新时间时会调用该方法,在所有任务处理完之后
/// </summary>
public event Action<Main> TimeUIHandle;
/// <summary>
/// 如果不开启功能模式,默认状态设置
/// </summary>
public GameSave.ModeType NoFunctionMOD = GameSave.ModeType.Happy;
/// <summary>
/// 是否开始运行
/// </summary>
public bool IsWorking { get; private set; } = false;
public SoundPlayer soundPlayer = new SoundPlayer();
public bool windowMediaPlayerAvailable = true;
public Main(GameCore core, bool loadtouchevent = true)
{
//Console.WriteLine(DateTime.Now.ToString("T:fff"));
InitializeComponent();
Core = core;
WorkTimer = new WorkTimer(this);
WorkTimer.Visibility = Visibility.Collapsed;
UIGrid.Children.Add(WorkTimer);
ToolBar = new ToolBar(this);
ToolBar.Visibility = Visibility.Collapsed;
UIGrid.Children.Add(ToolBar);
MsgBar = new MessageBar(this);
MsgBar.Visibility = Visibility.Collapsed;
UIGrid.Children.Add(MsgBar);
labeldisplaytimer.Elapsed += Labledisplaytimer_Elapsed;
if (loadtouchevent)
{
LoadTouchEvent();
}
if (!core.Controller.EnableFunction)
Core.Save.Mode = NoFunctionMOD;
var ig = Core.Graph.FindGraph(Core.Graph.FindName(GraphType.StartUP), AnimatType.Single, core.Save.Mode);
ig ??= Core.Graph.FindGraph(Core.Graph.FindName(GraphType.StartUP), AnimatType.Single, GameSave.ModeType.PoorCondition);
//var ig2 = Core.Graph.FindGraph(GraphType.Default, core.GameSave.Mode);
PetGrid2.Visibility = Visibility.Collapsed;
Task.Run(() =>
{
//while (!ig.IsReady)
//{
// Thread.Sleep(100);
//}//新功能:等待所有图像加载完成再跑
foreach(var igs in Core.Graph.GraphsList.Values)
{
foreach(var ig2 in igs.Values)
{
foreach(var ig3 in ig2)
{
while (!ig3.IsReady)
{
Thread.Sleep(100);
}
}
}
}
ig.Run(PetGrid, () =>
{
IsWorking = true;
Dispatcher.Invoke(() =>
{
PetGrid.Tag = ig;
PetGrid2.Tag = ig;
});
DisplayNomal();
});
});
EventTimer.Elapsed += (s, e) => EventTimer_Elapsed();
MoveTimer.Elapsed += MoveTimer_Elapsed;
SmartMoveTimer.Elapsed += SmartMoveTimer_Elapsed;
}
private void Labledisplaytimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
if (--labeldisplaycount <= 0)
{
labeldisplaytimer.Enabled = false;
labeldisplaychangenum1 = 0;
labeldisplaychangenum2 = 0;
Dispatcher.Invoke(() =>
{
LabelDisplay.Visibility = Visibility.Collapsed;
});
}
else if (labeldisplaycount < 50)
{
Dispatcher.Invoke(() =>
{
LabelDisplay.Opacity = labeldisplaycount / 50;
});
}
}
/// <summary>
/// 自动加载触摸事件
/// </summary>
public void LoadTouchEvent()
{
Core.TouchEvent.Add(new TouchArea(Core.Graph.GraphConfig.TouchHeadLocate, Core.Graph.GraphConfig.TouchHeadSize, () => { DisplayTouchHead(); return true; }));
for (int i = 0; i < 4; i++)
{
GameSave.ModeType m = (GameSave.ModeType)i;
Core.TouchEvent.Add(new TouchArea(Core.Graph.GraphConfig.TouchRaisedLocate[i], Core.Graph.GraphConfig.TouchRaisedSize[i],
() =>
{
if (Core.Save.Mode == m)
{
DisplayRaised();
return true;
}
else
return false;
}, true));
}
}
/// <summary>
/// 播放语音 语音播放时不会停止播放说话表情
/// </summary>
/// <param name="VoicePath">语音位置</param>
public void PlayVoice(Uri VoicePath)//, TimeSpan timediff = TimeSpan.Zero) TODO
{
PlayingVoice = true;
if (windowMediaPlayerAvailable)
{
Dispatcher.Invoke(() =>
{
VoicePlayer.Clock = new MediaTimeline(VoicePath).CreateClock();
VoicePlayer.Clock.Completed += Clock_Completed;
VoicePlayer.MediaFailed += MediaPlayer_MediaFailed;
VoicePlayer.Play();
//Task.Run(() =>
//{
// Thread.Sleep(1000);
// Dispatcher.Invoke(() =>
// {
// if (VoicePlayer?.Clock?.NaturalDuration.HasTimeSpan == true)
// PlayEndTime += VoicePlayer.Clock.NaturalDuration.TimeSpan - TimeSpan.FromSeconds(0.8);
// });
//});
});
}
else
{
soundPlayer.SoundLocation = VoicePath.LocalPath;
soundPlayer.LoadAsync();
}
}
/// <summary>
/// 声音音量
/// </summary>
public double PlayVoiceVolume
{
get => Dispatcher.Invoke(() => VoicePlayer.Volume);
set => Dispatcher.Invoke(() => VoicePlayer.Volume = value);
}
/// <summary>
/// 当前是否正在播放
/// </summary>
public bool PlayingVoice = false;
private void MediaPlayer_MediaFailed(object sender, ExceptionRoutedEventArgs e)
{
windowMediaPlayerAvailable = false;
PlayingVoice = false;
MessageBoxX.Show("音频播放失败已尝试自动切换到备用播放器。如果问题持续请检查是否已安装WindowsMediaPlayer。\nAudio playback failed, attempted automatic switch to backup player. If the issue persists, please check if Windows Media Player is installed.", "音频错误 audio error", Panuon.WPF.UI.MessageBoxIcon.Warning);
}
private void Clock_Completed(object sender, EventArgs e)
{
PlayingVoice = false;
VoicePlayer.Clock = null;
}
public bool MoveTimerSmartMove = false;
private void SmartMoveTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
MoveTimerSmartMove = false;
}
private void MoveTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
if (DisplayType.Type != GraphType.Move || !MoveTimerSmartMove)
{
return;
}
Core.Controller.MoveWindows(MoveTimerPoint.X, MoveTimerPoint.Y);
//if (Core.Controller.GetWindowsDistanceLeft() < -500)
//{
// MessageBox.Show("当前动画移动设计错误: 已到达边界 左侧\n动画名称: {0}\n距离: {1}".Translate(DisplayType.Name, Core.Controller.GetWindowsDistanceLeft()), "MOD移动设计错误".Translate());
//}
//else if (Core.Controller.GetWindowsDistanceRight() < -500)
//{
// MessageBox.Show("当前动画移动设计错误: 已到达边界 右侧\n动画名称: {0}\n距离: {1}".Translate(DisplayType.Name, Core.Controller.GetWindowsDistanceRight()), "MOD移动设计错误".Translate());
//}
//else if (Core.Controller.GetWindowsDistanceUp() < -500)
//{
// MessageBox.Show("当前动画移动设计错误: 已到达边界 上侧\n动画名称: {0}\n距离: {1}".Translate(DisplayType.Name, Core.Controller.GetWindowsDistanceUp()), "MOD移动设计错误".Translate());
//}
//else if (Core.Controller.GetWindowsDistanceDown() < -500)
//{
// MessageBox.Show("当前动画移动设计错误: 已到达边界 下侧\n动画名称: {0}\n距离: {1}".Translate(DisplayType.Name, Core.Controller.GetWindowsDistanceDown()), "MOD移动设计错误".Translate());
//}
MoveTimer.Start();
}
/// <summary>
/// 默认点击事件
/// </summary>
public Action DefaultClickAction;
/// <summary>
/// 默认长按事件
/// </summary>
public Action DefaultPressAction;
bool isPress = false;
long presstime;
private void MainGrid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
isPress = true;
CountNomal = 0;
Task.Run(() =>
{
var pth = DateTime.Now.Ticks;
presstime = pth;
Thread.Sleep(Core.Controller.PressLength);
Point mp = default;
Dispatcher.BeginInvoke(new Action(() => mp = Mouse.GetPosition(MainGrid))).Wait();
//mp = new Point(mp.X * Core.Controller.ZoomRatio, mp.Y * Core.Controller.ZoomRatio);
if (isPress && presstime == pth)
{//历遍长按事件
LastInteractionTime = DateTime.Now;
foreach (var x in Core.TouchEvent)
{
if (x.IsPress == true && x.Touch(mp) && x.DoAction())
return;
}
DefaultPressAction?.Invoke();
}
else
{//历遍点击事件
LastInteractionTime = DateTime.Now;
foreach (var x in Core.TouchEvent)
{
if (x.IsPress == false && x.Touch(mp) && x.DoAction())
return;
}
//普通点击验证
if (DisplayType.Type != GraphType.Default)
{//不是nomal! 可能会卡timer,所有全部timer清空下
CleanState();
if (!IsIdel && DisplayStop(DisplayToNomal))
return;
}
DefaultClickAction?.Invoke();
}
});
}
private void MainGrid_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
isPress = false;
if (DisplayType.Type.ToString().StartsWith("Raised"))
{
MainGrid.MouseMove -= MainGrid_MouseMove;
MainGrid.MouseMove += MainGrid_MouseWave;
rasetype = -1;
DisplayRaising();
}
else
{
//if (MsgBar.Visibility == Visibility.Visible)
//{
// MsgBar.ForceClose();
//}
if (SmartMove)
{
MoveTimerSmartMove = true;
SmartMoveTimer.Enabled = false;
SmartMoveTimer.Start();
}
}
((UIElement)e.Source).ReleaseMouseCapture();
}
private void MainGrid_MouseMove(object sender, MouseEventArgs e)
{
if (!((UIElement)e.Source).CaptureMouse() || !isPress)
{
MainGrid.MouseMove -= MainGrid_MouseMove;
MainGrid.MouseMove += MainGrid_MouseWave;
rasetype = -1;
DisplayRaising();
return;
}
var mp = e.GetPosition(MainGrid);
var x = mp.X - Core.Graph.GraphConfig.RaisePoint[(int)Core.Save.Mode].X;
var y = mp.Y - Core.Graph.GraphConfig.RaisePoint[(int)Core.Save.Mode].Y;
Core.Controller.MoveWindows(x, y);
if (Math.Abs(x) + Math.Abs(y) > 20 && rasetype >= 1)
rasetype = 0;
}
private void MainGrid_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
if (ToolBar.Visibility == Visibility.Visible)
{
ToolBar.CloseTimer.Enabled = false;
ToolBar.Visibility = Visibility.Collapsed;
}
else
ToolBar.Show();
}
public void Dispose()
{
EventTimer.Stop();
MoveTimer.Enabled = false;
EventTimer.Dispose();
MoveTimer.Dispose();
MsgBar.Dispose();
ToolBar.Dispose();
if (PetGrid.Child is IGraph g)
g.Stop(true);
if (PetGrid2.Child is IGraph g2)
g2.Stop(true);
}
/// <summary>
/// 清理所有状态
/// </summary>
public void CleanState()
{
MoveTimer.Enabled = false;
MainGrid.MouseMove -= MainGrid_MouseMove;
MainGrid.MouseMove += MainGrid_MouseWave;
}
private int wavetimes = 0;
private int switchcount = 0;
private bool? waveleft = null;
private bool? wavetop = null;
private DateTime wavespan;
private void MainGrid_MouseWave(object sender, MouseEventArgs e)
{
if (rasetype >= 0 || State != WorkingState.Nomal)
return;
if ((DateTime.Now - wavespan).TotalSeconds > 2)
{
wavetimes = 0;
switchcount = 0;
waveleft = null;
wavetop = null;
}
wavespan = DateTime.Now;
bool active = false;
var p = e.GetPosition(MainGrid);
if (p.Y < 200)
{
if (wavetop != false)
wavetop = true;
else
{
if (switchcount++ > 150)
wavespan = DateTime.MinValue;
return;
}
}
else
{
if (wavetop != true)
wavetop = false;
else
{
if (switchcount++ > 150)
wavespan = DateTime.MinValue;
return;
}
}
if (p.X < 200 && waveleft != true)
{
waveleft = true;
active = true;
}
if (p.X > 300 && waveleft != false)
{
active = true;
waveleft = false;
}
if (active)
{
if (wavetimes++ > 4)
if (wavetop == true)
{
if (wavetimes >= 10 || IsIdel || DisplayType.Type == GraphType.Touch_Head)
DisplayTouchHead();
//Console.WriteLine(wavetimes);
LastInteractionTime = DateTime.Now;
}
else
{
if (wavetimes >= 10 || IsIdel || DisplayType.Type == GraphType.Touch_Body)
DisplayTouchBody();
LastInteractionTime = DateTime.Now;
}
}
}
}
}