diff options
author | elioat <elioat@tilde.institute> | 2024-12-13 15:46:01 -0500 |
---|---|---|
committer | elioat <elioat@tilde.institute> | 2024-12-13 15:46:01 -0500 |
commit | d03aa9e95b865a2a89f0d89d4045d16aaef55d72 (patch) | |
tree | 0ef5b3bb45460ffd38dc482f79775e50dfc5e147 | |
parent | 0edfe176ce5149b2d934b1b43a2fd2a35b50791d (diff) | |
download | tour-d03aa9e95b865a2a89f0d89d4045d16aaef55d72.tar.gz |
*
-rw-r--r-- | html/plains/game.js | 69 |
1 files changed, 63 insertions, 6 deletions
diff --git a/html/plains/game.js b/html/plains/game.js index cd37bd1..9a9fe4c 100644 --- a/html/plains/game.js +++ b/html/plains/game.js @@ -34,6 +34,11 @@ const CONFIG = { duration: 3000, // 3 seconds of use cooldown: 1000, // 1 second cooldown exhaustedAt: 0 // Track when dash was exhausted + }, + idle: { + startDelay: 2000, // Start idle animation after 2 seconds + lookSpeed: 0.001, // Speed of the looking animation + lookRadius: 0.3 // How far to look around (in radians) } }, sword: { @@ -100,7 +105,9 @@ const createInitialState = () => ({ dashStartTime: 0, // When the current dash started isDashing: false, // Currently dashing? dashExhausted: false, // Is dash on cooldown? - lastDashEnd: 0 // When the last dash ended + lastDashEnd: 0, // When the last dash ended + lastInputTime: 0, // Track when the last input occurred + baseDirection: { x: 0, y: -1 } // Store the actual facing direction }, particles: [], footprints: [], @@ -373,6 +380,9 @@ const handleKeyDown = (e) => { } }); } + + // Update last input time for any key press + state.player.lastInputTime = animationTime; }; const handleKeyUp = (e) => { @@ -396,6 +406,31 @@ const updatePlayer = () => { state.footprints = state.footprints.filter(footprint => { return (animationTime - footprint.createdAt) < CONFIG.footprints.lifetime; }); + + // Update player direction for idle animation + if (!keys.size && !state.player.isSwinging && !state.player.isDefending) { + const idleTime = animationTime - state.player.lastInputTime; + + if (idleTime > CONFIG.player.idle.startDelay) { + // Calculate looking direction using sine waves + const lookAngle = Math.sin(animationTime * CONFIG.player.idle.lookSpeed) * CONFIG.player.idle.lookRadius; + const baseAngle = Math.atan2(state.player.baseDirection.y, state.player.baseDirection.x); + const newAngle = baseAngle + lookAngle; + + state.player.direction = { + x: Math.cos(newAngle), + y: Math.sin(newAngle) + }; + } else { + // Reset direction to base direction when not idle + state.player.direction = { ...state.player.baseDirection }; + } + } else { + // Update last input time when other actions occur + if (state.player.isSwinging || state.player.isDefending) { + state.player.lastInputTime = animationTime; + } + } }; const createParticle = (x, y, angle) => ({ @@ -828,19 +863,29 @@ const calculateMovement = (keys) => { return { moving: false }; } + // Update last input time when moving + state.player.lastInputTime = animationTime; + const length = Math.sqrt(dx * dx + dy * dy); const normalizedDx = dx / length; const normalizedDy = dy / length; const isStrafing = keys.has(CONFIG.player.strafeKey); + const newDirection = isStrafing ? + { ...state.player.direction } : // Keep current direction while strafing + { x: normalizedDx, y: normalizedDy }; // Update direction normally + + // Update base direction when not strafing + if (!isStrafing) { + state.player.baseDirection = { ...newDirection }; + } + return { moving: true, dx: normalizedDx, dy: normalizedDy, - direction: isStrafing ? - { ...state.player.direction } : // Keep current direction while strafing - { x: normalizedDx, y: normalizedDy } // Update direction normally + direction: newDirection }; }; @@ -860,7 +905,19 @@ const getDotOpacity = (state, animationTime) => { const dashProgress = (animationTime - state.player.dashStartTime) / CONFIG.player.dash.duration; dashOpacity = 1 - (dashProgress * 0.7); // Fade to 0.3 during dash } + + // Add blinking effect when moving or defending + let blinkOpacity = 1; + if (state.player.isDefending) { + // Create a slow pulse using sin wave (period of about 1.5 seconds) + const blinkPhase = Math.sin(animationTime * 0.002); + // Only blink occasionally (when sin wave is above 0.7) + if (blinkPhase > 0.7) { + // Quick fade out and in + blinkOpacity = 0.3 + (blinkPhase - 0.7) * 2; + } + } - // Return the lower opacity of the two systems - return Math.min(bubbleOpacity, dashOpacity); + // Return the lowest opacity of all systems + return Math.min(bubbleOpacity, dashOpacity, blinkOpacity); }; \ No newline at end of file |