[MF]修改石头剪刀布倒计时和随机逻辑
This commit is contained in:
parent
59ba028e01
commit
539eadbaf3
@ -137,6 +137,36 @@
|
|||||||
z-index: 3;
|
z-index: 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* --- Start: Countdown specific styles --- */
|
||||||
|
.countdown-overlay {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: rgba(0, 0, 0, 0.85); /* Slightly darker for better contrast */
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 8rem; /* Large font for countdown */
|
||||||
|
font-weight: bold;
|
||||||
|
color: #00d4ff;
|
||||||
|
text-shadow: 0 0 30px rgba(0, 212, 255, 0.8);
|
||||||
|
z-index: 5; /* Above video/canvas but below status bar if needed, adjusted based on existing z-index structure */
|
||||||
|
border-radius: 15px;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.3s ease-in-out;
|
||||||
|
pointer-events: none; /* Allow interaction with elements behind it when not visible */
|
||||||
|
}
|
||||||
|
|
||||||
|
.countdown-overlay.show {
|
||||||
|
opacity: 1;
|
||||||
|
/* When visible, it takes pointer events to block interaction with video elements */
|
||||||
|
pointer-events: auto;
|
||||||
|
}
|
||||||
|
/* --- End: Countdown specific styles --- */
|
||||||
|
|
||||||
|
|
||||||
/* Control Panel */
|
/* Control Panel */
|
||||||
.control-panel {
|
.control-panel {
|
||||||
background: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.05) 100%);
|
background: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.05) 100%);
|
||||||
@ -354,6 +384,9 @@
|
|||||||
<div id="video-container">
|
<div id="video-container">
|
||||||
<video id="videoFeed" autoplay muted playsinline></video>
|
<video id="videoFeed" autoplay muted playsinline></video>
|
||||||
<canvas id="poseCanvas"></canvas>
|
<canvas id="poseCanvas"></canvas>
|
||||||
|
<!-- START: Countdown Overlay Element -->
|
||||||
|
<div id="countdownOverlay" class="countdown-overlay"></div>
|
||||||
|
<!-- END: Countdown Overlay Element -->
|
||||||
<div class="status-bar" id="statusDisplay">正在初始化系统...</div>
|
<div class="status-bar" id="statusDisplay">正在初始化系统...</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -422,6 +455,9 @@
|
|||||||
const resetBtn = document.getElementById('resetBtn');
|
const resetBtn = document.getElementById('resetBtn');
|
||||||
const importModelBtn = document.getElementById('importModelBtn');
|
const importModelBtn = document.getElementById('importModelBtn');
|
||||||
const fileImporter = document.getElementById('fileImporter');
|
const fileImporter = document.getElementById('fileImporter');
|
||||||
|
// START: Add Countdown Overlay Element
|
||||||
|
const countdownOverlay = document.getElementById('countdownOverlay');
|
||||||
|
// END: Add Countdown Overlay Element
|
||||||
|
|
||||||
let detector;
|
let detector;
|
||||||
let classifier;
|
let classifier;
|
||||||
@ -433,6 +469,9 @@
|
|||||||
let currentRound = 0;
|
let currentRound = 0;
|
||||||
let lastPrediction = null;
|
let lastPrediction = null;
|
||||||
let predictionCooldown = false;
|
let predictionCooldown = false;
|
||||||
|
// START: Add countdown state variable
|
||||||
|
let isCountingDown = false;
|
||||||
|
// END: Add countdown state variable
|
||||||
|
|
||||||
// 手势映射
|
// 手势映射
|
||||||
const gestureMap = {
|
const gestureMap = {
|
||||||
@ -575,7 +614,10 @@
|
|||||||
if (hands && hands.length > 0) {
|
if (hands && hands.length > 0) {
|
||||||
drawHand(hands[0]);
|
drawHand(hands[0]);
|
||||||
|
|
||||||
if (isModelLoaded && isPlaying && !predictionCooldown) {
|
// START: Modify prediction condition to include isCountingDown
|
||||||
|
// Only make predictions if game is playing AND not in cooldown AND NOT counting down
|
||||||
|
if (isModelLoaded && isPlaying && !predictionCooldown && !isCountingDown) {
|
||||||
|
// END: Modify prediction condition to include isCountingDown
|
||||||
const handTensor = flattenHand(hands[0]);
|
const handTensor = flattenHand(hands[0]);
|
||||||
|
|
||||||
if (classifier.getNumClasses() > 0) {
|
if (classifier.getNumClasses() > 0) {
|
||||||
@ -587,12 +629,12 @@
|
|||||||
const predictedGesture = gestureMap[prediction.label];
|
const predictedGesture = gestureMap[prediction.label];
|
||||||
if (predictedGesture && prediction.label !== lastPrediction) {
|
if (predictedGesture && prediction.label !== lastPrediction) {
|
||||||
lastPrediction = prediction.label;
|
lastPrediction = prediction.label;
|
||||||
playRound(predictedGesture);
|
// ORIGINAL playRound call
|
||||||
|
playRound(predictedGesture);
|
||||||
predictionCooldown = true;
|
predictionCooldown = true;
|
||||||
setTimeout(() => {
|
// START: Initiate countdown AFTER a round is played
|
||||||
predictionCooldown = false;
|
startCountdownForNextRound();
|
||||||
lastPrediction = null;
|
// END: Initiate countdown AFTER a round is played
|
||||||
}, 2000);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -653,8 +695,8 @@
|
|||||||
|
|
||||||
// 游戏逻辑
|
// 游戏逻辑
|
||||||
function playRound(userGesture) {
|
function playRound(userGesture) {
|
||||||
currentRound++;
|
currentRound++; // IMPORTANT: Restore this line
|
||||||
|
|
||||||
// AI 随机选择
|
// AI 随机选择
|
||||||
const aiOptions = Object.values(gestureMap);
|
const aiOptions = Object.values(gestureMap);
|
||||||
const aiGesture = aiOptions[Math.floor(Math.random() * aiOptions.length)];
|
const aiGesture = aiOptions[Math.floor(Math.random() * aiOptions.length)];
|
||||||
@ -692,21 +734,69 @@
|
|||||||
resultDisplay.innerHTML = `<div class="result-text ${resultClass}">${result}</div>`;
|
resultDisplay.innerHTML = `<div class="result-text ${resultClass}">${result}</div>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 开始游戏
|
// START: New function for countdown before next round
|
||||||
|
function startCountdownForNextRound() {
|
||||||
|
if (!isPlaying) return; // Only run if game is active
|
||||||
|
|
||||||
|
isCountingDown = true; // Disable hand detection during countdown
|
||||||
|
countdownOverlay.textContent = ''; // Clear previous text
|
||||||
|
countdownOverlay.classList.add('show');
|
||||||
|
updateStatus('下一回合准备中...');
|
||||||
|
|
||||||
|
let count = 3;
|
||||||
|
const countdownInterval = setInterval(() => {
|
||||||
|
if (count > 0) {
|
||||||
|
countdownOverlay.textContent = count;
|
||||||
|
count--;
|
||||||
|
} else {
|
||||||
|
clearInterval(countdownInterval);
|
||||||
|
countdownOverlay.classList.remove('show');
|
||||||
|
countdownOverlay.textContent = ''; // Clear "GO!" text immediately
|
||||||
|
isCountingDown = false; // Enable hand detection again
|
||||||
|
predictionCooldown = false; // Allow new predictions
|
||||||
|
lastPrediction = null; // Reset last prediction to allow new gesture
|
||||||
|
updateStatus('游戏进行中 - 请做出手势');
|
||||||
|
|
||||||
|
// Clear previous choices and results for the new round
|
||||||
|
userChoiceDisplay.textContent = '-';
|
||||||
|
aiChoiceDisplay.textContent = '-';
|
||||||
|
resultDisplay.innerHTML = '';
|
||||||
|
choicesDisplay.style.display = 'flex'; // Ensure choices are visible for new round
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
// END: New function for countdown
|
||||||
|
|
||||||
|
// 开始游戏 (Modified to initiate first round countdown)
|
||||||
function startGame() {
|
function startGame() {
|
||||||
isPlaying = true;
|
isPlaying = true;
|
||||||
currentRound = 0;
|
currentRound = 0; // Initialize to 0, playRound will increment it to 1 for the first round.
|
||||||
roundInfo.textContent = '游戏进行中...';
|
|
||||||
choicesDisplay.style.display = 'none';
|
// Clear choices and results display immediately when game starts
|
||||||
|
userChoiceDisplay.textContent = '-';
|
||||||
|
aiChoiceDisplay.textContent = '-';
|
||||||
resultDisplay.innerHTML = '';
|
resultDisplay.innerHTML = '';
|
||||||
|
choicesDisplay.style.display = 'flex'; // Ensure choices are visible when game starts
|
||||||
|
|
||||||
startBtn.textContent = '游戏中...';
|
startBtn.textContent = '游戏中...';
|
||||||
startBtn.disabled = true;
|
startBtn.disabled = true;
|
||||||
updateStatus('游戏进行中 - 请做出手势');
|
resetBtn.disabled = false; // Enable reset once game starts
|
||||||
|
importModelBtn.disabled = true; // Disable import once game starts
|
||||||
|
|
||||||
|
// Start the very first countdown for the first round
|
||||||
|
startCountdownForNextRound();
|
||||||
|
// Note: statusDisplay will be updated by startCountdownForNextRound
|
||||||
}
|
}
|
||||||
|
|
||||||
// 重置游戏
|
// 重置游戏 (Modified to handle countdown state cleanup)
|
||||||
function resetGame() {
|
function resetGame() {
|
||||||
isPlaying = false;
|
isPlaying = false;
|
||||||
|
// START: Clean up countdown state on reset
|
||||||
|
isCountingDown = false;
|
||||||
|
countdownOverlay.classList.remove('show');
|
||||||
|
countdownOverlay.textContent = '';
|
||||||
|
// END: Clean up countdown state on reset
|
||||||
|
|
||||||
scores = { user: 0, ai: 0 };
|
scores = { user: 0, ai: 0 };
|
||||||
currentRound = 0;
|
currentRound = 0;
|
||||||
userScoreDisplay.textContent = '0';
|
userScoreDisplay.textContent = '0';
|
||||||
@ -716,6 +806,8 @@
|
|||||||
resultDisplay.innerHTML = '';
|
resultDisplay.innerHTML = '';
|
||||||
startBtn.textContent = '开始游戏';
|
startBtn.textContent = '开始游戏';
|
||||||
startBtn.disabled = !isModelLoaded;
|
startBtn.disabled = !isModelLoaded;
|
||||||
|
resetBtn.disabled = false; // Already enabled, just ensuring
|
||||||
|
importModelBtn.disabled = false; // Enable import button again
|
||||||
predictionCooldown = false;
|
predictionCooldown = false;
|
||||||
lastPrediction = null;
|
lastPrediction = null;
|
||||||
updateStatus(isModelLoaded ? '准备就绪' : '请导入模型');
|
updateStatus(isModelLoaded ? '准备就绪' : '请导入模型');
|
||||||
@ -765,4 +857,4 @@
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user