Compare commits

...

4 Commits

Author SHA1 Message Date
ltx
64bdaa3e05 Merge branch 'dev' of http://8.153.108.90:3000/YD/Wpf_AiSportsMicrospace into dev 2025-10-12 20:21:09 +08:00
ltx
ab7435f3ef update:jump page 2025-10-12 20:20:47 +08:00
ltx
5134b1ff3e Merge branch 'dev' of http://8.153.108.90:3000/YD/Wpf_AiSportsMicrospace into dev
# Conflicts:
#	Wpf_AiSportsMicrospace/Views/JumpRope/GroupJumpRope.xaml
2025-10-12 18:44:33 +08:00
ltx
941956ea35 update:字体&样式 2025-10-12 18:30:11 +08:00
18 changed files with 296 additions and 58 deletions

View File

@ -6,7 +6,10 @@
<!--StartupUri="Views/JumpRope/GroupJumpRope.xaml">-->
<Application.Resources>
<FontFamily x:Key="AppFont">./Resoures/Fonts/myFontFamily</FontFamily>
<Style TargetType="TextBlock">
<Setter Property="FontFamily" Value="./Resoures/Fonts/myFontFamily"/>
</Style>
</Application.Resources>
</Application>

View File

@ -0,0 +1,24 @@
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
namespace Wpf_AiSportsMicrospace.MyUserControl
{
public class ImageStateToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is string state && parameter is string target)
{
return state == target ? Visibility.Visible : Visibility.Collapsed;
}
return Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,49 @@
<UserControl x:Class="Wpf_AiSportsMicrospace.MyUserControl.SportUserItem"
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:Wpf_AiSportsMicrospace.MyUserControl"
xmlns:system="clr-namespace:System;assembly=mscorlib"
xmlns:gif="http://wpfanimatedgif.codeplex.com"
Width="270" Height="530">
<UserControl.Resources>
<local:ImageStateToVisibilityConverter x:Key="ImageStateToVisibilityConverter"/>
</UserControl.Resources>
<Grid>
<!--<Border Background="#60000000" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>-->
<Image Source="/Resources/Img/test_img/one_rope/top_bg.png" Width="224"
HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,0,0,0"/>
<TextBlock Text="{Binding DisplayText, RelativeSource={RelativeSource AncestorType=UserControl}}"
FontSize="26"
Foreground="#fff"
FontWeight="Bold"
FontStyle="Italic"
Margin="-17,4,0,0"
HorizontalAlignment="Center"
VerticalAlignment="Top"/>
<TextBlock Text="{Binding NumberText, RelativeSource={RelativeSource AncestorType=UserControl}}"
FontSize="36"
Foreground="#000"
FontWeight="Bold"
FontStyle="Italic"
Margin="0,45,0,0"
HorizontalAlignment="Center"
VerticalAlignment="Top"/>
<Image Source="/Resources/Img/test_img/one_rope/out_user.png" Width="250" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,131,0,0"
Visibility="{Binding ImageState, RelativeSource={RelativeSource AncestorType=UserControl}, Converter={StaticResource ImageStateToVisibilityConverter}, ConverterParameter=3}" />
<Image Source="/Resources/Img/test_img/one_rope/pre_user.png" Width="270" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,131,0,0"
Visibility="{Binding ImageState, RelativeSource={RelativeSource AncestorType=UserControl}, Converter={StaticResource ImageStateToVisibilityConverter}, ConverterParameter=1}" />
<Image Source="/Resources/Img/test_img/one_rope/nopeople.png" Width="270" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,131,0,0"
Visibility="{Binding ImageState, RelativeSource={RelativeSource AncestorType=UserControl}, Converter={StaticResource ImageStateToVisibilityConverter}, ConverterParameter=0}" />
<Image gif:ImageBehavior.AnimatedSource="/Resources/Img/test_img/one_rope/jump_rope.gif"
gif:ImageBehavior.RepeatBehavior="Forever"
HorizontalAlignment="Center"
VerticalAlignment="Top"
Width="370"
Margin="0,131,0,0"
Visibility="{Binding ImageState, RelativeSource={RelativeSource AncestorType=UserControl}, Converter={StaticResource ImageStateToVisibilityConverter}, ConverterParameter=2}" />
</Grid>
</UserControl>

