[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; | ||||||
|  |                                         // ORIGINAL playRound call | ||||||
|                                         playRound(predictedGesture);  |                                         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,7 +695,7 @@ | |||||||
| 
 | 
 | ||||||
|         // 游戏逻辑 |         // 游戏逻辑 | ||||||
|         function playRound(userGesture) { |         function playRound(userGesture) { | ||||||
|             currentRound++; |             currentRound++; // IMPORTANT: Restore this line | ||||||
| 
 | 
 | ||||||
|             // AI 随机选择 |             // AI 随机选择 | ||||||
|             const aiOptions = Object.values(gestureMap); |             const aiOptions = Object.values(gestureMap); | ||||||
| @ -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 ? '准备就绪' : '请导入模型'); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user