From ab7435f3efe48baddfb493c5db79dd956b932404 Mon Sep 17 00:00:00 2001 From: ltx <1006158920@qq.com> Date: Sun, 12 Oct 2025 20:20:47 +0800 Subject: [PATCH] =?UTF-8?q?update=EF=BC=9Ajump=20page?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ImageStateToVisibilityConverter.cs | 2 +- .../MyUserControl/SportUserItem.xaml | 6 +- .../Views/JumpRope/GroupJumpRope.xaml | 31 ++-- .../Views/JumpRope/GroupJumpRope.xaml.cs | 132 +++++++++++++----- 4 files changed, 115 insertions(+), 56 deletions(-) diff --git a/Wpf_AiSportsMicrospace/MyUserControl/ImageStateToVisibilityConverter.cs b/Wpf_AiSportsMicrospace/MyUserControl/ImageStateToVisibilityConverter.cs index c24c465..0fc8476 100644 --- a/Wpf_AiSportsMicrospace/MyUserControl/ImageStateToVisibilityConverter.cs +++ b/Wpf_AiSportsMicrospace/MyUserControl/ImageStateToVisibilityConverter.cs @@ -9,7 +9,7 @@ namespace Wpf_AiSportsMicrospace.MyUserControl { 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; } diff --git a/Wpf_AiSportsMicrospace/MyUserControl/SportUserItem.xaml b/Wpf_AiSportsMicrospace/MyUserControl/SportUserItem.xaml index de28d38..42fc688 100644 --- a/Wpf_AiSportsMicrospace/MyUserControl/SportUserItem.xaml +++ b/Wpf_AiSportsMicrospace/MyUserControl/SportUserItem.xaml @@ -6,13 +6,13 @@ xmlns:local="clr-namespace:Wpf_AiSportsMicrospace.MyUserControl" xmlns:system="clr-namespace:System;assembly=mscorlib" xmlns:gif="http://wpfanimatedgif.codeplex.com" - Width="270" Height="560"> + Width="270" Height="530"> - + diff --git a/Wpf_AiSportsMicrospace/Views/JumpRope/GroupJumpRope.xaml b/Wpf_AiSportsMicrospace/Views/JumpRope/GroupJumpRope.xaml index ff59387..c4d854c 100644 --- a/Wpf_AiSportsMicrospace/Views/JumpRope/GroupJumpRope.xaml +++ b/Wpf_AiSportsMicrospace/Views/JumpRope/GroupJumpRope.xaml @@ -9,7 +9,7 @@ - + - + - - - + + + + + diff --git a/Wpf_AiSportsMicrospace/Views/JumpRope/GroupJumpRope.xaml.cs b/Wpf_AiSportsMicrospace/Views/JumpRope/GroupJumpRope.xaml.cs index 81ec7ed..c0adc96 100644 --- a/Wpf_AiSportsMicrospace/Views/JumpRope/GroupJumpRope.xaml.cs +++ b/Wpf_AiSportsMicrospace/Views/JumpRope/GroupJumpRope.xaml.cs @@ -15,12 +15,14 @@ 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.Shapes; 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; @@ -40,6 +42,7 @@ namespace Wpf_AiSportsMicrospace.Views { private List sports = new(); private List circleTexts = new(); + private List 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(); @@ -70,6 +73,7 @@ namespace Wpf_AiSportsMicrospace.Views // 获取项目根目录 string projectRoot = System.IO.Path.Combine(AppContext.BaseDirectory, @"..\..\.."); string musicPath = System.IO.Path.Combine(projectRoot, "Resources", "Music", musicFileName); + string imgPath = System.IO.Path.Combine(projectRoot, "Resources", "Img", "提示图.png"); if (!File.Exists(musicPath)) { @@ -79,11 +83,64 @@ namespace Wpf_AiSportsMicrospace.Views _mediaPlayer.Open(new Uri(musicPath, UriKind.Absolute)); + ShowCenterTip(imgPath, TimeSpan.FromSeconds(3)); + // 监听播放完成事件 _mediaPlayer.MediaEnded += MediaPlayer_MediaEnded; _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) { @@ -128,6 +185,7 @@ namespace Wpf_AiSportsMicrospace.Views Utils.StopBackgroundMusic(); countdownText.Text = "3"; countdownText.Visibility = Visibility.Collapsed; + countdownGrid.Visibility = Visibility.Collapsed; break; } } @@ -149,6 +207,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); @@ -174,9 +233,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); @@ -187,6 +251,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--) { @@ -195,9 +260,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(); } @@ -314,6 +385,7 @@ namespace Wpf_AiSportsMicrospace.Views Application.Current.Dispatcher.BeginInvoke(() => { circleTexts[circleIndex].Text = "您已出圈!"; + userList[circleIndex].ImageState = "3"; }); continue; } @@ -350,15 +422,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); // 创建文本控件 @@ -376,7 +449,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; @@ -385,6 +458,7 @@ namespace Wpf_AiSportsMicrospace.Views Application.Current.Dispatcher.BeginInvoke(() => { circleTexts[index].Text = count.ToString(); + userList[index].NumberText = count.ToString(); }); }; sport.Start(); @@ -410,43 +484,25 @@ namespace Wpf_AiSportsMicrospace.Views /// /// 添加带渐变光的圆圈(中心红色,边缘蓝色) /// - 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 trueName = ["一号位", "二号位", "三号位", "四号位", "五号位", "六号位", "七号位", ]; + List 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; // }