zeroed-some/cob / 3a2c3d0

Browse files

better handling web drift

Authored by espadonne
SHA
3a2c3d0ed38136c68e45c79b65aa84d422a9c9f0
Parents
5fa41f1
Tree
71a4e73

2 changed files

StatusFile+-
M js/entities.js 70 20
M js/game.js 61 32
js/entities.jsmodified
@@ -14,6 +14,7 @@ class Spider {
1414
     this.maxSpeed = 15
1515
     this.munchRadius = 20
1616
     this.munchCooldown = 0
17
+    this.attachedObstacle = null // Track which obstacle spider is on
1718
   }
1819
 
1920
   jump(targetX, targetY) {
@@ -101,8 +102,18 @@ class Spider {
101102
   }
102103
 
103104
   update () {
105
+    // If attached to a moving obstacle, move with it
106
+    if (this.attachedObstacle && !this.isAirborne) {
107
+      // Calculate angle from obstacle center to spider
108
+      let angle = atan2(this.pos.y - this.attachedObstacle.y, this.pos.x - this.attachedObstacle.x)
109
+      // Keep spider on the surface of the obstacle
110
+      this.pos.x = this.attachedObstacle.x + cos(angle) * (this.attachedObstacle.radius + this.radius)
111
+      this.pos.y = this.attachedObstacle.y + sin(angle) * (this.attachedObstacle.radius + this.radius)
112
+    }
113
+    
104114
     if (this.isAirborne) {
105115
       this.acc.add(this.gravity)
116
+      this.attachedObstacle = null // Clear attachment when jumping
106117
     }
107118
 
108119
     this.vel.add(this.acc)
@@ -121,6 +132,7 @@ class Spider {
121132
     if (this.pos.y >= height - this.radius) {
122133
       this.pos.y = height - this.radius
123134
       this.land()
135
+      this.attachedObstacle = null
124136
     }
125137
 
126138
     // Check wall collisions
@@ -180,6 +192,7 @@ class Spider {
180192
           // Place spider on the branch surface
181193
           this.pos.y = branchSurfaceY - this.radius
182194
           this.land()
195
+          this.attachedObstacle = null
183196
         }
184197
       }
185198
     }
@@ -242,6 +255,7 @@ class Spider {
242255
     let angle = atan2(this.pos.y - obstacle.y, this.pos.x - obstacle.x)
243256
     this.pos.x = obstacle.x + cos(angle) * (obstacle.radius + this.radius)
244257
     this.pos.y = obstacle.y + sin(angle) * (obstacle.radius + this.radius)
258
+    this.attachedObstacle = obstacle // Track which obstacle we're on
245259
     this.land()
246260
   }
247261
 
@@ -258,6 +272,7 @@ class Spider {
258272
       p5.Vector.mult(line, projLength)
259273
     )
260274
     this.pos = closestPoint
275
+    this.attachedObstacle = null // Not on an obstacle
261276
     this.land()
262277
   }
263278
 