View File

@ -0,0 +1,62 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
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.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
namespace Wpf_AiSportsMicrospace.MyUserControl
{
/// <summary>
/// CoverFlowControl.xaml 的交互逻辑
/// </summary>
/// ST
public partial class SportUserItem : UserControl
{
public SportUserItem()
{
InitializeComponent();
}
public string DisplayText
{
get => (string)GetValue(DisplayTextProperty);
set => SetValue(DisplayTextProperty, value);
}
public static readonly DependencyProperty DisplayTextProperty =
DependencyProperty.Register(nameof(DisplayText), typeof(string), typeof(SportUserItem), new PropertyMetadata("??"));
public string NumberText
{
get => (string)GetValue(NumberTextProperty);
set => SetValue(DisplayTextProperty, value);
}
public static readonly DependencyProperty NumberTextProperty =
DependencyProperty.Register(nameof(NumberText), typeof(string), typeof(SportUserItem), new PropertyMetadata("??"));
public string ImageState
//0 没有人 1 准备中 2 运动中 3 出圈了
{
get => (string)GetValue(ImageStateProperty);
set => SetValue(ImageStateProperty, value);
}
public static readonly DependencyProperty ImageStateProperty =
DependencyProperty.Register(nameof(ImageState), typeof(string), typeof(SportUserItem), new PropertyMetadata("0"));
}
}

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 991 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 690 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 358 KiB

After

Width:  |  Height:  |  Size: 690 KiB

View File

@ -3,25 +3,37 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Wpf_AiSportsMicrospace.Views"
xmlns:local="clr-namespace:Wpf_AiSportsMicrospace.MyUserControl"
mc:Ignorable="d" Height="1080" Width="1920" Loaded="UserControl_Loaded" Unloaded="UserControl_Unloaded">
<Grid >
<Grid.Background>
<ImageBrush ImageSource="/Resources/Img/Album/home_bg.png" Stretch="UniformToFill"/>
<Grid.Background>
<ImageBrush ImageSource="/Resources/Img/test_img/test_home_bg.png" Stretch="UniformToFill"/>
</Grid.Background>
<Grid>
<Canvas x:Name="overlayCanvas" IsHitTestVisible="False" Height="1080" Width="1920"/>
<TextBlock x:Name="countdownText"
Text="3"
FontSize="120"
FontWeight="Bold"
Foreground="Red"
<Grid Height="1080" Width="1920" x:Name="userBox">
<Image
Source="/Resources/Img/test_img/one_rope/title.png"
HorizontalAlignment="Center"
VerticalAlignment="Top"
Margin="0,50,0,0"
TextAlignment="Center"
Visibility="Collapsed"/>
Width="615"
Margin="0,0,0,0"
/>
<!--<local:SportUserItem DisplayText="一号位" NumberText="100000" ImageState="0" Margin="0,0,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" />-->
<!-- title -->
<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">
<Border Background="#005fff" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" CornerRadius="30" />
<TextBlock x:Name="countdownText"
Text="35"
FontSize="120"
FontWeight="Bold"
Foreground="#fff"
FontStyle="Italic"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="0,10,0,0"
TextAlignment="Center"
/>
</Grid>
</Grid>
</Grid>
</UserControl>

View File

