diff --git a/Wpf_AiSportsMicrospace/Dto/WhackAMoleContext.cs b/Wpf_AiSportsMicrospace/Dto/WhackAMoleContext.cs index 4f105e9..78f0911 100644 --- a/Wpf_AiSportsMicrospace/Dto/WhackAMoleContext.cs +++ b/Wpf_AiSportsMicrospace/Dto/WhackAMoleContext.cs @@ -18,7 +18,7 @@ namespace Dto public List UserList { get; private set; } public List UserNumberList { get; private set; } public List Sports { get; private set; } - public List UseNameList { get; private set; } = new() + public List UserNameList { get; private set; } = new() { "游客-A", "游客-B", "游客-C", "游客-D", "游客-E", "游客-F", "游客-G", "游客-H", "游客-I", "游客-F", "游客-J" }; @@ -47,7 +47,7 @@ namespace Dto .Select((numStr, index) => new { Index = index, - Name = UseNameList[index], + Name = UserNameList[index], Number = int.TryParse(numStr, out var n) ? n : 0 }) .OrderByDescending(x => x.Number) diff --git a/Wpf_AiSportsMicrospace/MyUserControl/WhackAMoleUserControl.xaml.cs b/Wpf_AiSportsMicrospace/MyUserControl/WhackAMoleUserControl.xaml.cs index 2384c36..a7db814 100644 --- a/Wpf_AiSportsMicrospace/MyUserControl/WhackAMoleUserControl.xaml.cs +++ b/Wpf_AiSportsMicrospace/MyUserControl/WhackAMoleUserControl.xaml.cs @@ -98,7 +98,7 @@ namespace Wpf_AiSportsMicrospace.MyUserControl /// 外部上下文,用于更新用户分数列表 /// 注意:需要根据实际项目调整这个引用方式 /// - private dynamic _groupJumpRopeContext; + private WhackAMoleContext _whackAMoleContext; #endregion @@ -153,8 +153,6 @@ namespace Wpf_AiSportsMicrospace.MyUserControl #region 私有方法 - - /// /// 初始化计时器 /// @@ -173,6 +171,8 @@ namespace Wpf_AiSportsMicrospace.MyUserControl _hitDetectionTimer = new DispatcherTimer(); _hitDetectionTimer.Interval = TimeSpan.FromMilliseconds(50); _hitDetectionTimer.Tick += HitDetectionTimer_Tick; + + _whackAMoleContext = new WhackAMoleContext(); } /// @@ -191,10 +191,10 @@ namespace Wpf_AiSportsMicrospace.MyUserControl var parent = this.Parent as FrameworkElement; while (parent != null) { - var contextProperty = parent.GetType().GetProperty("_groupJumpRopeContext"); + var contextProperty = parent.GetType().GetProperty("_whackAMoleContext"); if (contextProperty != null) { - _groupJumpRopeContext = contextProperty.GetValue(parent); + _whackAMoleContext = (WhackAMoleContext)contextProperty.GetValue(parent); break; } parent = parent.Parent as FrameworkElement; @@ -227,7 +227,7 @@ namespace Wpf_AiSportsMicrospace.MyUserControl /// private void TryGetContext() { - if (_groupJumpRopeContext == null) + if (_whackAMoleContext == null) { InitializeContext(); } @@ -240,11 +240,11 @@ namespace Wpf_AiSportsMicrospace.MyUserControl { TryGetContext(); - if (_groupJumpRopeContext != null) + if (_whackAMoleContext != null) { try { - var userNumberList = _groupJumpRopeContext.GetType().GetProperty("UserNumberList")?.GetValue(_groupJumpRopeContext) as List; + var userNumberList = _whackAMoleContext.GetType().GetProperty("UserNumberList")?.GetValue(_whackAMoleContext) as List; if (userNumberList != null && Index >= 0 && Index < userNumberList.Count) { userNumberList[Index] = _score; @@ -264,7 +264,7 @@ namespace Wpf_AiSportsMicrospace.MyUserControl { if (!_isInitialized) { InitImageContal(); - name.Text = _groupJumpRopeContext.UserNameList[Index]; + name.Text = _whackAMoleContext.UserNameList[Index]; } // 重置分数 @@ -680,7 +680,7 @@ namespace Wpf_AiSportsMicrospace.MyUserControl /// 外部上下文对象 public void SetContext(dynamic context) { - _groupJumpRopeContext = context; + _whackAMoleContext = context; } #endregion diff --git a/Wpf_AiSportsMicrospace/Views/Home.xaml.cs b/Wpf_AiSportsMicrospace/Views/Home.xaml.cs index 7e03476..39c8f01 100644 --- a/Wpf_AiSportsMicrospace/Views/Home.xaml.cs +++ b/Wpf_AiSportsMicrospace/Views/Home.xaml.cs @@ -175,7 +175,7 @@ namespace Wpf_AiSportsMicrospace else { //var newPage = new TrainingRecords(); - var newPage = new StandingLeap(); + var newPage = new WhackAMole(); mainWin?.SwitchPageWithMaskAnimation(newPage, true); } } diff --git a/Wpf_AiSportsMicrospace/Views/SquatFu/WhackAMole.xaml.cs b/Wpf_AiSportsMicrospace/Views/SquatFu/WhackAMole.xaml.cs index f092a04..94f0e2b 100644 --- a/Wpf_AiSportsMicrospace/Views/SquatFu/WhackAMole.xaml.cs +++ b/Wpf_AiSportsMicrospace/Views/SquatFu/WhackAMole.xaml.cs @@ -43,14 +43,14 @@ namespace Views.SquatFu private GameState _currentGameState = GameState.NotStarted; private readonly object _updateLock = new object(); private readonly Dictionary _jumpStatus = new Dictionary(); - private WhackAMoleContext _groupJumpRopeContext; + private WhackAMoleContext _WhackAMoleContext; public WhackAMole() { InitializeComponent(); Loaded += UserControl_Loaded; Unloaded += UserControl_Unloaded; - _groupJumpRopeContext = new WhackAMoleContext(); + _WhackAMoleContext = new WhackAMoleContext(); } private async void UserControl_Loaded(object sender, RoutedEventArgs e) @@ -62,13 +62,20 @@ namespace Views.SquatFu using var scope = App.AppHost.Services.CreateScope(); var db = scope.ServiceProvider.GetRequiredService(); var cfg = await db.GroupPoints.FirstOrDefaultAsync(x => x.Code == AppSettings.Code); - //var pointlist = JsonSerializer.Deserialize>(cfg!.PointsJson); + List<(double XNorm, double YNorm)> pointlist = new List<(double XNorm, double YNorm)>(); - List<(double XNorm, double YNorm)> pointlist = - [(cfg.Point1.X, cfg.Point1.Y),(cfg.Point2.X, cfg.Point2.Y), - (cfg.Point3.X, cfg.Point3.Y), (cfg.Point4.X, cfg.Point4.Y), - (cfg.Point5.X, cfg.Point5.Y),(cfg.Point6.X, cfg.Point6.Y)]; - _groupJumpRopeContext.CirclePositions = pointlist; + var points = new[] { cfg.Point1, cfg.Point2, cfg.Point3, + cfg.Point4, cfg.Point5, cfg.Point6, + cfg.Point7, cfg.Point8, cfg.Point9, cfg.Point10 }; + + foreach (var point in points) + { + if (point != null) + { + pointlist.Add((point.X, point.Y)); + } + } + _WhackAMoleContext.CirclePositions = pointlist; DrawCirclesWithText(); @@ -282,7 +289,7 @@ namespace Views.SquatFu { countdownText.Text = "GO!"; countdownGrid.Visibility = Visibility.Hidden; - _groupJumpRopeContext.UserList.ForEach(x => + _WhackAMoleContext.UserList.ForEach(x => { x.Start(); }); @@ -305,7 +312,7 @@ namespace Views.SquatFu countdownGrid.Visibility = Visibility.Hidden; - _groupJumpRopeContext.UserList.ForEach(x => + _WhackAMoleContext.UserList.ForEach(x => { Tiggle += 1; x.TriggerValue = Tiggle; @@ -314,7 +321,7 @@ namespace Views.SquatFu _mainWin.HumanFrameUpdated -= OnHumanFrameUpdated; _mainWin.WebcamClient.StopExtract(); - RankingItemList = _groupJumpRopeContext.UpdateWhackAMoleRankList(); + RankingItemList = _WhackAMoleContext.UpdateWhackAMoleRankList(); ShowRankingBoard(RankingItemList); Utils.StopBackgroundMusic(); @@ -340,14 +347,14 @@ namespace Views.SquatFu private void DrawCirclesWithText() { userBox.Children.Clear(); - _groupJumpRopeContext.Sports.Clear(); - _groupJumpRopeContext.UserList.Clear(); - _groupJumpRopeContext.UserNumberList.Clear(); + _WhackAMoleContext.Sports.Clear(); + _WhackAMoleContext.UserList.Clear(); + _WhackAMoleContext.UserNumberList.Clear(); - for (int i = 0; i < _groupJumpRopeContext.CirclePositions.Count; i++) + for (int i = 0; i < _WhackAMoleContext.CirclePositions.Count; i++) { - var pos = _groupJumpRopeContext.CirclePositions[i]; + var pos = _WhackAMoleContext.CirclePositions[i]; double x = pos.XNorm ; double y = pos.YNorm ; @@ -370,85 +377,49 @@ namespace Views.SquatFu // 更新UI //userItem.NumberText = count.ToString(); // 更新数字源 - _groupJumpRopeContext.UserNumberList[indexCopy] = count.ToString(); + _WhackAMoleContext.UserNumberList[indexCopy] = count.ToString(); // 改变状态为“跳绳中” if (userItem.TriggerValue != 2) userItem.TriggerValue = 2; }; sport.Start(); - _groupJumpRopeContext.Sports.Add(sport); + _WhackAMoleContext.Sports.Add(sport); } } + + private void UpdateCircleCounts(List humans) { - // 放宽一点的圈半径(归一化) - double radiusNormX = 0.10; - double radiusNormY = 0.14; + double halfW = AppSettings.AreaSize.X; + double halfH = AppSettings.AreaSize.Y; - for (int i = 0; i < _groupJumpRopeContext.CirclePositions.Count; i++) + int circleCount = _WhackAMoleContext.CirclePositions.Count; + + for (int i = 0; i < circleCount; i++) { - var circleX = _groupJumpRopeContext.CirclePositions[i].XNorm; - var circleY = _groupJumpRopeContext.CirclePositions[i].YNorm; + var circle = _WhackAMoleContext.CirclePositions[i]; + double cx = circle.XNorm; + double cy = circle.YNorm; - Human humanInCircle = null; + Human targetHuman = null; - foreach (var hu in humans) + // 1️⃣ 找圈内的人(单脚命中即可) + foreach (var h in humans) { - var rightFoot = hu.Keypoints.FirstOrDefault(k => k.Name == "right_ankle"); - var leftFoot = hu.Keypoints.FirstOrDefault(k => k.Name == "left_ankle"); - - if (rightFoot == null && leftFoot == null) - continue; - - bool rightInCircle = false; - bool leftInCircle = false; - - // 右脚判断 - if (rightFoot != null) + if (sportOperate.IsAnyFootInCircle(h, cx, cy, halfW, halfH)) { - double xRightNorm = rightFoot.X / userBox.ActualWidth; - double yRightNorm = rightFoot.Y / userBox.ActualHeight; - - rightInCircle = - xRightNorm >= (circleX - radiusNormX) && - xRightNorm <= (circleX + radiusNormX) && - yRightNorm >= (circleY - radiusNormY) && - yRightNorm <= (circleY + radiusNormY); - } - - // 左脚判断 - if (leftFoot != null) - { - double xLeftNorm = leftFoot.X / userBox.ActualWidth; - double yLeftNorm = leftFoot.Y / userBox.ActualHeight; - - leftInCircle = - xLeftNorm >= (circleX - radiusNormX) && - xLeftNorm <= (circleX + radiusNormX) && - yLeftNorm >= (circleY - radiusNormY) && - yLeftNorm <= (circleY + radiusNormY); - } - - // ✅ 只要有一只脚在圈内 - if (rightInCircle || leftInCircle) - { - humanInCircle = hu; - break; + targetHuman = h; + break; // 每个圈只认一个人 } } - bool hasHuman = humanInCircle != null; - - //lock (_updateLock) - //{ - // _groupJumpRopeContext.UserList[i].ImageState = - // GetJumpState(i, hasHuman); - //} + bool hasHuman = targetHuman != null; + // 3️⃣ 推送跳绳计数 if (hasHuman) { - _groupJumpRopeContext.Sports[i].Pushing(humanInCircle); + _WhackAMoleContext.Sports[i].Pushing(targetHuman); } } } @@ -466,8 +437,8 @@ namespace Views.SquatFu //userItem.Margin = new Thickness(centerX - (index == 0 ? 80 : index == 6 ? 190 : 135), centerY - 540, 0, 0); userItem.Margin = new Thickness(centerX , centerY - 600 - 50, 0, 0); userBox.Children.Add(userItem); - _groupJumpRopeContext.UserList.Add(userItem); - _groupJumpRopeContext.UserNumberList.Add("0"); + _WhackAMoleContext.UserList.Add(userItem); + _WhackAMoleContext.UserNumberList.Add("0"); return userItem; // }