@@ -822,7 +837,7 @@ class Obstacle {
822837
       pop()
823838
       
824839
     } else if (this.type === 'beetle') {
825
-      // Big beetle!
840
+      // Big floating beetle!
826841
       push()
827842
       rotate(this.rotation)
828843
       
@@ -831,18 +846,49 @@ class Obstacle {
831846
       fill(0, 0, 0, 40)
832847
       ellipse(3, 3, this.radius * 1.8, this.radius * 2.2)
833848
       
834
-      // Wings (if flying at night)
835
-      if (gamePhase === 'NIGHT') {
849
+      // Wings - always visible and flapping since they're floating
836850
       push()
837
-        fill(255, 255, 255, 100 + sin(this.wingPhase) * 50)
851
+      // Wing flap animation
852
+      let wingAngle = sin(this.wingPhase) * 0.3
853
+      let wingSpread = 15 + sin(this.wingPhase) * 10
854
+      
855
+      // Left wing
856
+      push()
857
+      translate(-this.radius * 0.4, 0)
858
+      rotate(-wingAngle)
859
+      fill(255, 255, 255, 120)
860
+      stroke(0, 0, 0, 100)
861
+      strokeWeight(0.5)
862
+      ellipse(-wingSpread * 0.7, 0, wingSpread * 1.2, 15)
863
+      // Wing details
838864
       noStroke()
839
-        let wingSpread = sin(this.wingPhase) * 15
840
-        ellipse(-wingSpread, 0, 20, 12)
841
-        ellipse(wingSpread, 0, 20, 12)
865
+      fill(200, 200, 200, 80)
866
+      ellipse(-wingSpread * 0.6, 0, wingSpread * 0.8, 10)
842867
       pop()
868
+      
869
+      // Right wing
870
+      push()
871
+      translate(this.radius * 0.4, 0)
872
+      rotate(wingAngle)
873
+      fill(255, 255, 255, 120)
874
+      stroke(0, 0, 0, 100)
875
+      strokeWeight(0.5)
876
+      ellipse(wingSpread * 0.7, 0, wingSpread * 1.2, 15)
877
+      // Wing details
878
+      noStroke()
879
+      fill(200, 200, 200, 80)
880
+      ellipse(wingSpread * 0.6, 0, wingSpread * 0.8, 10)
881
+      pop()
882
+      
883
+      // Extra glow at night
884
+      if (gamePhase === 'NIGHT') {
885
+        noStroke()
886
+        fill(255, 255, 200, 30 + sin(this.wingPhase * 2) * 20)
887
+        ellipse(0, 0, this.radius * 3, this.radius * 2)
843888
       }
889
+      pop()
844890
       
845
-      // Main beetle body
891
+      // Main beetle body (on top of wings)
846892
       fill(red(this.beetleColor), green(this.beetleColor), blue(this.beetleColor))
847893
       stroke(0)
848894
       strokeWeight(2)
@@ -865,26 +911,30 @@ class Obstacle {
865911
       ellipse(this.radius * 0.2, this.radius * 0.4, this.radius * 0.35)
866912
       ellipse(-this.radius * 0.25, this.radius * 0.3, this.radius * 0.25)
867913
       
868
-      // Legs
914
+      // No legs - they're flying!
915
+      // Just small leg stubs tucked under the body
869916
       stroke(0)
870
-      strokeWeight(2)
871
-      for (let i = 0; i < 3; i++) {
872
-        let legY = -this.radius * 0.3 + i * this.radius * 0.3
873
-        let legMove = sin(this.wingPhase * 2 + i) * 2
874
-        line(-this.radius * 0.8, legY, -this.radius * 1.2 + legMove, legY + 5)
875
-        line(this.radius * 0.8, legY, this.radius * 1.2 - legMove, legY + 5)
876
-      }
917
+      strokeWeight(1)
918
+      // Tiny tucked legs
919
+      line(-this.radius * 0.5, -this.radius * 0.2, -this.radius * 0.6, -this.radius * 0.1)
920
+      line(this.radius * 0.5, -this.radius * 0.2, this.radius * 0.6, -this.radius * 0.1)
921
+      line(-this.radius * 0.5, this.radius * 0.2, -this.radius * 0.6, this.radius * 0.1)
922
+      line(this.radius * 0.5, this.radius * 0.2, this.radius * 0.6, this.radius * 0.1)
877923
       
878924
       // Antennae
879925
       strokeWeight(1)
880926
       line(-3, -this.radius * 1.1, -8, -this.radius * 1.4)
881927
       line(3, -this.radius * 1.1, 8, -this.radius * 1.4)
882928
       
883
-      // Eyes
929
+      // Eyes (bigger and more prominent)
884930
       fill(255, 0, 0)
885931
       noStroke()
886
-      ellipse(-5, -this.radius * 0.7, 4)
887
-      ellipse(5, -this.radius * 0.7, 4)
932
+      ellipse(-5, -this.radius * 0.7, 5)
933
+      ellipse(5, -this.radius * 0.7, 5)
934
+      // Eye shine
935
+      fill(255, 150, 150)
936
+      ellipse(-4, -this.radius * 0.72, 2)
937
+      ellipse(6, -this.radius * 0.72, 2)
888938
       
889939
       pop()
890940
       
js/game.jsmodified
@@ -117,25 +117,25 @@ function setup() {
117117
         obstacles.push(new Obstacle(x, y, 20, 'leaf')); // Use leaf as invisible anchor
118118
     }
119119
     
120
-    // Create fewer, bigger, quirkier obstacles
121
-    let numObstacles = Math.floor((width * height) / 120000); // Much fewer
122
-    numObstacles = constrain(numObstacles, 8, 15);
120
+    // Create more obstacles for denser coverage
121
+    let numObstacles = Math.floor((width * height) / 60000); // More obstacles
122
+    numObstacles = constrain(numObstacles, 15, 25);
123123
     
124
-    // Create ant balloons (2-3)
125
-    let numBalloons = Math.floor(random(2, 4));
124
+    // Create ant balloons (4-6)
125
+    let numBalloons = Math.floor(random(4, 7));
126126
     for (let i = 0; i < numBalloons; i++) {
127127
         let attempts = 0;
128128
         let placed = false;
129129
         
130130
         while (!placed && attempts < 30) {
131
-            let x = random(120, width - 120);
132
-            let y = random(80, height * 0.5); // Balloons float in upper half
133
-            let radius = random(40, 55); // Bigger
131
+            let x = random(80, width - 80);
132
+            let y = random(60, height * 0.55); // Balloons float in upper half
133
+            let radius = random(35, 45); // Good size for hopping
134134
             
135135
             let valid = true;
136136
             // Check distance from other obstacles
137137
             for (let obstacle of obstacles) {
138
-                if (dist(x, y, obstacle.x, obstacle.y) < radius + obstacle.radius + 80) {
138
+                if (dist(x, y, obstacle.x, obstacle.y) < radius + obstacle.radius + 50) {
139139
                     valid = false;
140140
                     break;
141141
                 }
@@ -144,7 +144,7 @@ function setup() {
144144
             // Check distance from home branch
145145
             if (valid && window.homeBranch) {
146146
                 let branchY = window.homeBranch.y;
147
-                if (Math.abs(y - branchY) < radius + 50) {
147
+                if (Math.abs(y - branchY) < radius + 35) {
148148
                     valid = false;
149149
                 }
150150
             }
@@ -157,20 +157,20 @@ function setup() {
157157
         }
158158
     }
159159
     
160
-    // Create beetles (2-3)
161
-    let numBeetles = Math.floor(random(2, 4));
160
+    // Create beetles (3-5)
161
+    let numBeetles = Math.floor(random(3, 6));
162162
     for (let i = 0; i < numBeetles; i++) {
163163
         let attempts = 0;
164164
         let placed = false;
165165
         
166166
         while (!placed && attempts < 30) {
167
-            let x = random(100, width - 100);
168
-            let y = random(height * 0.3, height * 0.7); // Middle areas
169
-            let radius = random(35, 50);
167
+            let x = random(70, width - 70);
168
+            let y = random(height * 0.2, height * 0.8); // Spread throughout middle/lower
169
+            let radius = random(30, 40);
170170
             
171171
             let valid = true;
172172
             for (let obstacle of obstacles) {
173
-                if (dist(x, y, obstacle.x, obstacle.y) < radius + obstacle.radius + 70) {
173
+                if (dist(x, y, obstacle.x, obstacle.y) < radius + obstacle.radius + 45) {
174174
                     valid = false;
175175
                     break;
176176
                 }
@@ -179,7 +179,7 @@ function setup() {
179179
             // Check distance from home branch
180180
             if (valid && window.homeBranch) {
181181
                 let branchY = window.homeBranch.y;
182
-                if (Math.abs(y - branchY) < radius + 40) {
182
+                if (Math.abs(y - branchY) < radius + 30) {
183183
                     valid = false;
184184
                 }
185185
             }
@@ -192,20 +192,23 @@ function setup() {
192192
         }
193193
     }
194194
     
195
-    // Create leaves (3-4) for more stable anchor points
196
-    let numLeaves = Math.floor(random(3, 5));
195
+    // Create LOTS of leaves (8-12) for excellent hopping coverage
196
+    let numLeaves = Math.floor(random(8, 13));
197197
     for (let i = 0; i < numLeaves; i++) {
198198
         let attempts = 0;
199199
         let placed = false;
200200
         
201201
         while (!placed && attempts < 30) {
202
-            let x = random(80, width - 80);
203
-            let y = random(100, height - 150);
204
-            let radius = random(30, 40);
202
+            // Distribute leaves more evenly across the screen
203
+            let gridX = (i % 4) * (width / 4) + random(50, width/4 - 50);
204
+            let gridY = Math.floor(i / 4) * (height / 3) + random(50, height/3 - 50);
205
+            let x = constrain(gridX, 50, width - 50);
206
+            let y = constrain(gridY, 60, height - 100);
207
+            let radius = random(20, 30);
205208
             
206209
             let valid = true;
207210
             for (let obstacle of obstacles) {
208
-                if (dist(x, y, obstacle.x, obstacle.y) < radius + obstacle.radius + 60) {
211
+                if (dist(x, y, obstacle.x, obstacle.y) < radius + obstacle.radius + 35) {
209212
                     valid = false;
210213
                     break;
211214
                 }
@@ -219,15 +222,41 @@ function setup() {
219222
         }
220223
     }
221224
     
222
-    // Add guaranteed edge anchor points (smaller, stable leaves)
223
-    obstacles.push(new Obstacle(50, height/2, 25, 'leaf'));
224
-    obstacles.push(new Obstacle(width - 50, height/2, 25, 'leaf'));
225
-    obstacles.push(new Obstacle(width/2, 60, 25, 'leaf'));
226
-    
227
-    // Bottom anchors for better coverage
228
-    if (width > 1000) {
229
-        obstacles.push(new Obstacle(width/3, height - 130, 25, 'leaf'));
230
-        obstacles.push(new Obstacle(2*width/3, height - 130, 25, 'leaf'));
225
+    // Add even more guaranteed coverage points (smaller leaves)
226
+    // Corners
227
+    obstacles.push(new Obstacle(50, 80, 18, 'leaf'));
228
+    obstacles.push(new Obstacle(width - 50, 80, 18, 'leaf'));
229
+    obstacles.push(new Obstacle(50, height - 100, 18, 'leaf'));
230
+    obstacles.push(new Obstacle(width - 50, height - 100, 18, 'leaf'));
231
+    
232
+    // Edge midpoints
233
+    obstacles.push(new Obstacle(35, height/3, 18, 'leaf'));
234
+    obstacles.push(new Obstacle(35, 2*height/3, 18, 'leaf'));
235
+    obstacles.push(new Obstacle(width - 35, height/3, 18, 'leaf'));
236
+    obstacles.push(new Obstacle(width - 35, 2*height/3, 18, 'leaf'));
237
+    obstacles.push(new Obstacle(width/3, 45, 18, 'leaf'));
238
+    obstacles.push(new Obstacle(2*width/3, 45, 18, 'leaf'));
239
+    obstacles.push(new Obstacle(width/3, height - 90, 18, 'leaf'));
240
+    obstacles.push(new Obstacle(2*width/3, height - 90, 18, 'leaf'));
241
+    
242
+    // Fill any remaining gaps for smooth hopping
243
+    if (width > 600) {
244
+        // Create a grid of small leaves to ensure no dead zones
245
+        for (let x = width/5; x < width; x += width/5) {
246
+            for (let y = height/4; y < height - 100; y += height/4) {
247
+                // Check if there's already an obstacle nearby
248
+                let needsLeaf = true;
249
+                for (let obstacle of obstacles) {
250
+                    if (dist(x, y, obstacle.x, obstacle.y) < 80) {
251
+                        needsLeaf = false;
252
+                        break;
253
+                    }
254
+                }
255
+                if (needsLeaf) {
256
+                    obstacles.push(new Obstacle(x + random(-20, 20), y + random(-20, 20), 15, 'leaf'));
257
+                }
258
+            }
259
+        }
231260
     }
232261
     
233262
     // Spawn initial food boxes