@ -22,6 +22,7 @@ using System.Windows.Threading;
using Wpf_AiSportsMicrospace.Common;
using Wpf_AiSportsMicrospace.Dto;
using Wpf_AiSportsMicrospace.Enum;
using Wpf_AiSportsMicrospace.MyUserControl;
using Wpf_AiSportsMicrospace.Service;
using WpfAnimatedGif;
using Yztob.AiSports.Common;
@ -41,6 +42,7 @@ namespace Wpf_AiSportsMicrospace.Views
{
private List<SportBase> sports = 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 Main _mainWin => Application.Current.MainWindow as Main;
private List<(double XNorm, double YNorm)> circlePositions = new();
@ -138,6 +140,57 @@ namespace Wpf_AiSportsMicrospace.Views
_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)
{
@ -181,6 +234,7 @@ namespace Wpf_AiSportsMicrospace.Views
Utils.StopBackgroundMusic();
countdownText.Text = "3";
countdownText.Visibility = Visibility.Collapsed;
countdownGrid.Visibility = Visibility.Collapsed;
break;
}
}
@ -202,6 +256,7 @@ namespace Wpf_AiSportsMicrospace.Views
_currentCountdown = start;
countdownText.Text = _currentCountdown.ToString();
countdownText.Visibility = Visibility.Visible;
countdownGrid.Visibility = Visibility.Visible;
_lastUpdateTime = DateTime.Now;
Utils.PlayBackgroundMusic("countdown_3.mp3", false);
@ -227,9 +282,14 @@ namespace Wpf_AiSportsMicrospace.Views
private async void FinishCountdown()
{
foreach (var item in userList)
{
item.ImageState = "2";
}
// 举手完成,显示 ✔
countdownText.Text = "✔";
countdownText.Text = "GO!";
countdownText.Visibility = Visibility.Collapsed;
countdownGrid.Visibility = Visibility.Collapsed;
IsGameStarted = true;
// 播放背景音乐(循环)
Utils.PlayBackgroundMusic("homeprojectselected1.mp3", true);
@ -240,6 +300,7 @@ namespace Wpf_AiSportsMicrospace.Views
private async void StartGameCountdown(int seconds)
{
countdownText.Visibility = Visibility.Visible;
countdownGrid.Visibility = Visibility.Visible;
for (int i = seconds; i >= 0; i--)
{
@ -248,9 +309,15 @@ namespace Wpf_AiSportsMicrospace.Views
}
countdownText.Visibility = Visibility.Collapsed;
countdownGrid.Visibility = Visibility.Collapsed;
IsGameStarted = false;
// 倒计时完成后可以触发其他逻辑,例如停止音乐
foreach (var item in userList)
{
item.ImageState = "1";
}
Utils.StopBackgroundMusic();
}
@ -367,6 +434,7 @@ namespace Wpf_AiSportsMicrospace.Views
Application.Current.Dispatcher.BeginInvoke(() =>
{
circleTexts[circleIndex].Text = "您已出圈!";
userList[circleIndex].ImageState = "3";
});
continue;
}
@ -403,15 +471,16 @@ namespace Wpf_AiSportsMicrospace.Views
(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 y = pos.YNorm * imgHeight;
// 绘制发光圆
//AddGlowEllipse(x, y, overlayCanvas);
AddGlowEllipse(x, y, overlayCanvas);
AddUserItem(x, y, i);
// 创建文本控件
@ -429,7 +498,7 @@ namespace Wpf_AiSportsMicrospace.Views
Canvas.SetTop(text, y - radius - 25);
overlayCanvas.Children.Add(text);
circleTexts.Add(text);
// 绑定运动对象
var sport = SportBase.Create("rope-skipping");
int index = circleTexts.Count - 1;
@ -438,6 +507,7 @@ namespace Wpf_AiSportsMicrospace.Views
Application.Current.Dispatcher.BeginInvoke(() =>
{
circleTexts[index].Text = count.ToString();
userList[index].NumberText = count.ToString();
});
};
sport.Start();
@ -463,43 +533,25 @@ namespace Wpf_AiSportsMicrospace.Views
/// <summary>
/// 添加带渐变光的圆圈(中心红色,边缘蓝色)
/// </summary>
private Ellipse AddGlowEllipse(double centerX, double centerY, Canvas canvas)
private SportUserItem AddUserItem(double centerX, double centerY, int index)
{
double radius = 70; // 统一半径
double flattenFactor = 0.5; // 扁平化比例
double opacity = 0.8; // 透明度
// 默认颜色
Color cColor = Color.FromArgb(220, 255, 255, 0); // 黄
Color eColor = Color.FromArgb(180, 0, 0, 255); // 蓝
var ellipse = new Ellipse
List<String> trueName = ["一号位", "二号位", "三号位", "四号位", "五号位", "六号位", "七号位", ];
List<String> useName = ["四号位", "一号位", "五号位", "二号位", "六号位", "三号位", "七号位", ];
var userItem = new SportUserItem();
userItem.Width = 270;
userItem.Height = 560;
userItem.DisplayText = useName[index];
userItem.VerticalAlignment = VerticalAlignment.Top;
userItem.HorizontalAlignment = HorizontalAlignment.Left;
if(index == 3)
{
Width = radius * 2,
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.ImageState = "1";
}
}
};
// 定位到中心
Canvas.SetLeft(ellipse, centerX - radius);
Canvas.SetTop(ellipse, centerY - (radius * flattenFactor) / 2);
canvas.Children.Add(ellipse);
return ellipse; // 返回 Ellipse 对象方便后续修改或移除
//设置位置---------------------------------
userItem.Margin = new Thickness(centerX - 135, centerY - 540, 0, 0);
userBox.Children.Add(userItem);
userList.Add(userItem);
return userItem; //
}

