about summary refs log tree commit diff stats
path: root/html/plains
diff options
context:
space:
mode:
authorelioat <elioat@tilde.institute>2024-12-13 15:46:01 -0500
committerelioat <elioat@tilde.institute>2024-12-13 15:46:01 -0500
commitd03aa9e95b865a2a89f0d89d4045d16aaef55d72 (patch)
tree0ef5b3bb45460ffd38dc482f79775e50dfc5e147 /html/plains
parent0edfe176ce5149b2d934b1b43a2fd2a35b50791d (diff)
downloadtour-d03aa9e95b865a2a89f0d89d4045d16aaef55d72.tar.gz
*
Diffstat (limited to 'html/plains')
-rw-r--r--html/plains/game.js69
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