zeroed-some/dougk / 5a30cab

Browse files

make donny angle upward, track doug

Authored by espadonne
SHA
5a30cabc11c39beba738404c5076990280894647
Parents
aa974e3
Tree
4cdfcd3

2 changed files

StatusFile+-
M src/renderers/three/index.js 1 1
M src/renderers/three/narwhal.js 34 1
src/renderers/three/index.jsmodified
@@ -164,7 +164,7 @@ function animate() {
164164
   doug.update(delta, elapsed, breadManager.getActiveBits(), pond)
165165
   breadManager.update(delta, elapsed)
166166
   pond.update(delta, elapsed)
167
-  donny.update(delta, elapsed, pond)
167
+  donny.update(delta, elapsed, pond, doug)
168168
 
169169
   composer.render()
170170
 }
src/renderers/three/narwhal.jsmodified
@@ -188,9 +188,26 @@ export function createDonny(scene, gradientMap) {
188188
     group.rotation.y = angle + Math.PI / 2 // Face outward-ish
189189
   }
190190
 
191
-  function update(delta, elapsed, pond) {
191
+  // Helper to smoothly interpolate angles
192
+  function lerpAngle(from, to, t) {
193
+    let diff = to - from
194
+    while (diff > Math.PI) diff -= Math.PI * 2
195
+    while (diff < -Math.PI) diff += Math.PI * 2
196
+    return from + diff * t
197
+  }
198
+
199
+  function update(delta, elapsed, pond, doug) {
192200
     state.timer += delta
193201
 
202
+    // Calculate angle to face Doug
203
+    let angleToDoug = 0
204
+    if (doug) {
205
+      const dougPos = doug.getPosition()
206
+      const dx = dougPos.x - group.position.x
207
+      const dz = dougPos.z - group.position.z
208
+      angleToDoug = Math.atan2(dx, dz)
209
+    }
210
+
194211
     switch (state.mode) {
195212
       case 'waiting':
196213
         if (state.timer >= 60) {
@@ -211,6 +228,8 @@ export function createDonny(scene, gradientMap) {
211228
           state.timer = 0
212229
           group.visible = true
213230
           group.position.y = -2
231
+          // Start facing Doug
232
+          group.rotation.y = angleToDoug
214233
         }
215234
         break
216235
 
@@ -220,6 +239,12 @@ export function createDonny(scene, gradientMap) {
220239
         const easeOut = 1 - Math.pow(1 - emergeProgress, 3)
221240
         group.position.y = -2 + easeOut * 2.3 // Rise to 0.3 above water
222241
 
242
+        // Tilt upward as emerging (nose up!)
243
+        group.rotation.x = -0.3 * easeOut
244
+
245
+        // Slowly turn toward Doug - lugubrious, not laser tracking
246
+        group.rotation.y = lerpAngle(group.rotation.y, angleToDoug, delta * 0.3)
247
+
223248
         // Gentle rocking as emerging
224249
         group.rotation.z = Math.sin(state.timer * 4) * 0.1
225250
 
@@ -235,6 +260,10 @@ export function createDonny(scene, gradientMap) {
235260
         group.position.y = 0.3 + Math.sin(elapsed * 2) * 0.08
236261
         group.rotation.z = Math.sin(elapsed * 1.5) * 0.05
237262
 
263
+        // Keep tilted upward, slowly drifting gaze toward Doug
264
+        group.rotation.x = -0.25 + Math.sin(elapsed * 1.5) * 0.05
265
+        group.rotation.y = lerpAngle(group.rotation.y, angleToDoug, delta * 0.2)
266
+
238267
         // Gentle flipper animation
239268
         leftFlipper.rotation.z = 2.2 + Math.sin(elapsed * 3) * 0.15
240269
         rightFlipper.rotation.z = 2.2 + Math.sin(elapsed * 3 + 0.5) * 0.15
@@ -259,6 +288,9 @@ export function createDonny(scene, gradientMap) {
259288
         const easeIn = Math.pow(submergeProgress, 2)
260289
         group.position.y = 0.3 - easeIn * 2.5
261290
 
291
+        // Tilt nose down as submerging
292
+        group.rotation.x = -0.25 + easeIn * 0.4
293
+
262294
         // Add bubbles/ripples as submerging
263295
         if (Math.random() < delta * 4) {
264296
           pond.addRipple(
@@ -272,6 +304,7 @@ export function createDonny(scene, gradientMap) {
272304
           state.timer = 0
273305
           group.visible = false
274306
           group.position.y = -3
307
+          group.rotation.x = 0
275308
         }
276309
         break
277310
     }