View File

@ -36,11 +36,11 @@ namespace Wpf_AiSportsMicrospace.Views
{
InitializeComponent();
var options = new InferenceOptions()
{
GpuEnabled = true
};
Yztob.AiSports.Common.SportAppSettingService.Set("inferences", options);
//var options = new InferenceOptions()
//{
// GpuEnabled = true
//};
//Yztob.AiSports.Common.SportAppSettingService.Set("inferences", options);
_humanPredictor = HumanPredictorFactory.Create(HumanPredictorType.MultiLow);
_humanGraphicsRenderer = new HumanGraphicsRenderer();

View File

@ -9,6 +9,7 @@
</PropertyGroup>
<ItemGroup>
<None Remove="Resources\Font\myFontFamily.ttf" />
<None Remove="Resources\Img\Album\1.gif" />
<None Remove="Resources\Img\Album\1.jpg" />
<None Remove="Resources\Img\Album\2.gif" />
@ -43,6 +44,14 @@
<None Remove="Resources\Img\play_img\play_jump.png" />
<None Remove="Resources\Img\play_img\play_music.png" />
<None Remove="Resources\Img\play_img\play_vs.png" />
<None Remove="Resources\Img\test_img\one_rope\jump_rope.gif" />
<None Remove="Resources\Img\test_img\one_rope\nopeople.png" />
<None Remove="Resources\Img\test_img\one_rope\out_user.png" />
<None Remove="Resources\Img\test_img\one_rope\pre_people.png" />
<None Remove="Resources\Img\test_img\one_rope\pre_user.png" />
<None Remove="Resources\Img\test_img\one_rope\test_home_bg.png" />
<None Remove="Resources\Img\test_img\one_rope\title.png" />
<None Remove="Resources\Img\test_img\one_rope\top_bg.png" />
<None Remove="Resources\Img\test_img\test_home_bg.png" />
<None Remove="Resources\Img\test_img\test_home_title.png" />
<None Remove="Resources\Img\test_img\test_jump.png" />
@ -106,6 +115,9 @@
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Font\myFontFamily.ttf">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Resources\Img\Album\1.gif">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
@ -199,6 +211,30 @@
<Resource Include="Resources\Img\play_img\play_vs.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Resources\Img\test_img\one_rope\jump_rope.gif">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Resources\Img\test_img\one_rope\nopeople.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Resources\Img\test_img\one_rope\out_user.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Resources\Img\test_img\one_rope\pre_people.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Resources\Img\test_img\one_rope\pre_user.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Resources\Img\test_img\one_rope\test_home_bg.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Resources\Img\test_img\one_rope\title.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Resources\Img\test_img\one_rope\top_bg.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Resources\Img\test_img\test_home_bg.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>