This commit is contained in:
tanglong 2025-10-14 18:44:01 +08:00
parent 8ab511e961
commit 68b5ad8c1e

View File

@ -45,13 +45,15 @@ namespace Wpf_AiSportsMicrospace.Views
private List<TextBlock> circleTexts = new(); private List<TextBlock> circleTexts = new();
private List<SportUserItem> userList = new(); private List<SportUserItem> userList = new();
private List<string> userNumberList = ["0", "0", "0", "0", "0", "0"]; private List<string> userNumberList = ["0", "0", "0", "0", "0", "0"];
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();
private MediaPlayer _mediaPlayer = new MediaPlayer(); private MediaPlayer _mediaPlayer = new MediaPlayer();
private bool IsGameStarted = false; private bool IsGameStarted = false;
List<string> _useName = ["一号位", "五号位", "二号位", "六号位", "三号位", "七号位",]; List<string> _useName = ["一号位", "五号位", "二号位", "六号位", "三号位", "七号位",];
private readonly object _updateLock = new object();
private readonly Dictionary<int, (string lastNumber, DateTime lastChangeTime, string currentState)> _jumpStatus = new Dictionary<int, (string, DateTime, string)>();
public GroupJumpRope() public GroupJumpRope()
{ {
InitializeComponent(); InitializeComponent();
@ -345,23 +347,22 @@ namespace Wpf_AiSportsMicrospace.Views
_firstHandTriggered = false; _firstHandTriggered = false;
_lastCountdownSecond = 3; _lastCountdownSecond = 3;
} }
private Dictionary<int, DateTime> _lastJumpUpdateTime = new(); // 用于存储最后更新时间
private Dictionary<int, DateTime> _lastUIUpdateTime = new(); // 用于防抖处理
public Human LocateHuman(List<Human> humans, double frameWidth, double frameHeight, int circleIndex)
{
if (humans == null || humans.Count == 0)
{
return null;
}
double circleX = circlePositions[circleIndex].XNorm; private void UpdateCircleCounts(List<Human> humans)
double circleY = circlePositions[circleIndex].YNorm; {
lock (_updateLock)
{
double radiusNormX = 0.07; double radiusNormX = 0.07;
double radiusNormY = 0.14; double radiusNormY = 0.07;
Human inCircleHuman = null; for (int i = 0; i < circlePositions.Count; i++)
bool isOut = false; {
var circleX = circlePositions[i].XNorm;
var circleY = circlePositions[i].YNorm;
Human humanInCircle = null;
// 找圈内的人
foreach (var hu in humans) foreach (var hu in humans)
{ {
var rightFoot = hu.Keypoints.FirstOrDefault(k => k.Name == "right_ankle"); var rightFoot = hu.Keypoints.FirstOrDefault(k => k.Name == "right_ankle");
@ -369,10 +370,10 @@ namespace Wpf_AiSportsMicrospace.Views
if (rightFoot == null || leftFoot == null) if (rightFoot == null || leftFoot == null)
continue; continue;
double xRightNorm = rightFoot.X / frameWidth; double xRightNorm = rightFoot.X / userBox.ActualWidth;
double xLeftNorm = leftFoot.X / frameWidth; double xLeftNorm = leftFoot.X / userBox.ActualWidth;
double yRightNorm = rightFoot.Y / frameHeight; double yRightNorm = rightFoot.Y / userBox.ActualHeight;
double yLeftNorm = leftFoot.Y / frameHeight; double yLeftNorm = leftFoot.Y / userBox.ActualHeight;
bool outOfCircle = bool outOfCircle =
xRightNorm < (circleX - radiusNormX) || xRightNorm > (circleX + radiusNormX) || xRightNorm < (circleX - radiusNormX) || xRightNorm > (circleX + radiusNormX) ||
@ -380,48 +381,60 @@ namespace Wpf_AiSportsMicrospace.Views
yRightNorm < (circleY - radiusNormY) || yRightNorm > (circleY + radiusNormY) || yRightNorm < (circleY - radiusNormY) || yRightNorm > (circleY + radiusNormY) ||
yLeftNorm < (circleY - radiusNormY) || yLeftNorm > (circleY + radiusNormY); yLeftNorm < (circleY - radiusNormY) || yLeftNorm > (circleY + radiusNormY);
if (outOfCircle) if (!outOfCircle)
{ {
isOut = true; humanInCircle = hu;
} break; // 每圈只处理一个人
else if (inCircleHuman == null)
{
inCircleHuman = hu;
} }
} }
if (isOut) // 根据是否有人和跳绳数字判断状态
userList[circleIndex].ImageState = "3"; bool hasHuman = humanInCircle != null;
else userList[i].ImageState = GetJumpState(i, hasHuman);
// 推送计数
if (hasHuman)
sports[i].Pushing(humanInCircle);
}
}
}
private string GetJumpState(int circleIndex, bool humanInCircle)
{ {
//if (userList[circleIndex].ImageState == "3") if (!humanInCircle)
{
// 无人 → 出圈
return "3";
}
string currentNumber = userNumberList[circleIndex];
if (!_jumpStatus.ContainsKey(circleIndex))
{
_jumpStatus[circleIndex] = (currentNumber, DateTime.Now, "1"); // 初始状态先为停止
return "1";
}
var (lastNumber, lastChangeTime, lastState) = _jumpStatus[circleIndex];
//if (currentNumber != lastNumber)
//{ //{
// userList[circleIndex].ImageState = "1"; // // 数字变化 → 跳绳中
// _jumpStatus[circleIndex] = (currentNumber, DateTime.Now, "2");
// return "2";
//} //}
// 检查当前编号是否未变化超过 2 秒
if (userNumberList[circleIndex] == userList[circleIndex].NumberText)
{
// 获取上次变化时间
if (!_lastJumpUpdateTime.TryGetValue(circleIndex, out var lastTime))
lastTime = DateTime.Now; // 默认当前时间
var elapsed = (DateTime.Now - lastTime).TotalSeconds; // 数字未变化,判断是否超过 2 秒
double elapsed = (DateTime.Now - lastChangeTime).TotalSeconds;
if (elapsed >= 3)
{
// 超过 2 秒未变化 → 停止
_jumpStatus[circleIndex] = (currentNumber, lastChangeTime, "1");
return "1";
}
if (elapsed > 1) // 维持上次状态
{ return lastState;
userList[circleIndex].ImageState = "1";
_lastJumpUpdateTime[circleIndex] = DateTime.Now;
}
// 否则2 秒内仍在变化,不更新状态
}
else
{
// 编号发生变化,更新记录,并保持状态不变
userNumberList[circleIndex] = userList[circleIndex].NumberText;
_lastJumpUpdateTime[circleIndex] = DateTime.Now;
}
}
return inCircleHuman;
} }
private void DrawCirclesWithText() private void DrawCirclesWithText()
@ -475,25 +488,6 @@ namespace Wpf_AiSportsMicrospace.Views
sports.Add(sport); sports.Add(sport);
} }
} }
private void UpdateCircleCounts(List<Human> humans)
{
// 在后台线程运行检测逻辑
//Parallel.For(0, circlePositions.Count, i =>
//{
// var human = LocateHuman(humans, userBox.ActualWidth, userBox.ActualHeight, i);
// sports[i].Pushing(human);
//});
for (int i = 0; i < circlePositions.Count; i++)
{
var human = LocateHuman(humans, userBox.ActualWidth, userBox.ActualHeight, i);
if (human != null)
{
sports[i].Pushing(human);
}
}
}
/// <summary> /// <summary>
/// 添加带渐变光的圆圈(中心红色,边缘蓝色) /// 添加带渐变光的圆圈(中心红色,边缘蓝色)
@ -507,7 +501,7 @@ namespace Wpf_AiSportsMicrospace.Views
userItem.VerticalAlignment = VerticalAlignment.Top; userItem.VerticalAlignment = VerticalAlignment.Top;
userItem.HorizontalAlignment = HorizontalAlignment.Left; userItem.HorizontalAlignment = HorizontalAlignment.Left;
userItem.ImageState = "1"; userItem.ImageState = "1";
userItem.Margin = new Thickness(centerX - (index == 0 ? 80 : index == 6 ? 190 : 135), centerY - 540, 0, 0); userItem.Margin = new Thickness(centerX - 265, centerY - 500, 0, 0);
userBox.Children.Add(userItem); userBox.Children.Add(userItem);
userList.Add(userItem); userList.Add(userItem);
return userItem; // return userItem; //