[MF]修改石头剪刀布倒计时和随机逻辑
This commit is contained in:
parent
59ba028e01
commit
539eadbaf3
@ -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 @@
|
||||
<div id="video-container">
|
||||
<video id="videoFeed" autoplay muted playsinline></video>
|
||||
<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>
|
||||
</div>
|
||||
@ -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 = `<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() {
|
||||
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 @@
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
Loading…
x
Reference in New Issue
Block a user