From 539eadbaf30151c9eb5fb2f6bfdb4caf4671ed87 Mon Sep 17 00:00:00 2001 From: 51hhh Date: Tue, 26 Aug 2025 09:57:09 +0800 Subject: [PATCH] =?UTF-8?q?[MF]=E4=BF=AE=E6=94=B9=E7=9F=B3=E5=A4=B4?= =?UTF-8?q?=E5=89=AA=E5=88=80=E5=B8=83=E5=80=92=E8=AE=A1=E6=97=B6=E5=92=8C?= =?UTF-8?q?=E9=9A=8F=E6=9C=BA=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- game/石头剪刀布/game.html | 122 +++++++++++++++++++++++++++++++++----- 1 file changed, 107 insertions(+), 15 deletions(-) diff --git a/game/石头剪刀布/game.html b/game/石头剪刀布/game.html index ef722c6..146de16 100644 --- a/game/石头剪刀布/game.html +++ b/game/石头剪刀布/game.html @@ -137,6 +137,36 @@ 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 { background: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.05) 100%); @@ -354,6 +384,9 @@
+ +
+
正在初始化系统...
@@ -422,6 +455,9 @@ const resetBtn = document.getElementById('resetBtn'); const importModelBtn = document.getElementById('importModelBtn'); const fileImporter = document.getElementById('fileImporter'); + // START: Add Countdown Overlay Element + const countdownOverlay = document.getElementById('countdownOverlay'); + // END: Add Countdown Overlay Element let detector; let classifier; @@ -433,6 +469,9 @@ let currentRound = 0; let lastPrediction = null; let predictionCooldown = false; + // START: Add countdown state variable + let isCountingDown = false; + // END: Add countdown state variable // 手势映射 const gestureMap = { @@ -575,7 +614,10 @@ if (hands && hands.length > 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]); if (classifier.getNumClasses() > 0) { @@ -587,12 +629,12 @@ const predictedGesture = gestureMap[prediction.label]; if (predictedGesture && prediction.label !== lastPrediction) { lastPrediction = prediction.label; - playRound(predictedGesture); + // ORIGINAL playRound call + playRound(predictedGesture); predictionCooldown = true; - setTimeout(() => { - predictionCooldown = false; - lastPrediction = null; - }, 2000); + // START: Initiate countdown AFTER a round is played + startCountdownForNextRound(); + // END: Initiate countdown AFTER a round is played } } } else { @@ -653,8 +695,8 @@ // 游戏逻辑 function playRound(userGesture) { - currentRound++; - + currentRound++; // IMPORTANT: Restore this line + // AI 随机选择 const aiOptions = Object.values(gestureMap); const aiGesture = aiOptions[Math.floor(Math.random() * aiOptions.length)]; @@ -692,21 +734,69 @@ resultDisplay.innerHTML = `
${result}
`; } - // 开始游戏 + // 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() { isPlaying = true; - currentRound = 0; - roundInfo.textContent = '游戏进行中...'; - choicesDisplay.style.display = 'none'; + currentRound = 0; // Initialize to 0, playRound will increment it to 1 for the first round. + + // Clear choices and results display immediately when game starts + userChoiceDisplay.textContent = '-'; + aiChoiceDisplay.textContent = '-'; resultDisplay.innerHTML = ''; + choicesDisplay.style.display = 'flex'; // Ensure choices are visible when game starts + startBtn.textContent = '游戏中...'; 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() { 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 }; currentRound = 0; userScoreDisplay.textContent = '0'; @@ -716,6 +806,8 @@ resultDisplay.innerHTML = ''; startBtn.textContent = '开始游戏'; startBtn.disabled = !isModelLoaded; + resetBtn.disabled = false; // Already enabled, just ensuring + importModelBtn.disabled = false; // Enable import button again predictionCooldown = false; lastPrediction = null; updateStatus(isModelLoaded ? '准备就绪' : '请导入模型'); @@ -765,4 +857,4 @@ }); - \ No newline at end of file +