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