update:jump page

This commit is contained in:
ltx 2025-10-12 20:20:47 +08:00
parent 5134b1ff3e
commit ab7435f3ef
4 changed files with 115 additions and 56 deletions

View File

@ -9,7 +9,7 @@ namespace Wpf_AiSportsMicrospace.MyUserControl
{ {
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{ {
if (value is int state && parameter is string param && int.TryParse(param, out int target)) if (value is string state && parameter is string target)
{ {
return state == target ? Visibility.Visible : Visibility.Collapsed; return state == target ? Visibility.Visible : Visibility.Collapsed;
} }

View File

@ -6,13 +6,13 @@
xmlns:local="clr-namespace:Wpf_AiSportsMicrospace.MyUserControl" xmlns:local="clr-namespace:Wpf_AiSportsMicrospace.MyUserControl"
xmlns:system="clr-namespace:System;assembly=mscorlib" xmlns:system="clr-namespace:System;assembly=mscorlib"
xmlns:gif="http://wpfanimatedgif.codeplex.com" xmlns:gif="http://wpfanimatedgif.codeplex.com"
Width="270" Height="560"> Width="270" Height="530">
<UserControl.Resources> <UserControl.Resources>
<local:ImageStateToVisibilityConverter x:Key="ImageStateToVisibilityConverter"/> <local:ImageStateToVisibilityConverter x:Key="ImageStateToVisibilityConverter"/>
</UserControl.Resources> </UserControl.Resources>
<Grid> <Grid>
<Border Background="#60000000" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/> <!--<Border Background="#60000000" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>-->
<Image Source="/Resources/Img/test_img/one_rope/top_bg.png" Width="224" <Image Source="/Resources/Img/test_img/one_rope/top_bg.png" Width="224"
HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,0,0,0"/> HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,0,0,0"/>
<TextBlock Text="{Binding DisplayText, RelativeSource={RelativeSource AncestorType=UserControl}}" <TextBlock Text="{Binding DisplayText, RelativeSource={RelativeSource AncestorType=UserControl}}"
@ -42,7 +42,7 @@
gif:ImageBehavior.RepeatBehavior="Forever" gif:ImageBehavior.RepeatBehavior="Forever"
HorizontalAlignment="Center" HorizontalAlignment="Center"
VerticalAlignment="Top" VerticalAlignment="Top"
Width="270" Width="370"
Margin="0,131,0,0" Margin="0,131,0,0"
Visibility="{Binding ImageState, RelativeSource={RelativeSource AncestorType=UserControl}, Converter={StaticResource ImageStateToVisibilityConverter}, ConverterParameter=2}" /> Visibility="{Binding ImageState, RelativeSource={RelativeSource AncestorType=UserControl}, Converter={StaticResource ImageStateToVisibilityConverter}, ConverterParameter=2}" />
</Grid> </Grid>

View File

@ -9,7 +9,7 @@
<Grid.Background> <Grid.Background>
<ImageBrush ImageSource="/Resources/Img/test_img/test_home_bg.png" Stretch="UniformToFill"/> <ImageBrush ImageSource="/Resources/Img/test_img/test_home_bg.png" Stretch="UniformToFill"/>
</Grid.Background> </Grid.Background>
<Grid> <Grid Height="1080" Width="1920" x:Name="userBox">
<Image <Image
Source="/Resources/Img/test_img/one_rope/title.png" Source="/Resources/Img/test_img/one_rope/title.png"
HorizontalAlignment="Center" HorizontalAlignment="Center"
@ -17,20 +17,23 @@
Width="615" Width="615"
Margin="0,0,0,0" Margin="0,0,0,0"
/> />
<local:SportUserItem DisplayText="一号位" NumberText="100000" ImageState="1" /> <!--<local:SportUserItem DisplayText="一号位" NumberText="100000" ImageState="0" Margin="0,0,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" />-->
<!-- title --> <!-- title -->
<Canvas x:Name="overlayCanvas" IsHitTestVisible="False" Height="1080" Width="1920" Margin="0,10,0,-10"/> <Canvas x:Name="overlayCanvas" IsHitTestVisible="False" Height="1080" Width="1920" Margin="0,10,0,-10" />
<Grid Width="220" Height="130" VerticalAlignment="Top" Margin="0,150,0,0" Visibility="Collapsed" x:Name="countdownGrid">
<TextBlock x:Name="countdownText" <Border Background="#005fff" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" CornerRadius="30" />
Text="3" <TextBlock x:Name="countdownText"
FontSize="120" Text="35"
FontWeight="Bold" FontSize="120"
Foreground="Red" FontWeight="Bold"
HorizontalAlignment="Center" Foreground="#fff"
VerticalAlignment="Top" FontStyle="Italic"
Margin="0,50,0,0" HorizontalAlignment="Center"
TextAlignment="Center" VerticalAlignment="Center"
Visibility="Collapsed"/> Margin="0,10,0,0"
TextAlignment="Center"
/>
</Grid>
</Grid> </Grid>
</Grid> </Grid>
</UserControl> </UserControl>

View File

@ -15,12 +15,14 @@ using System.Windows.Data;
using System.Windows.Documents; using System.Windows.Documents;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
using System.Windows.Shapes; using System.Windows.Shapes;
using System.Windows.Threading; using System.Windows.Threading;
using Wpf_AiSportsMicrospace.Common; using Wpf_AiSportsMicrospace.Common;
using Wpf_AiSportsMicrospace.Dto; using Wpf_AiSportsMicrospace.Dto;
using Wpf_AiSportsMicrospace.Enum; using Wpf_AiSportsMicrospace.Enum;
using Wpf_AiSportsMicrospace.MyUserControl;
using Wpf_AiSportsMicrospace.Service; using Wpf_AiSportsMicrospace.Service;
using WpfAnimatedGif; using WpfAnimatedGif;
using Yztob.AiSports.Common; using Yztob.AiSports.Common;
@ -40,6 +42,7 @@ namespace Wpf_AiSportsMicrospace.Views
{ {
private List<SportBase> sports = new(); private List<SportBase> sports = new();
private List<TextBlock> circleTexts = new(); private List<TextBlock> circleTexts = new();
private List<SportUserItem> userList = new();
private double[] circlePositionsX = { 0.07, 0.21, 0.36, 0.50, 0.64, 0.78, 0.92 }; private double[] circlePositionsX = { 0.07, 0.21, 0.36, 0.50, 0.64, 0.78, 0.92 };
private Main _mainWin => Application.Current.MainWindow as Main; private Main _mainWin => Application.Current.MainWindow as Main;
private List<(double XNorm, double YNorm)> circlePositions = new(); private List<(double XNorm, double YNorm)> circlePositions = new();
@ -70,6 +73,7 @@ namespace Wpf_AiSportsMicrospace.Views
// 获取项目根目录 // 获取项目根目录
string projectRoot = System.IO.Path.Combine(AppContext.BaseDirectory, @"..\..\.."); string projectRoot = System.IO.Path.Combine(AppContext.BaseDirectory, @"..\..\..");
string musicPath = System.IO.Path.Combine(projectRoot, "Resources", "Music", musicFileName); string musicPath = System.IO.Path.Combine(projectRoot, "Resources", "Music", musicFileName);
string imgPath = System.IO.Path.Combine(projectRoot, "Resources", "Img", "提示图.png");
if (!File.Exists(musicPath)) if (!File.Exists(musicPath))
{ {
@ -79,11 +83,64 @@ namespace Wpf_AiSportsMicrospace.Views
_mediaPlayer.Open(new Uri(musicPath, UriKind.Absolute)); _mediaPlayer.Open(new Uri(musicPath, UriKind.Absolute));
ShowCenterTip(imgPath, TimeSpan.FromSeconds(3));
// 监听播放完成事件 // 监听播放完成事件
_mediaPlayer.MediaEnded += MediaPlayer_MediaEnded; _mediaPlayer.MediaEnded += MediaPlayer_MediaEnded;
_mediaPlayer.Play(); _mediaPlayer.Play();
} }
private void ShowCenterTip(string imagePath, TimeSpan duration)
{
var tipImage = new Image
{
Source = new BitmapImage(new Uri(imagePath, UriKind.Absolute)),
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
Opacity = 0
};
// 增加图片的大小,调整比例
tipImage.Width = overlayCanvas.ActualWidth * 0.9; // 宽度为 Canvas 宽度的 90%
tipImage.Height = overlayCanvas.ActualHeight * 0.6; // 高度为 Canvas 高度的 60%
// 将图片添加到 Overlay Canvas
overlayCanvas.Children.Add(tipImage);
Canvas.SetLeft(tipImage, (overlayCanvas.ActualWidth - tipImage.Width) / 2); // 居中
Canvas.SetTop(tipImage, (overlayCanvas.ActualHeight - tipImage.Height) / 2); // 居中
// 渐变出现动画
var fadeInAnimation = new DoubleAnimation
{
From = 0,
To = 1,
Duration = TimeSpan.FromSeconds(1.5)
};
tipImage.BeginAnimation(UIElement.OpacityProperty, fadeInAnimation);
// 定时移除,并且渐变消失
Task.Delay(duration).ContinueWith(_ =>
{
Dispatcher.Invoke(() =>
{
// 渐变消失动画
var fadeOutAnimation = new DoubleAnimation
{
From = 1,
To = 0,
Duration = TimeSpan.FromSeconds(1.5)
};
tipImage.BeginAnimation(UIElement.OpacityProperty, fadeOutAnimation);
// 完成后移除图片
fadeOutAnimation.Completed += (s, e) =>
{
overlayCanvas.Children.Remove(tipImage);
};
});
});
}
private void MediaPlayer_MediaEnded(object sender, EventArgs e) private void MediaPlayer_MediaEnded(object sender, EventArgs e)
{ {
@ -128,6 +185,7 @@ namespace Wpf_AiSportsMicrospace.Views
Utils.StopBackgroundMusic(); Utils.StopBackgroundMusic();
countdownText.Text = "3"; countdownText.Text = "3";
countdownText.Visibility = Visibility.Collapsed; countdownText.Visibility = Visibility.Collapsed;
countdownGrid.Visibility = Visibility.Collapsed;
break; break;
} }
} }
@ -149,6 +207,7 @@ namespace Wpf_AiSportsMicrospace.Views
_currentCountdown = start; _currentCountdown = start;
countdownText.Text = _currentCountdown.ToString(); countdownText.Text = _currentCountdown.ToString();
countdownText.Visibility = Visibility.Visible; countdownText.Visibility = Visibility.Visible;
countdownGrid.Visibility = Visibility.Visible;
_lastUpdateTime = DateTime.Now; _lastUpdateTime = DateTime.Now;
Utils.PlayBackgroundMusic("countdown_3.mp3", false); Utils.PlayBackgroundMusic("countdown_3.mp3", false);
@ -174,9 +233,14 @@ namespace Wpf_AiSportsMicrospace.Views
private async void FinishCountdown() private async void FinishCountdown()
{ {
foreach (var item in userList)
{
item.ImageState = "2";
}
// 举手完成,显示 ✔ // 举手完成,显示 ✔
countdownText.Text = "✔"; countdownText.Text = "GO!";
countdownText.Visibility = Visibility.Collapsed; countdownText.Visibility = Visibility.Collapsed;
countdownGrid.Visibility = Visibility.Collapsed;
IsGameStarted = true; IsGameStarted = true;
// 播放背景音乐(循环) // 播放背景音乐(循环)
Utils.PlayBackgroundMusic("homeprojectselected1.mp3", true); Utils.PlayBackgroundMusic("homeprojectselected1.mp3", true);
@ -187,6 +251,7 @@ namespace Wpf_AiSportsMicrospace.Views
private async void StartGameCountdown(int seconds) private async void StartGameCountdown(int seconds)
{ {
countdownText.Visibility = Visibility.Visible; countdownText.Visibility = Visibility.Visible;
countdownGrid.Visibility = Visibility.Visible;
for (int i = seconds; i >= 0; i--) for (int i = seconds; i >= 0; i--)
{ {
@ -195,9 +260,15 @@ namespace Wpf_AiSportsMicrospace.Views
} }
countdownText.Visibility = Visibility.Collapsed; countdownText.Visibility = Visibility.Collapsed;
countdownGrid.Visibility = Visibility.Collapsed;
IsGameStarted = false; IsGameStarted = false;
// 倒计时完成后可以触发其他逻辑,例如停止音乐 // 倒计时完成后可以触发其他逻辑,例如停止音乐
foreach (var item in userList)
{
item.ImageState = "1";
}
Utils.StopBackgroundMusic(); Utils.StopBackgroundMusic();
} }
@ -314,6 +385,7 @@ namespace Wpf_AiSportsMicrospace.Views
Application.Current.Dispatcher.BeginInvoke(() => Application.Current.Dispatcher.BeginInvoke(() =>
{ {
circleTexts[circleIndex].Text = "您已出圈!"; circleTexts[circleIndex].Text = "您已出圈!";
userList[circleIndex].ImageState = "3";
}); });
continue; continue;
} }
@ -350,15 +422,16 @@ namespace Wpf_AiSportsMicrospace.Views
(0.92, 0.58 ) (0.92, 0.58 )
}; };
foreach (var pos in circlePositions) for (int i = 0; i < circlePositions.Count; i++)
{ {
var pos = circlePositions[i];
double x = pos.XNorm * imgWidth; double x = pos.XNorm * imgWidth;
double y = pos.YNorm * imgHeight; double y = pos.YNorm * imgHeight;
// 绘制发光圆 // 绘制发光圆
//AddGlowEllipse(x, y, overlayCanvas); //AddGlowEllipse(x, y, overlayCanvas);
AddGlowEllipse(x, y, overlayCanvas); AddUserItem(x, y, i);
// 创建文本控件 // 创建文本控件
@ -376,7 +449,7 @@ namespace Wpf_AiSportsMicrospace.Views
Canvas.SetTop(text, y - radius - 25); Canvas.SetTop(text, y - radius - 25);
overlayCanvas.Children.Add(text); overlayCanvas.Children.Add(text);
circleTexts.Add(text); circleTexts.Add(text);
// 绑定运动对象 // 绑定运动对象
var sport = SportBase.Create("rope-skipping"); var sport = SportBase.Create("rope-skipping");
int index = circleTexts.Count - 1; int index = circleTexts.Count - 1;
@ -385,6 +458,7 @@ namespace Wpf_AiSportsMicrospace.Views
Application.Current.Dispatcher.BeginInvoke(() => Application.Current.Dispatcher.BeginInvoke(() =>
{ {
circleTexts[index].Text = count.ToString(); circleTexts[index].Text = count.ToString();
userList[index].NumberText = count.ToString();
}); });
}; };
sport.Start(); sport.Start();
@ -410,43 +484,25 @@ namespace Wpf_AiSportsMicrospace.Views
/// <summary> /// <summary>
/// 添加带渐变光的圆圈(中心红色,边缘蓝色) /// 添加带渐变光的圆圈(中心红色,边缘蓝色)
/// </summary> /// </summary>
private Ellipse AddGlowEllipse(double centerX, double centerY, Canvas canvas) private SportUserItem AddUserItem(double centerX, double centerY, int index)
{ {
double radius = 70; // 统一半径 List<String> trueName = ["一号位", "二号位", "三号位", "四号位", "五号位", "六号位", "七号位", ];
double flattenFactor = 0.5; // 扁平化比例 List<String> useName = ["四号位", "一号位", "五号位", "二号位", "六号位", "三号位", "七号位", ];
double opacity = 0.8; // 透明度 var userItem = new SportUserItem();
userItem.Width = 270;
// 默认颜色 userItem.Height = 560;
Color cColor = Color.FromArgb(220, 255, 255, 0); // 黄 userItem.DisplayText = useName[index];
Color eColor = Color.FromArgb(180, 0, 0, 255); // 蓝 userItem.VerticalAlignment = VerticalAlignment.Top;
userItem.HorizontalAlignment = HorizontalAlignment.Left;
var ellipse = new Ellipse if(index == 3)
{ {
Width = radius * 2, userItem.ImageState = "1";
Height = radius * flattenFactor,
Opacity = opacity,
Fill = new RadialGradientBrush
{
GradientOrigin = new Point(0.5, 0.5),
Center = new Point(0.5, 0.5),
RadiusX = 0.5,
RadiusY = 0.5,
GradientStops = new GradientStopCollection
{
new GradientStop(cColor, 0.0), // 中心颜色
new GradientStop(cColor, 0.4), // 内部颜色
new GradientStop(eColor, 0.7), // 边缘颜色
new GradientStop(Color.FromArgb(0, eColor.R, eColor.G, eColor.B), 1.0) // 外部透明
} }
} //设置位置---------------------------------
}; userItem.Margin = new Thickness(centerX - 135, centerY - 540, 0, 0);
userBox.Children.Add(userItem);
// 定位到中心 userList.Add(userItem);
Canvas.SetLeft(ellipse, centerX - radius); return userItem; //
Canvas.SetTop(ellipse, centerY - (radius * flattenFactor) / 2);
canvas.Children.Add(ellipse);
return ellipse; // 返回 Ellipse 对象方便后续修改或移除
} }