From 089a2db31058c5f1c3f4c8150d9fe9cb99da5d91 Mon Sep 17 00:00:00 2001 From: cmclark00 Date: Tue, 25 Mar 2025 17:16:06 -0400 Subject: [PATCH] Fine-tune touch controls: improve swipe responsiveness, prevent accidental hard drops, enhance instructions --- script.js | 92 +++++++++++++++++++++++++++++++++++++++++-------------- style.css | 23 ++++++++++++-- 2 files changed, 90 insertions(+), 25 deletions(-) diff --git a/script.js b/script.js index 6d0484f..ddbc3f8 100644 --- a/script.js +++ b/script.js @@ -2182,14 +2182,17 @@ function clearPreviousPiecePosition() { let touchStartX = 0; let touchStartY = 0; let touchStartTime = 0; -const SWIPE_THRESHOLD = 30; +const SWIPE_THRESHOLD = 15; // Reduced threshold for more responsive movement const TAP_THRESHOLD = 200; // milliseconds -const DOUBLE_TAP_THRESHOLD = 300; // milliseconds +const DOUBLE_TAP_THRESHOLD = 400; // Increased to prevent accidental double-taps let lastTapTime = 0; let lastMoveTime = 0; let touchIdentifier = null; let multiTouchDetected = false; -const MOVE_COOLDOWN = 100; // ms between moves to prevent too rapid movement +const MOVE_COOLDOWN = 60; // Reduced cooldown for smoother movement +let lastTapX = 0; +let lastTapY = 0; +const TAP_DISTANCE_THRESHOLD = 20; // Maximum distance to consider as same-position tap // Initialize touch controls function initTouchControls() { @@ -2232,7 +2235,6 @@ function handleTouchMove(event) { if (multiTouchDetected || event.touches.length > 1) return; const now = Date.now(); - if (now - lastMoveTime < MOVE_COOLDOWN) return; if (!event.touches.length) return; @@ -2247,25 +2249,27 @@ function handleTouchMove(event) { const absX = Math.abs(diffX); const absY = Math.abs(diffY); - if (absX > SWIPE_THRESHOLD || absY > SWIPE_THRESHOLD) { - // Determine direction of swipe - if more horizontal than vertical - if (absX > absY) { + if (absX > SWIPE_THRESHOLD) { + // Horizontal movement has priority and a shorter cooldown + if (now - lastMoveTime >= MOVE_COOLDOWN) { if (diffX > 0) { p.moveRight(); } else { p.moveLeft(); } - } else { - // Only handle downward swipes for soft drop - if (diffY > 0) { - p.moveDown(); - } + + // Reset touch start to allow for continuous movement + touchStartX = touch.clientX; + lastMoveTime = now; + } + } + // Only handle downward swipes for soft drop - if no horizontal movement is detected + else if (absY > SWIPE_THRESHOLD * 2 && absY > absX && diffY > 0) { + if (now - lastMoveTime >= MOVE_COOLDOWN * 2) { // Use longer cooldown for down movement + p.moveDown(); + touchStartY = touch.clientY; + lastMoveTime = now; } - - // Reset touch start to allow for continuous movement - touchStartX = touch.clientX; - touchStartY = touch.clientY; - lastMoveTime = now; } } @@ -2289,16 +2293,30 @@ function handleTouchEnd(event) { const touchEndTime = Date.now(); const touchDuration = touchEndTime - touchStartTime; + // Get touch coordinates + const touch = event.changedTouches[0]; + const touchX = touch.clientX; + const touchY = touch.clientY; + // Check for tap (quick touch) if (touchDuration < TAP_THRESHOLD) { // Check for double tap (for hard drop) - if (touchEndTime - lastTapTime < DOUBLE_TAP_THRESHOLD) { + // Must be within time threshold AND close to the same position + const timeBetweenTaps = touchEndTime - lastTapTime; + const distanceBetweenTaps = Math.sqrt( + Math.pow(touchX - lastTapX, 2) + + Math.pow(touchY - lastTapY, 2) + ); + + if (timeBetweenTaps < DOUBLE_TAP_THRESHOLD && distanceBetweenTaps < TAP_DISTANCE_THRESHOLD) { p.hardDrop(); lastTapTime = 0; // Reset to prevent triple-tap detection } else { // Single tap rotates piece p.rotate('right'); lastTapTime = touchEndTime; + lastTapX = touchX; + lastTapY = touchY; } } @@ -2314,11 +2332,12 @@ function createTouchControlButtons() { const touchInstructions = document.createElement('div'); touchInstructions.className = 'touch-instructions'; touchInstructions.innerHTML = ` -

Swipe left/right: Move piece

-

Swipe down: Soft drop

-

Tap: Rotate right

-

Double tap: Hard drop

-

Two-finger tap: 3D rotate

+

Touch Controls

+

Swipe left/right: Move piece

+

Swipe down: Soft drop

+

Tap anywhere: Rotate right

+

Double-tap: Hard drop

+

Two-finger tap: 3D rotate

`; document.body.appendChild(touchInstructions); @@ -2326,9 +2345,36 @@ function createTouchControlButtons() { setTimeout(() => { touchInstructions.classList.add('fade-out'); setTimeout(() => { + // Keep element in DOM but hidden, so it can be shown again later + touchInstructions.style.opacity = '0'; touchInstructions.style.display = 'none'; }, 1000); }, 5000); + + // Add instruction toggle button to score container + const instructionsBtn = document.createElement('button'); + instructionsBtn.className = 'game-btn instructions-btn'; + instructionsBtn.innerHTML = 'Controls'; + instructionsBtn.addEventListener('click', function() { + // Show instructions again + touchInstructions.style.display = 'block'; + touchInstructions.style.opacity = '1'; + touchInstructions.classList.remove('fade-out'); + + // Fade out after 5 seconds + setTimeout(() => { + touchInstructions.classList.add('fade-out'); + setTimeout(() => { + touchInstructions.style.display = 'none'; + }, 1000); + }, 5000); + }); + + // Add button to score container + const scoreContainer = document.querySelector('.score-container'); + if (scoreContainer) { + scoreContainer.appendChild(instructionsBtn); + } } // Set active piece to next piece and create new next piece diff --git a/style.css b/style.css index fd726cb..2a5d6ea 100644 --- a/style.css +++ b/style.css @@ -658,7 +658,7 @@ input[type=range]::-moz-range-thumb { top: 50%; left: 50%; transform: translate(-50%, -50%); - background: rgba(0, 0, 0, 0.8); + background: rgba(0, 0, 0, 0.9); border: 2px solid rgba(0, 255, 255, 0.7); border-radius: 10px; padding: 15px; @@ -666,6 +666,14 @@ input[type=range]::-moz-range-thumb { box-shadow: 0 0 20px rgba(0, 255, 255, 0.5); transition: opacity 1s ease; text-align: center; + max-width: 90vw; +} + +.touch-instructions h3 { + color: #00ffff; + text-shadow: 0 0 5px #00ffff, 0 0 10px #00ffff; + margin-bottom: 15px; + font-size: 16px; } .mobile-mode .touch-instructions { @@ -674,10 +682,21 @@ input[type=range]::-moz-range-thumb { .touch-instructions p { margin: 10px 0; - font-size: 14px; + font-size: 13px; color: #fff; + text-align: left; +} + +.touch-instructions p b { + color: #ff9900; + text-shadow: 0 0 5px rgba(255, 153, 0, 0.5); } .touch-instructions.fade-out { opacity: 0; +} + +.instructions-btn { + margin-top: 15px; + background: linear-gradient(45deg, #ff9900, #ff5500); } \ No newline at end of file