zeroed-some/cob / 9d78b64

Browse files

turns out it was collision on one side

Authored by espadonne
SHA
9d78b646e628aba2700d4a06f83419ecc23bfb98
Parents
e0cda7f
Tree
8163911

2 changed files

StatusFile+-
M js/entities.js 621 575
M js/game.js 8 5
js/entities.jsmodified
1002 lines changed — click to load
@@ -2,18 +2,18 @@
22
 
33
 class Spider {
44
   constructor (x, y) {
5
-        this.pos = createVector(x, y);
6
-        this.vel = createVector(0, 0);
7
-        this.acc = createVector(0, 0);
8
-        this.radius = 8;
9
-        this.isAirborne = false;
10
-        this.canJump = true;
11
-        this.lastAnchorPoint = null;
12
-        this.gravity = createVector(0, 0.3);
13
-        this.jumpPower = 12;
14
-        this.maxSpeed = 15;
15
-        this.munchRadius = 20;
16
-        this.munchCooldown = 0;
5
+    this.pos = createVector(x, y)
6
+    this.vel = createVector(0, 0)
7
+    this.acc = createVector(0, 0)
8
+    this.radius = 8
9
+    this.isAirborne = false
10
+    this.canJump = true
11
+    this.lastAnchorPoint = null
12
+    this.gravity = createVector(0, 0.3)
13
+    this.jumpPower = 12
14
+    this.maxSpeed = 15
15
+    this.munchRadius = 20
16
+    this.munchCooldown = 0
1717
   }
1818
 
1919
 jump(targetX, targetY) {
@@ -76,102 +76,110 @@ jump(targetX, targetY) {
7676
     }
7777
     
7878
   munch () {
79
-        if (this.munchCooldown > 0) return;
79
+    if (this.munchCooldown > 0) return
8080
 
81
-        isMunching = true;
82
-        this.munchCooldown = 30;
81
+    isMunching = true
82
+    this.munchCooldown = 30
8383
 
8484
     for (let i = flies.length - 1; i >= 0; i--) {
85
-            let fly = flies[i];
86
-            let d = dist(this.pos.x, this.pos.y, fly.pos.x, fly.pos.y);
85
+      let fly = flies[i]
86
+      let d = dist(this.pos.x, this.pos.y, fly.pos.x, fly.pos.y)
8787
       if (d < this.munchRadius) {
88
-                fliesMunched++;
89
-                webSilk = min(webSilk + 15, maxWebSilk);
88
+        fliesMunched++
89
+        webSilk = min(webSilk + 15, maxWebSilk)
9090
 
9191
         for (let j = 0; j < 12; j++) {
92
-                    let p = new Particle(fly.pos.x, fly.pos.y);
93
-                    p.color = color(255, random(100, 255), 0);
94
-                    particles.push(p);
92
+          let p = new Particle(fly.pos.x, fly.pos.y)
93
+          p.color = color(255, random(100, 255), 0)
94
+          particles.push(p)
9595
         }
9696
 
97
-                flies.splice(i, 1);
98
-                break;
97
+        flies.splice(i, 1)
98
+        break
9999
       }
100100
     }
101101
   }
102102
 
103103
   update () {
104104
     if (this.isAirborne) {
105
-            this.acc.add(this.gravity);
105
+      this.acc.add(this.gravity)
106106
     }
107107
 
108
-        this.vel.add(this.acc);
109
-        this.vel.limit(this.maxSpeed);
110
-        this.pos.add(this.vel);
111
-        this.acc.mult(0);
108
+    this.vel.add(this.acc)
109
+    this.vel.limit(this.maxSpeed)
110
+    this.pos.add(this.vel)
111
+    this.acc.mult(0)
112112
 
113113
     if (this.munchCooldown > 0) {
114
-            this.munchCooldown--;
114
+      this.munchCooldown--
115115
       if (this.munchCooldown === 0) {
116
-                isMunching = false;
116
+        isMunching = false
117117
       }
118118
     }
119119
 
120120
     // Check ground collision
121121
     if (this.pos.y >= height - this.radius) {
122
-            this.pos.y = height - this.radius;
123
-            this.land();
122
+      this.pos.y = height - this.radius
123
+      this.land()
124124
     }
125125
 
126126
     // Check wall collisions
127127
     if (this.pos.x <= this.radius || this.pos.x >= width - this.radius) {
128
-            this.pos.x = constrain(this.pos.x, this.radius, width - this.radius);
129
-            this.vel.x *= -0.5;
128
+      this.pos.x = constrain(this.pos.x, this.radius, width - this.radius)
129
+      this.vel.x *= -0.5
130130
     }
131131
 
132132
     // Check ceiling
133133
     if (this.pos.y <= this.radius) {
134
-            this.pos.y = this.radius;
135
-            this.vel.y *= -0.5; // Bounce off ceiling, don't land
134
+      this.pos.y = this.radius
135
+      this.vel.y *= -0.5 // Bounce off ceiling, don't land
136136
     }
137137
 
138138
     // Check home branch collision (one-way platform)
139
-        if (window.homeBranch && this.isAirborne && this.vel.y > 0.1) { // Only when actually falling
140
-            let branch = window.homeBranch;
139
+    if (window.homeBranch && this.isAirborne && this.vel.y > 0.1) {
140
+      // Only when actually falling
141
+      let branch = window.homeBranch
141142
 
142143
       // Check if spider is within branch X range
143
-            let branchStart = Math.min(branch.startX, branch.endX);
144
-            let branchEnd = Math.max(branch.startX, branch.endX);
144
+      let branchStart = Math.min(branch.startX, branch.endX)
145
+      let branchEnd = Math.max(branch.startX, branch.endX)
145146
 
146147
       // Since the branch angle is very small (0.05 radians ≈ 3 degrees),
147148
       // we can use a simpler approximation
148149
       if (this.pos.x >= branchStart - 10 && this.pos.x <= branchEnd + 10) {
149150
         // Calculate position along branch (0 to 1)
150
-                let t = (this.pos.x - branchStart) / (branchEnd - branchStart);
151
-                t = constrain(t, 0, 1);
151
+        let t = (this.pos.x - branchStart) / (branchEnd - branchStart)
152
+        t = constrain(t, 0, 1)
152153
 
153154
         // Branch visual thickness tapers from full at start to 35% at end
154155
         // This matches exactly how it's drawn in the bezier curves
155
-                let branchTopThickness = lerp(branch.thickness * 0.9, branch.thickness * 0.35, t);
156
+        let branchTopThickness = lerp(
157
+          branch.thickness * 0.9,
158
+          branch.thickness * 0.35,
159
+          t
160
+        )
156161
 
157162
         // The branch is drawn centered at branch.y
158163
         // With small angle approximation: the top of the branch is at
159
-                let branchSurfaceY = branch.y - branchTopThickness;
164
+        let branchSurfaceY = branch.y - branchTopThickness
160165
 
161166
         // Add slight angle correction (for small angles, tan ≈ sin ≈ angle in radians)
162
-                let angleCorrection = (this.pos.x - branchStart) * branch.angle;
163
-                branchSurfaceY += angleCorrection;
167
+        let angleCorrection = (this.pos.x - branchStart) * branch.angle
168
+        branchSurfaceY += angleCorrection
164169
 
165170
         // Check if spider is crossing the branch from above
166
-                let prevY = this.pos.y - this.vel.y;
171
+        let prevY = this.pos.y - this.vel.y
167172
 
168
-                if (prevY <= branchSurfaceY && // Was above
173
+        if (
174
+          prevY <= branchSurfaceY && // Was above
169175
           this.pos.y + this.radius >= branchSurfaceY && // Now at or below
170
-                    this.pos.y < branch.y + branch.thickness) { // Not too far below
176
+          this.pos.y < branch.y + branch.thickness
177
+        ) {
178
+          // Not too far below
171179
 
172180
           // Place spider on the branch surface
173
-                    this.pos.y = branchSurfaceY - this.radius;
174
-                    this.land();
181
+          this.pos.y = branchSurfaceY - this.radius
182
+          this.land()
175183
         }
176184
       }
177185
     }
@@ -179,257 +187,289 @@ jump(targetX, targetY) {
179187
     // Check obstacle collisions
180188
     for (let obstacle of obstacles) {
181189
       if (this.checkObstacleCollision(obstacle)) {
182
-                this.landOnObstacle(obstacle);
190
+        this.landOnObstacle(obstacle)
183191
       }
184192
     }
185193
 
186194
     // Check web strand collisions
187195
     for (let strand of webStrands) {
188
-            if (strand === currentStrand) continue;
196
+      if (strand === currentStrand) continue
189197
 
190198
       if (this.isAirborne && this.checkStrandCollision(strand)) {
191
-                this.landOnStrand(strand);
199
+        this.landOnStrand(strand)
192200
       }
193201
     }
194202
 
195203
     // Check food box collisions
196204
     for (let i = foodBoxes.length - 1; i >= 0; i--) {
197
-            let box = foodBoxes[i];
198
-            if (dist(this.pos.x, this.pos.y, box.pos.x, box.pos.y) < this.radius + box.radius) {
199
-                box.collect();
200
-                foodBoxes.splice(i, 1);
205
+      let box = foodBoxes[i]
206
+      if (
207
+        dist(this.pos.x, this.pos.y, box.pos.x, box.pos.y) <
208
+        this.radius + box.radius
209
+      ) {
210
+        box.collect()
211
+        foodBoxes.splice(i, 1)
201212
       }
202213
     }
203214
   }
204215
 
205216
   checkObstacleCollision (obstacle) {
206
-        let d = dist(this.pos.x, this.pos.y, obstacle.x, obstacle.y);
207
-        return d < this.radius + obstacle.radius;
217
+    let d = dist(this.pos.x, this.pos.y, obstacle.x, obstacle.y)
218
+    return d < this.radius + obstacle.radius
208219
   }
209220
 
210221
   checkStrandCollision (strand) {
211
-        let d = this.pointToLineDistance(this.pos, strand.start, strand.end);
212
-        return d < this.radius + 2;
222
+    let d = this.pointToLineDistance(this.pos, strand.start, strand.end)
223
+    return d < this.radius + 2
213224
   }
214225
 
215226
   pointToLineDistance (point, lineStart, lineEnd) {
216
-        let line = p5.Vector.sub(lineEnd, lineStart);
217
-        let lineLength = line.mag();
218
-        line.normalize();
227
+    let line = p5.Vector.sub(lineEnd, lineStart)
228
+    let lineLength = line.mag()
229
+    line.normalize()
219230
 
220
-        let pointToStart = p5.Vector.sub(point, lineStart);
221
-        let projLength = constrain(pointToStart.dot(line), 0, lineLength);
231
+    let pointToStart = p5.Vector.sub(point, lineStart)
232
+    let projLength = constrain(pointToStart.dot(line), 0, lineLength)
222233
 
223
-        let closestPoint = p5.Vector.add(lineStart, p5.Vector.mult(line, projLength));
224
-        return p5.Vector.dist(point, closestPoint);
234
+    let closestPoint = p5.Vector.add(
235
+      lineStart,
236
+      p5.Vector.mult(line, projLength)
237
+    )
238
+    return p5.Vector.dist(point, closestPoint)
225239
   }
226240
 
227241
   landOnObstacle (obstacle) {
228
-        let angle = atan2(this.pos.y - obstacle.y, this.pos.x - obstacle.x);
229
-        this.pos.x = obstacle.x + cos(angle) * (obstacle.radius + this.radius);
230
-        this.pos.y = obstacle.y + sin(angle) * (obstacle.radius + this.radius);
231
-        this.land();
242
+    let angle = atan2(this.pos.y - obstacle.y, this.pos.x - obstacle.x)
243
+    this.pos.x = obstacle.x + cos(angle) * (obstacle.radius + this.radius)
244
+    this.pos.y = obstacle.y + sin(angle) * (obstacle.radius + this.radius)
245
+    this.land()
232246
   }
233247
 
234248
   landOnStrand (strand) {
235
-        let line = p5.Vector.sub(strand.end, strand.start);
236
-        let lineLength = line.mag();
237
-        line.normalize();
249
+    let line = p5.Vector.sub(strand.end, strand.start)
250
+    let lineLength = line.mag()
251
+    line.normalize()
238252
 
239
-        let pointToStart = p5.Vector.sub(this.pos, strand.start);
240
-        let projLength = constrain(pointToStart.dot(line), 0, lineLength);
253
+    let pointToStart = p5.Vector.sub(this.pos, strand.start)
254
+    let projLength = constrain(pointToStart.dot(line), 0, lineLength)
241255
 
242
-        let closestPoint = p5.Vector.add(strand.start, p5.Vector.mult(line, projLength));
243
-        this.pos = closestPoint;
244
-        this.land();
256
+    let closestPoint = p5.Vector.add(
257
+      strand.start,
258
+      p5.Vector.mult(line, projLength)
259
+    )
260
+    this.pos = closestPoint
261
+    this.land()
245262
   }
246263
 
247264
   land () {
248
-        this.vel.mult(0);
249
-        this.isAirborne = false;
250
-        this.canJump = true;
265
+    this.vel.mult(0)
266
+    this.isAirborne = false
267
+    this.canJump = true
251268
 
252269
     if (currentStrand && isDeployingWeb && spacePressed) {
253
-            currentStrand.end = this.pos.copy();
254
-            currentStrand.path.push(this.pos.copy());
255
-            webNodes.push(new WebNode(this.pos.x, this.pos.y));
270
+      currentStrand.end = this.pos.copy()
271
+      currentStrand.path.push(this.pos.copy())
272
+      webNodes.push(new WebNode(this.pos.x, this.pos.y))
256273
     }
257274
 
258
-        currentStrand = null;
259
-        isDeployingWeb = false;
275
+    currentStrand = null
276
+    isDeployingWeb = false
260277
   }
261278
 
262279
   display () {
263
-        push();
264
-        translate(this.pos.x, this.pos.y);
280
+    push()
281
+    translate(this.pos.x, this.pos.y)
265282
 
266283
     if (isMunching && this.munchCooldown > 15) {
267
-            push();
268
-            fill(255, 100, 100, 150);
269
-            noStroke();
270
-            let munchSize = 15 + sin(frameCount * 0.5) * 5;
271
-            arc(0, 0, munchSize, munchSize, 0, PI + HALF_PI, PIE);
272
-            pop();
284
+      push()
285
+      fill(255, 100, 100, 150)
286
+      noStroke()
287
+      let munchSize = 15 + sin(frameCount * 0.5) * 5
288
+      arc(0, 0, munchSize, munchSize, 0, PI + HALF_PI, PIE)
289
+      pop()
273290
     }
274291
 
275
-        fill(20);
276
-        stroke(0);
277
-        strokeWeight(1);
278
-        ellipse(0, 0, this.radius * 2);
292
+    fill(20)
293
+    stroke(0)
294
+    strokeWeight(1)
295
+    ellipse(0, 0, this.radius * 2)
279296
 
280
-        fill(40);
281
-        noStroke();
282
-        ellipse(0, -2, this.radius * 1.2, this.radius * 1.5);
297
+    fill(40)
298
+    noStroke()
299
+    ellipse(0, -2, this.radius * 1.2, this.radius * 1.5)
283300
 
284301
     if (gamePhase === 'NIGHT') {
285
-            fill(255, 100, 100);
302
+      fill(255, 100, 100)
286303
     } else {
287
-            fill(255, 0, 0);
304
+      fill(255, 0, 0)
288305
     }
289
-        ellipse(-3, -3, 3);
290
-        ellipse(3, -3, 3);
306
+    ellipse(-3, -3, 3)
307
+    ellipse(3, -3, 3)
291308
 
292
-        stroke(0);
293
-        strokeWeight(1.5);
309
+    stroke(0)
310
+    strokeWeight(1.5)
294311
     for (let i = 0; i < 4; i++) {
295
-            let angle = PI/6 + (i * PI/8);
296
-            line(0, 0, cos(angle) * 12, sin(angle) * 8);
297
-            line(0, 0, -cos(angle) * 12, sin(angle) * 8);
312
+      let angle = PI / 6 + (i * PI) / 8
313
+      line(0, 0, cos(angle) * 12, sin(angle) * 8)
314
+      line(0, 0, -cos(angle) * 12, sin(angle) * 8)
298315
     }
299316
 
300317
     if (webSilk < 20) {
301
-            fill(255, 100, 100, 150 + sin(frameCount * 0.2) * 50);
302
-            noStroke();
303
-            ellipse(0, -15, 8);
318
+      fill(255, 100, 100, 150 + sin(frameCount * 0.2) * 50)
319
+      noStroke()
320
+      ellipse(0, -15, 8)
304321
     }
305322
 
306
-        pop();
323
+    pop()
307324
   }
308325
 }
309326
 
310327
 class Fly {
311328
   constructor () {
312329
     if (random() < 0.5) {
313
-            this.pos = createVector(random() < 0.5 ? -20 : width + 20, random(50, height - 100));
330
+      this.pos = createVector(
331
+        random() < 0.5 ? -20 : width + 20,
332
+        random(50, height - 100)
333
+      )
314334
     } else {
315
-            this.pos = createVector(random(width), random() < 0.5 ? -20 : height + 20);
335
+      this.pos = createVector(random(width), random() < 0.5 ? -20 : height + 20)
316336
     }
317337
 
318
-        this.vel = createVector(random(-2, 2), random(-1, 1));
319
-        this.acc = createVector(0, 0);
320
-        this.radius = 4;
321
-        this.caught = false;
322
-        this.stuck = false;
323
-        this.wingPhase = random(TWO_PI);
324
-        this.wanderAngle = random(TWO_PI);
325
-        this.glowIntensity = random(150, 255);
326
-        this.touchedStrands = new Set();
327
-        this.slowedBy = new Set(); // Track which strands are slowing us
328
-        this.baseSpeed = 3;
329
-        this.currentSpeed = this.baseSpeed;
338
+    this.vel = createVector(random(-2, 2), random(-1, 1))
339
+    this.acc = createVector(0, 0)
340
+    this.radius = 4
341
+    this.caught = false
342
+    this.stuck = false
343
+    this.wingPhase = random(TWO_PI)
344
+    this.wanderAngle = random(TWO_PI)
345
+    this.glowIntensity = random(150, 255)
346
+    this.touchedStrands = new Set()
347
+    this.slowedBy = new Set() // Track which strands are slowing us
348
+    this.baseSpeed = 3
349
+    this.currentSpeed = this.baseSpeed
330350
   }
331351
 
332352
   update () {
333
-        if (this.stuck) return;
353
+    if (this.stuck) return
334354
 
335355
     if (this.caught) {
336
-            this.vel.mult(0.95);
356
+      this.vel.mult(0.95)
337357
       if (this.vel.mag() < 0.1) {
338
-                this.stuck = true;
339
-                fliesCaught++;
340
-                webSilk = min(webSilk + 5, maxWebSilk);
358
+        this.stuck = true
359
+        fliesCaught++
360
+        webSilk = min(webSilk + 5, maxWebSilk)
341361
       }
342
-            return;
362
+      return
343363
     }
344364
 
345
-        this.wanderAngle += random(-0.3, 0.3);
346
-        let wanderForce = createVector(cos(this.wanderAngle), sin(this.wanderAngle));
347
-        wanderForce.mult(0.1);
348
-        this.acc.add(wanderForce);
365
+    this.wanderAngle += random(-0.3, 0.3)
366
+    let wanderForce = createVector(cos(this.wanderAngle), sin(this.wanderAngle))
367
+    wanderForce.mult(0.1)
368
+    this.acc.add(wanderForce)
349369
 
350370
     // Apply current speed (which may be slowed)
351
-        this.vel.add(this.acc);
352
-        this.vel.limit(this.currentSpeed);
353
-        this.pos.add(this.vel);
354
-        this.acc.mult(0);
371
+    this.vel.add(this.acc)
372
+    this.vel.limit(this.currentSpeed)
373
+    this.pos.add(this.vel)
374
+    this.acc.mult(0)
355375
 
356
-        if (this.pos.x < -30) this.pos.x = width + 30;
357
-        if (this.pos.x > width + 30) this.pos.x = -30;
358
-        if (this.pos.y < -30) this.pos.y = height + 30;
359
-        if (this.pos.y > height + 30) this.pos.y = -30;
376
+    if (this.pos.x < -30) this.pos.x = width + 30
377
+    if (this.pos.x > width + 30) this.pos.x = -30
378
+    if (this.pos.y < -30) this.pos.y = height + 30
379
+    if (this.pos.y > height + 30) this.pos.y = -30
360380
 
361381
     // Check web collisions
362
-        this.checkWebCollisions();
382
+    this.checkWebCollisions()
363383
   }
364384
 
365385
   checkWebCollisions () {
366
-        let currentlyTouching = new Set();
386
+    let currentlyTouching = new Set()
367387
 
368388
     for (let strand of webStrands) {
369
-            let touching = false;
389
+      let touching = false
370390
 
371391
       // Check collision with strand path
372392
       if (strand.path && strand.path.length > 1) {
373393
         for (let i = 0; i < strand.path.length - 1; i++) {
374
-                    let p1 = strand.path[i];
375
-                    let p2 = strand.path[i + 1];
376
-                    let d = this.pointToLineDistance(this.pos, p1, p2);
394
+          let p1 = strand.path[i]
395
+          let p2 = strand.path[i + 1]
396
+          let d = this.pointToLineDistance(this.pos, p1, p2)
377397
           if (d < this.radius + 3) {
378
-                        touching = true;
379
-                        break;
398
+            touching = true
399
+            break
380400
           }
381401
         }
382402
       } else if (strand.start && strand.end) {
383403
         // Fallback for strands without path
384
-                let d = this.pointToLineDistance(this.pos, strand.start, strand.end);
404
+        let d = this.pointToLineDistance(this.pos, strand.start, strand.end)
385405
         if (d < this.radius + 3) {
386
-                    touching = true;
406
+          touching = true
387407
         }
388408
       }
389409
 
390410
       if (touching) {
391
-                currentlyTouching.add(strand);
411
+        currentlyTouching.add(strand)
392412
 
393413
         // If this is a new strand we're touching
394414
         if (!this.touchedStrands.has(strand)) {
395
-                    this.touchedStrands.add(strand);
415
+          this.touchedStrands.add(strand)
396416
 
397417
           // Vibrate the web when first touching
398
-                    strand.vibrate(3);
418
+          strand.vibrate(3)
399419
 
400420
           // First strand slows us down
401421
           if (this.touchedStrands.size === 1) {
402
-                        this.currentSpeed = this.baseSpeed * 0.4; // Slow to 40% speed
403
-                        this.slowedBy.add(strand);
422
+            this.currentSpeed = this.baseSpeed * 0.4 // Slow to 40% speed
423
+            this.slowedBy.add(strand)
404424
 
405425
             // Visual feedback - yellow particles for slowing
406426
             for (let j = 0; j < 3; j++) {
407
-                            let p = new Particle(this.pos.x, this.pos.y);
408
-                            p.color = color(255, 255, 0, 150);
409
-                            p.vel = createVector(random(-1, 1), random(-1, 1));
410
-                            p.size = 3;
411
-                            particles.push(p);
427
+              let p = new Particle(this.pos.x, this.pos.y)
428
+              p.color = color(255, 255, 0, 150)
429
+              p.vel = createVector(random(-1, 1), random(-1, 1))
430
+              p.size = 3
431
+              particles.push(p)
412432
             }
413433
           }
414434
           // Second strand catches us
415435
           else if (this.touchedStrands.size >= 2 && !this.caught) {
416
-                        this.caught = true;
417
-                        this.currentSpeed = 0;
436
+            this.caught = true
437
+            this.currentSpeed = 0
418438
 
419439
             // Stronger vibration when caught
420
-                        strand.vibrate(8);
440
+            strand.vibrate(8)
421441
 
422442
             // Also vibrate nearby strands
423443
             for (let otherStrand of webStrands) {
424444
               if (otherStrand !== strand) {
425445
                 for (let touchedStrand of this.touchedStrands) {
426
-                                    let d1 = dist(otherStrand.start.x, otherStrand.start.y, touchedStrand.start.x, touchedStrand.start.y);
427
-                                    let d2 = dist(otherStrand.start.x, otherStrand.start.y, touchedStrand.end.x, touchedStrand.end.y);
428
-                                    let d3 = dist(otherStrand.end.x, otherStrand.end.y, touchedStrand.start.x, touchedStrand.start.y);
429
-                                    let d4 = dist(otherStrand.end.x, otherStrand.end.y, touchedStrand.end.x, touchedStrand.end.y);
446
+                  let d1 = dist(
447
+                    otherStrand.start.x,
448
+                    otherStrand.start.y,
449
+                    touchedStrand.start.x,
450
+                    touchedStrand.start.y
451
+                  )
452
+                  let d2 = dist(
453
+                    otherStrand.start.x,
454
+                    otherStrand.start.y,
455
+                    touchedStrand.end.x,
456
+                    touchedStrand.end.y
457
+                  )
458
+                  let d3 = dist(
459
+                    otherStrand.end.x,
460
+                    otherStrand.end.y,
461
+                    touchedStrand.start.x,
462
+                    touchedStrand.start.y
463
+                  )
464
+                  let d4 = dist(
465
+                    otherStrand.end.x,
466
+                    otherStrand.end.y,
467
+                    touchedStrand.end.x,
468
+                    touchedStrand.end.y
469
+                  )
430470
                   if (min(d1, d2, d3, d4) < 50) {
431
-                                        otherStrand.vibrate(2);
432
-                                        break;
471
+                    otherStrand.vibrate(2)
472
+                    break
433473
                   }
434474
                 }
435475
               }
@@ -437,10 +477,10 @@ class Fly {
437477
 
438478
             // Create caught particles
439479
             for (let j = 0; j < 6; j++) {
440
-                            let p = new Particle(this.pos.x, this.pos.y);
441
-                            p.color = color(255, 200, 0, 200);
442
-                            p.vel = createVector(random(-2, 2), random(-2, 2));
443
-                            particles.push(p);
480
+              let p = new Particle(this.pos.x, this.pos.y)
481
+              p.color = color(255, 200, 0, 200)
482
+              p.vel = createVector(random(-2, 2), random(-2, 2))
483
+              particles.push(p)
444484
             }
445485
           }
446486
         }
@@ -449,243 +489,249 @@ class Fly {
449489
 
450490
     // If we're no longer touching strands we were slowed by, speed back up
451491
     if (this.slowedBy.size > 0 && currentlyTouching.size === 0) {
452
-            this.currentSpeed = this.baseSpeed;
453
-            this.slowedBy.clear();
492
+      this.currentSpeed = this.baseSpeed
493
+      this.slowedBy.clear()
454494
     }
455495
   }
456496
 
457497
   pointToLineDistance (point, lineStart, lineEnd) {
458
-        let line = p5.Vector.sub(lineEnd, lineStart);
459
-        let lineLength = line.mag();
460
-        line.normalize();
498
+    let line = p5.Vector.sub(lineEnd, lineStart)
499
+    let lineLength = line.mag()
500
+    line.normalize()
461501
 
462
-        let pointToStart = p5.Vector.sub(point, lineStart);
463
-        let projLength = constrain(pointToStart.dot(line), 0, lineLength);
502
+    let pointToStart = p5.Vector.sub(point, lineStart)
503
+    let projLength = constrain(pointToStart.dot(line), 0, lineLength)
464504
 
465
-        let closestPoint = p5.Vector.add(lineStart, p5.Vector.mult(line, projLength));
466
-        return p5.Vector.dist(point, closestPoint);
505
+    let closestPoint = p5.Vector.add(
506
+      lineStart,
507
+      p5.Vector.mult(line, projLength)
508
+    )
509
+    return p5.Vector.dist(point, closestPoint)
467510
   }
468511
 
469512
   display () {
470
-        push();
471
-        translate(this.pos.x, this.pos.y);
513
+    push()
514
+    translate(this.pos.x, this.pos.y)
472515
 
473516
     // Show slowdown effect
474517
     if (this.slowedBy.size > 0 && !this.caught) {
475
-            stroke(255, 255, 0, 100);
476
-            strokeWeight(1);
477
-            noFill();
478
-            ellipse(0, 0, 20);
518
+      stroke(255, 255, 0, 100)
519
+      strokeWeight(1)
520
+      noFill()
521
+      ellipse(0, 0, 20)
479522
     }
480523
 
481524
     if (gamePhase === 'NIGHT') {
482
-            noStroke();
483
-            fill(255, 255, 150, this.glowIntensity * 0.3);
484
-            ellipse(0, 0, 30);
485
-            fill(255, 255, 100, this.glowIntensity * 0.5);
486
-            ellipse(0, 0, 20);
525
+      noStroke()
526
+      fill(255, 255, 150, this.glowIntensity * 0.3)
527
+      ellipse(0, 0, 30)
528
+      fill(255, 255, 100, this.glowIntensity * 0.5)
529
+      ellipse(0, 0, 20)
487530
     }
488531
 
489
-        fill(30);
490
-        stroke(0);
491
-        strokeWeight(0.5);
492
-        ellipse(0, 0, this.radius * 2);
532
+    fill(30)
533
+    stroke(0)
534
+    strokeWeight(0.5)
535
+    ellipse(0, 0, this.radius * 2)
493536
 
494537
     if (!this.stuck) {
495
-            this.wingPhase += 0.5;
538
+      this.wingPhase += 0.5
496539
       // Wing animation slows down when slowed
497
-            let wingSpeed = this.slowedBy.size > 0 ? 0.25 : 0.5;
498
-            this.wingPhase += wingSpeed;
499
-            let wingSpread = sin(this.wingPhase) * 5;
540
+      let wingSpeed = this.slowedBy.size > 0 ? 0.25 : 0.5
541
+      this.wingPhase += wingSpeed
542
+      let wingSpread = sin(this.wingPhase) * 5
500543
 
501
-            fill(255, 255, 255, 150);
502
-            noStroke();
503
-            ellipse(-wingSpread, 0, 6, 4);
504
-            ellipse(wingSpread, 0, 6, 4);
544
+      fill(255, 255, 255, 150)
545
+      noStroke()
546
+      ellipse(-wingSpread, 0, 6, 4)
547
+      ellipse(wingSpread, 0, 6, 4)
505548
     }
506549
 
507550
     if (gamePhase === 'NIGHT') {
508
-            fill(255, 255, 100, this.glowIntensity);
509
-            noStroke();
510
-            ellipse(0, 2, 3);
551
+      fill(255, 255, 100, this.glowIntensity)
552
+      noStroke()
553
+      ellipse(0, 2, 3)
511554
     }
512555
 
513
-        pop();
556
+    pop()
514557
   }
515558
 }
516559
 
517560
 class Obstacle {
518561
   constructor (x, y, radius, type) {
519
-        this.x = x;
520
-        this.y = y;
521
-        this.radius = radius;
522
-        this.type = type || (random() < 0.5 ? 'branch' : 'leaf');
523
-        this.rotation = random(TWO_PI);
524
-        this.leafPoints = [];
562
+    this.x = x
563
+    this.y = y
564
+    this.radius = radius
565
+    this.type = type || (random() < 0.5 ? 'branch' : 'leaf')
566
+    this.rotation = random(TWO_PI)
567
+    this.leafPoints = []
525568
 
526569
     if (this.type === 'leaf') {
527
-            let numPoints = 8;
570
+      let numPoints = 8
528571
       for (let i = 0; i < numPoints; i++) {
529
-                let angle = (TWO_PI / numPoints) * i;
530
-                let r = radius * random(0.7, 1.2);
531
-                if (i === 0 || i === numPoints/2) r = radius * 1.3;
532
-                this.leafPoints.push({angle: angle, radius: r});
572
+        let angle = (TWO_PI / numPoints) * i
573
+        let r = radius * random(0.7, 1.2)
574
+        if (i === 0 || i === numPoints / 2) r = radius * 1.3
575
+        this.leafPoints.push({ angle: angle, radius: r })
533576
       }
534577
     }
535578
   }
536579
 
537580
   display () {
538
-        push();
539
-        translate(this.x, this.y);
540
-        rotate(this.rotation);
581
+    push()
582
+    translate(this.x, this.y)
583
+    rotate(this.rotation)
541584
 
542585
     if (this.type === 'branch') {
543586
       if (gamePhase === 'NIGHT') {
544
-                stroke(40, 20, 0);
545
-                fill(50, 25, 5);
587
+        stroke(40, 20, 0)
588
+        fill(50, 25, 5)
546589
       } else {
547
-                stroke(101, 67, 33);
548
-                fill(139, 90, 43);
590
+        stroke(101, 67, 33)
591
+        fill(139, 90, 43)
549592
       }
550
-            strokeWeight(3);
593
+      strokeWeight(3)
551594
 
552
-            push();
553
-            strokeWeight(this.radius / 3);
554
-            line(-this.radius, 0, this.radius, 0);
595
+      push()
596
+      strokeWeight(this.radius / 3)
597
+      line(-this.radius, 0, this.radius, 0)
555598
 
556
-            strokeWeight(2);
557
-            line(-this.radius/2, 0, -this.radius/2 - 10, -10);
558
-            line(this.radius/3, 0, this.radius/3 + 8, -8);
559
-            line(0, 0, 5, -15);
599
+      strokeWeight(2)
600
+      line(-this.radius / 2, 0, -this.radius / 2 - 10, -10)
601
+      line(this.radius / 3, 0, this.radius / 3 + 8, -8)
602
+      line(0, 0, 5, -15)
560603
 
561
-            stroke(80, 50, 20, 100);
562
-            strokeWeight(1);
604
+      stroke(80, 50, 20, 100)
605
+      strokeWeight(1)
563606
       for (let i = -this.radius; i < this.radius; i += 5) {
564
-                line(i, -2, i + 2, 2);
607
+        line(i, -2, i + 2, 2)
565608
       }
566
-            pop();
567
-            
568
-            noStroke();
569
-            fill(255, 255, 255, 30);
570
-            ellipse(0, 0, this.radius * 2);
609
+      pop()
571610
 
611
+      noStroke()
612
+      fill(255, 255, 255, 30)
613
+      ellipse(0, 0, this.radius * 2)
572614
     } else if (this.type === 'leaf') {
573615
       if (gamePhase === 'NIGHT') {
574
-                fill(20, 40, 20);
575
-                stroke(10, 20, 10);
616
+        fill(20, 40, 20)
617
+        stroke(10, 20, 10)
576618
       } else {
577
-                fill(34, 139, 34);
578
-                stroke(25, 100, 25);
619
+        fill(34, 139, 34)
620
+        stroke(25, 100, 25)
579621
       }
580
-            strokeWeight(2);
622
+      strokeWeight(2)
581623
 
582
-            beginShape();
624
+      beginShape()
583625
       for (let point of this.leafPoints) {
584
-                let x = cos(point.angle) * point.radius;
585
-                let y = sin(point.angle) * point.radius;
586
-                curveVertex(x, y);
626
+        let x = cos(point.angle) * point.radius
627
+        let y = sin(point.angle) * point.radius
628
+        curveVertex(x, y)
587629
       }
588
-            let firstPoint = this.leafPoints[0];
589
-            curveVertex(cos(firstPoint.angle) * firstPoint.radius, 
590
-                       sin(firstPoint.angle) * firstPoint.radius);
591
-            let secondPoint = this.leafPoints[1];
592
-            curveVertex(cos(secondPoint.angle) * secondPoint.radius, 
593
-                       sin(secondPoint.angle) * secondPoint.radius);
594
-            endShape();
630
+      let firstPoint = this.leafPoints[0]
631
+      curveVertex(
632
+        cos(firstPoint.angle) * firstPoint.radius,
633
+        sin(firstPoint.angle) * firstPoint.radius
634
+      )
635
+      let secondPoint = this.leafPoints[1]
636
+      curveVertex(
637
+        cos(secondPoint.angle) * secondPoint.radius,
638
+        sin(secondPoint.angle) * secondPoint.radius
639
+      )
640
+      endShape()
595641
 
596
-            stroke(25, 100, 25, 100);
597
-            strokeWeight(1);
598
-            line(0, -this.radius, 0, this.radius);
599
-            line(0, 0, -this.radius/2, -this.radius/2);
600
-            line(0, 0, this.radius/2, -this.radius/2);
601
-            line(0, 0, -this.radius/2, this.radius/2);
602
-            line(0, 0, this.radius/2, this.radius/2);
642
+      stroke(25, 100, 25, 100)
643
+      strokeWeight(1)
644
+      line(0, -this.radius, 0, this.radius)
645
+      line(0, 0, -this.radius / 2, -this.radius / 2)
646
+      line(0, 0, this.radius / 2, -this.radius / 2)
647
+      line(0, 0, -this.radius / 2, this.radius / 2)
648
+      line(0, 0, this.radius / 2, this.radius / 2)
603649
     }
604650
 
605
-        pop();
651
+    pop()
606652
   }
607653
 }
608654
 
609655
 class FoodBox {
610656
   constructor (x, y) {
611
-        this.pos = createVector(x, y);
612
-        this.radius = 10;
613
-        this.collected = false;
614
-        this.floatOffset = random(TWO_PI);
615
-        this.silkValue = random(20, 35);
616
-        this.glowPhase = random(TWO_PI);
657
+    this.pos = createVector(x, y)
658
+    this.radius = 10
659
+    this.collected = false
660
+    this.floatOffset = random(TWO_PI)
661
+    this.silkValue = random(20, 35)
662
+    this.glowPhase = random(TWO_PI)
617663
   }
618664
 
619665
   collect () {
620
-        webSilk = min(webSilk + this.silkValue, maxWebSilk);
666
+    webSilk = min(webSilk + this.silkValue, maxWebSilk)
621667
 
622668
     for (let i = 0; i < 8; i++) {
623
-            particles.push(new Particle(this.pos.x, this.pos.y));
669
+      particles.push(new Particle(this.pos.x, this.pos.y))
624670
     }
625671
   }
626672
 
627673
   display () {
628
-        push();
629
-        let floatY = sin(frameCount * 0.05 + this.floatOffset) * 3;
630
-        translate(this.pos.x, this.pos.y + floatY);
674
+    push()
675
+    let floatY = sin(frameCount * 0.05 + this.floatOffset) * 3
676
+    translate(this.pos.x, this.pos.y + floatY)
631677
 
632
-        let glowIntensity = 100 + sin(frameCount * 0.1 + this.glowPhase) * 50;
633
-        noStroke();
634
-        fill(255, 200, 100, glowIntensity * 0.3);
635
-        ellipse(0, 0, 40);
636
-        fill(255, 220, 150, glowIntensity * 0.5);
637
-        ellipse(0, 0, 25);
678
+    let glowIntensity = 100 + sin(frameCount * 0.1 + this.glowPhase) * 50
679
+    noStroke()
680
+    fill(255, 200, 100, glowIntensity * 0.3)
681
+    ellipse(0, 0, 40)
682
+    fill(255, 220, 150, glowIntensity * 0.5)
683
+    ellipse(0, 0, 25)
638684
 
639
-        rectMode(CENTER);
685
+    rectMode(CENTER)
640686
 
641
-        fill(0, 0, 0, 50);
642
-        rect(2, 2, this.radius * 2, this.radius * 1.8, 3);
687
+    fill(0, 0, 0, 50)
688
+    rect(2, 2, this.radius * 2, this.radius * 1.8, 3)
643689
 
644
-        fill(139, 69, 19);
645
-        stroke(100, 50, 0);
646
-        strokeWeight(1);
647
-        rect(0, 0, this.radius * 2, this.radius * 1.8, 3);
690
+    fill(139, 69, 19)
691
+    stroke(100, 50, 0)
692
+    strokeWeight(1)
693
+    rect(0, 0, this.radius * 2, this.radius * 1.8, 3)
648694
 
649
-        stroke(100, 50, 0);
650
-        strokeWeight(1);
651
-        line(-this.radius, 0, this.radius, 0);
652
-        line(0, -this.radius * 0.9, 0, this.radius * 0.9);
695
+    stroke(100, 50, 0)
696
+    strokeWeight(1)
697
+    line(-this.radius, 0, this.radius, 0)
698
+    line(0, -this.radius * 0.9, 0, this.radius * 0.9)
653699
 
654
-        noStroke();
655
-        fill(255, 200, 100);
656
-        ellipse(-5, -4, 4);
657
-        ellipse(5, -4, 3);
658
-        ellipse(-4, 5, 3);
659
-        ellipse(4, 4, 4);
700
+    noStroke()
701
+    fill(255, 200, 100)
702
+    ellipse(-5, -4, 4)
703
+    ellipse(5, -4, 3)
704
+    ellipse(-4, 5, 3)
705
+    ellipse(4, 4, 4)
660706
 
661
-        pop();
707
+    pop()
662708
   }
663709
 }
664710
 
665711
 class Particle {
666712
   constructor (x, y) {
667
-        this.pos = createVector(x, y);
668
-        this.vel = createVector(random(-3, 3), random(-5, -2));
669
-        this.lifetime = 255;
670
-        this.color = color(255, random(200, 255), random(100, 200));
671
-        this.size = 6;  // Default size
713
+    this.pos = createVector(x, y)
714
+    this.vel = createVector(random(-3, 3), random(-5, -2))
715
+    this.lifetime = 255
716
+    this.color = color(255, random(200, 255), random(100, 200))
717
+    this.size = 6 // Default size
672718
   }
673719
 
674720
   update () {
675
-        this.vel.y += 0.2;
676
-        this.pos.add(this.vel);
677
-        this.lifetime -= 8;
721
+    this.vel.y += 0.2
722
+    this.pos.add(this.vel)
723
+    this.lifetime -= 8
678724
   }
679725
 
680726
   display () {
681
-        push();
682
-        noStroke();
683
-        fill(red(this.color), green(this.color), blue(this.color), this.lifetime);
684
-        ellipse(this.pos.x, this.pos.y, this.size);
685
-        pop();
727
+    push()
728
+    noStroke()
729
+    fill(red(this.color), green(this.color), blue(this.color), this.lifetime)
730
+    ellipse(this.pos.x, this.pos.y, this.size)
731
+    pop()
686732
   }
687733
 
688734
   isDead () {
689
-        return this.lifetime <= 0;
735
+    return this.lifetime <= 0
690736
   }
691737
 }
js/game.jsmodified
@@ -90,15 +90,18 @@ function setup() {
9090
     // Place spider at the tip of the branch
9191
     let spiderStartX = branchEndX; // Place at the end/tip
9292
     
93
-    // At the tip (t=1), thickness is 35% of original
93
+    // The branch is drawn with a taper - at the tip it's 35% thickness
94
+    // The branch rendering uses push/translate/rotate, so we need to account for that
9495
     let branchTopThickness = homeBranchThickness * 0.35;
9596
     
96
-    // The branch is drawn centered at branch.y, so the top is at:
97
+    // The branch is drawn centered at branch.y after rotation
98
+    // Since the rotation is small, we can approximate
9799
     let branchSurfaceY = homeBranchY - branchTopThickness;
98100
     
99
-    // Add slight angle correction
100
-    let angleCorrection = (spiderStartX - branchStartX) * window.homeBranch.angle;
101
-    branchSurfaceY += angleCorrection;
101
+    // The branch rotates around (0, homeBranchY), so points further from origin rotate more
102
+    // For small angles: y_rotated ≈ y + x * sin(angle) ≈ y + x * angle
103
+    let rotationOffset = spiderStartX * window.homeBranch.angle;
104
+    branchSurfaceY += rotationOffset;
102105
     
103106
     // Place spider on top of the visual branch at the tip (8 is spider radius)
104107
     spider = new Spider(spiderStartX, branchSurfaceY - 8);