kadunban
This commit is contained in:
parent
8ab511e961
commit
68b5ad8c1e
@ -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,83 +347,94 @@ namespace Wpf_AiSportsMicrospace.Views
|
|||||||
_firstHandTriggered = false;
|
_firstHandTriggered = false;
|
||||||
_lastCountdownSecond = 3;
|
_lastCountdownSecond = 3;
|
||||||
}
|
}
|
||||||
private Dictionary<int, DateTime> _lastJumpUpdateTime = new(); // 用于存储最后更新时间
|
|
||||||
private Dictionary<int, DateTime> _lastUIUpdateTime = new(); // 用于防抖处理
|
private void UpdateCircleCounts(List<Human> humans)
|
||||||
public Human LocateHuman(List<Human> humans, double frameWidth, double frameHeight, int circleIndex)
|
|
||||||
{
|
{
|
||||||
if (humans == null || humans.Count == 0)
|
lock (_updateLock)
|
||||||
{
|
{
|
||||||
return null;
|
double radiusNormX = 0.07;
|
||||||
}
|
double radiusNormY = 0.07;
|
||||||
|
|
||||||
double circleX = circlePositions[circleIndex].XNorm;
|
for (int i = 0; i < circlePositions.Count; i++)
|
||||||
double circleY = circlePositions[circleIndex].YNorm;
|
|
||||||
double radiusNormX = 0.07;
|
|
||||||
double radiusNormY = 0.14;
|
|
||||||
|
|
||||||
Human inCircleHuman = null;
|
|
||||||
bool isOut = false;
|
|
||||||
|
|
||||||
foreach (var hu 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;
|
|
||||||
|
|
||||||
double xRightNorm = rightFoot.X / frameWidth;
|
|
||||||
double xLeftNorm = leftFoot.X / frameWidth;
|
|
||||||
double yRightNorm = rightFoot.Y / frameHeight;
|
|
||||||
double yLeftNorm = leftFoot.Y / frameHeight;
|
|
||||||
|
|
||||||
bool outOfCircle =
|
|
||||||
xRightNorm < (circleX - radiusNormX) || xRightNorm > (circleX + radiusNormX) ||
|
|
||||||
xLeftNorm < (circleX - radiusNormX) || xLeftNorm > (circleX + radiusNormX) ||
|
|
||||||
yRightNorm < (circleY - radiusNormY) || yRightNorm > (circleY + radiusNormY) ||
|
|
||||||
yLeftNorm < (circleY - radiusNormY) || yLeftNorm > (circleY + radiusNormY);
|
|
||||||
|
|
||||||
if (outOfCircle)
|
|
||||||
{
|
{
|
||||||
isOut = true;
|
var circleX = circlePositions[i].XNorm;
|
||||||
}
|
var circleY = circlePositions[i].YNorm;
|
||||||
else if (inCircleHuman == null)
|
|
||||||
{
|
|
||||||
inCircleHuman = hu;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isOut)
|
Human humanInCircle = null;
|
||||||
userList[circleIndex].ImageState = "3";
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//if (userList[circleIndex].ImageState == "3")
|
|
||||||
//{
|
|
||||||
// userList[circleIndex].ImageState = "1";
|
|
||||||
//}
|
|
||||||
// 检查当前编号是否未变化超过 2 秒
|
|
||||||
if (userNumberList[circleIndex] == userList[circleIndex].NumberText)
|
|
||||||
{
|
|
||||||
// 获取上次变化时间
|
|
||||||
if (!_lastJumpUpdateTime.TryGetValue(circleIndex, out var lastTime))
|
|
||||||
lastTime = DateTime.Now; // 默认当前时间
|
|
||||||
|
|
||||||
var elapsed = (DateTime.Now - lastTime).TotalSeconds;
|
// 找圈内的人
|
||||||
|
foreach (var hu in humans)
|
||||||
if (elapsed > 1)
|
|
||||||
{
|
{
|
||||||
userList[circleIndex].ImageState = "1";
|
var rightFoot = hu.Keypoints.FirstOrDefault(k => k.Name == "right_ankle");
|
||||||
_lastJumpUpdateTime[circleIndex] = DateTime.Now;
|
var leftFoot = hu.Keypoints.FirstOrDefault(k => k.Name == "left_ankle");
|
||||||
|
if (rightFoot == null || leftFoot == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
double xRightNorm = rightFoot.X / userBox.ActualWidth;
|
||||||
|
double xLeftNorm = leftFoot.X / userBox.ActualWidth;
|
||||||
|
double yRightNorm = rightFoot.Y / userBox.ActualHeight;
|
||||||
|
double yLeftNorm = leftFoot.Y / userBox.ActualHeight;
|
||||||
|
|
||||||
|
bool outOfCircle =
|
||||||
|
xRightNorm < (circleX - radiusNormX) || xRightNorm > (circleX + radiusNormX) ||
|
||||||
|
xLeftNorm < (circleX - radiusNormX) || xLeftNorm > (circleX + radiusNormX) ||
|
||||||
|
yRightNorm < (circleY - radiusNormY) || yRightNorm > (circleY + radiusNormY) ||
|
||||||
|
yLeftNorm < (circleY - radiusNormY) || yLeftNorm > (circleY + radiusNormY);
|
||||||
|
|
||||||
|
if (!outOfCircle)
|
||||||
|
{
|
||||||
|
humanInCircle = hu;
|
||||||
|
break; // 每圈只处理一个人
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// 否则:2 秒内仍在变化,不更新状态
|
|
||||||
}
|
// 根据是否有人和跳绳数字判断状态
|
||||||
else
|
bool hasHuman = humanInCircle != null;
|
||||||
{
|
userList[i].ImageState = GetJumpState(i, hasHuman);
|
||||||
// 编号发生变化,更新记录,并保持状态不变
|
|
||||||
userNumberList[circleIndex] = userList[circleIndex].NumberText;
|
// 推送计数
|
||||||
_lastJumpUpdateTime[circleIndex] = DateTime.Now;
|
if (hasHuman)
|
||||||
|
sports[i].Pushing(humanInCircle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return inCircleHuman;
|
}
|
||||||
|
|
||||||
|
private string GetJumpState(int circleIndex, bool humanInCircle)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
//{
|
||||||
|
// // 数字变化 → 跳绳中
|
||||||
|
// _jumpStatus[circleIndex] = (currentNumber, DateTime.Now, "2");
|
||||||
|
// return "2";
|
||||||
|
//}
|
||||||
|
|
||||||
|
// 数字未变化,判断是否超过 2 秒
|
||||||
|
double elapsed = (DateTime.Now - lastChangeTime).TotalSeconds;
|
||||||
|
if (elapsed >= 3)
|
||||||
|
{
|
||||||
|
// 超过 2 秒未变化 → 停止
|
||||||
|
_jumpStatus[circleIndex] = (currentNumber, lastChangeTime, "1");
|
||||||
|
return "1";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 维持上次状态
|
||||||
|
return lastState;
|
||||||
}
|
}
|
||||||
|
|
||||||
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; //
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user