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 {
14
     this.maxSpeed = 15
14
     this.maxSpeed = 15
15
     this.munchRadius = 20
15
     this.munchRadius = 20
16
     this.munchCooldown = 0
16
     this.munchCooldown = 0
17
+    this.attachedObstacle = null // Track which obstacle spider is on
17
   }
18
   }
18
 
19
 
19
   jump(targetX, targetY) {
20
   jump(targetX, targetY) {
@@ -101,8 +102,18 @@ class Spider {
101
   }
102
   }
102
 
103
 
103
   update () {
104
   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
+    
104
     if (this.isAirborne) {
114
     if (this.isAirborne) {
105
       this.acc.add(this.gravity)
115
       this.acc.add(this.gravity)
116
+      this.attachedObstacle = null // Clear attachment when jumping
106
     }
117
     }
107
 
118
 
108
     this.vel.add(this.acc)
119
     this.vel.add(this.acc)
@@ -121,6 +132,7 @@ class Spider {
121
     if (this.pos.y >= height - this.radius) {
132
     if (this.pos.y >= height - this.radius) {
122
       this.pos.y = height - this.radius
133
       this.pos.y = height - this.radius
123
       this.land()
134
       this.land()
135
+      this.attachedObstacle = null
124
     }
136
     }
125
 
137
 
126
     // Check wall collisions
138
     // Check wall collisions
@@ -180,6 +192,7 @@ class Spider {
180
           // Place spider on the branch surface
192
           // Place spider on the branch surface
181
           this.pos.y = branchSurfaceY - this.radius
193
           this.pos.y = branchSurfaceY - this.radius
182
           this.land()
194
           this.land()
195
+          this.attachedObstacle = null
183
         }
196
         }
184
       }
197
       }
185
     }
198
     }
@@ -242,6 +255,7 @@ class Spider {
242
     let angle = atan2(this.pos.y - obstacle.y, this.pos.x - obstacle.x)
255
     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)
256
     this.pos.x = obstacle.x + cos(angle) * (obstacle.radius + this.radius)
244
     this.pos.y = obstacle.y + sin(angle) * (obstacle.radius + this.radius)
257
     this.pos.y = obstacle.y + sin(angle) * (obstacle.radius + this.radius)
258
+    this.attachedObstacle = obstacle // Track which obstacle we're on
245
     this.land()
259
     this.land()
246
   }
260
   }
247
 
261
 
@@ -258,6 +272,7 @@ class Spider {
258
       p5.Vector.mult(line, projLength)
272
       p5.Vector.mult(line, projLength)
259
     )
273
     )
260
     this.pos = closestPoint
274
     this.pos = closestPoint
275
+    this.attachedObstacle = null // Not on an obstacle
261
     this.land()
276
     this.land()
262
   }
277
   }
263
 
278
 
@@ -822,7 +837,7 @@ class Obstacle {
822
       pop()
837
       pop()
823
       
838
       
824
     } else if (this.type === 'beetle') {
839
     } else if (this.type === 'beetle') {
825
-      // Big beetle!
840
+      // Big floating beetle!
826
       push()
841
       push()
827
       rotate(this.rotation)
842
       rotate(this.rotation)
828
       
843
       
@@ -831,18 +846,49 @@ class Obstacle {
831
       fill(0, 0, 0, 40)
846
       fill(0, 0, 0, 40)
832
       ellipse(3, 3, this.radius * 1.8, this.radius * 2.2)
847
       ellipse(3, 3, this.radius * 1.8, this.radius * 2.2)
833
       
848
       
834
-      // Wings (if flying at night)
849
+      // Wings - always visible and flapping since they're floating
850
+      push()
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
864
+      noStroke()
865
+      fill(200, 200, 200, 80)
866
+      ellipse(-wingSpread * 0.6, 0, wingSpread * 0.8, 10)
867
+      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
835
       if (gamePhase === 'NIGHT') {
884
       if (gamePhase === 'NIGHT') {
836
-        push()
837
-        fill(255, 255, 255, 100 + sin(this.wingPhase) * 50)
838
         noStroke()
885
         noStroke()
839
-        let wingSpread = sin(this.wingPhase) * 15
886
+        fill(255, 255, 200, 30 + sin(this.wingPhase * 2) * 20)
840
-        ellipse(-wingSpread, 0, 20, 12)
887
+        ellipse(0, 0, this.radius * 3, this.radius * 2)
841
-        ellipse(wingSpread, 0, 20, 12)
842
-        pop()
843
       }
888
       }
889
+      pop()
844
       
890
       
845
-      // Main beetle body
891
+      // Main beetle body (on top of wings)
846
       fill(red(this.beetleColor), green(this.beetleColor), blue(this.beetleColor))
892
       fill(red(this.beetleColor), green(this.beetleColor), blue(this.beetleColor))
847
       stroke(0)
893
       stroke(0)
848
       strokeWeight(2)
894
       strokeWeight(2)
@@ -865,26 +911,30 @@ class Obstacle {
865
       ellipse(this.radius * 0.2, this.radius * 0.4, this.radius * 0.35)
911
       ellipse(this.radius * 0.2, this.radius * 0.4, this.radius * 0.35)
866
       ellipse(-this.radius * 0.25, this.radius * 0.3, this.radius * 0.25)
912
       ellipse(-this.radius * 0.25, this.radius * 0.3, this.radius * 0.25)
867
       
913
       
868
-      // Legs
914
+      // No legs - they're flying!
915
+      // Just small leg stubs tucked under the body
869
       stroke(0)
916
       stroke(0)
870
-      strokeWeight(2)
917
+      strokeWeight(1)
871
-      for (let i = 0; i < 3; i++) {
918
+      // Tiny tucked legs
872
-        let legY = -this.radius * 0.3 + i * this.radius * 0.3
919
+      line(-this.radius * 0.5, -this.radius * 0.2, -this.radius * 0.6, -this.radius * 0.1)
873
-        let legMove = sin(this.wingPhase * 2 + i) * 2
920
+      line(this.radius * 0.5, -this.radius * 0.2, this.radius * 0.6, -this.radius * 0.1)
874
-        line(-this.radius * 0.8, legY, -this.radius * 1.2 + legMove, legY + 5)
921
+      line(-this.radius * 0.5, this.radius * 0.2, -this.radius * 0.6, this.radius * 0.1)
875
-        line(this.radius * 0.8, legY, this.radius * 1.2 - legMove, legY + 5)
922
+      line(this.radius * 0.5, this.radius * 0.2, this.radius * 0.6, this.radius * 0.1)
876
-      }
877
       
923
       
878
       // Antennae
924
       // Antennae
879
       strokeWeight(1)
925
       strokeWeight(1)
880
       line(-3, -this.radius * 1.1, -8, -this.radius * 1.4)
926
       line(-3, -this.radius * 1.1, -8, -this.radius * 1.4)
881
       line(3, -this.radius * 1.1, 8, -this.radius * 1.4)
927
       line(3, -this.radius * 1.1, 8, -this.radius * 1.4)
882
       
928
       
883
-      // Eyes
929
+      // Eyes (bigger and more prominent)
884
       fill(255, 0, 0)
930
       fill(255, 0, 0)
885
       noStroke()
931
       noStroke()
886
-      ellipse(-5, -this.radius * 0.7, 4)
932
+      ellipse(-5, -this.radius * 0.7, 5)
887
-      ellipse(5, -this.radius * 0.7, 4)
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)
888
       
938
       
889
       pop()
939
       pop()
890
       
940
       
js/game.jsmodified
@@ -117,25 +117,25 @@ function setup() {
117
         obstacles.push(new Obstacle(x, y, 20, 'leaf')); // Use leaf as invisible anchor
117
         obstacles.push(new Obstacle(x, y, 20, 'leaf')); // Use leaf as invisible anchor
118
     }
118
     }
119
     
119
     
120
-    // Create fewer, bigger, quirkier obstacles
120
+    // Create more obstacles for denser coverage
121
-    let numObstacles = Math.floor((width * height) / 120000); // Much fewer
121
+    let numObstacles = Math.floor((width * height) / 60000); // More obstacles
122
-    numObstacles = constrain(numObstacles, 8, 15);
122
+    numObstacles = constrain(numObstacles, 15, 25);
123
     
123
     
124
-    // Create ant balloons (2-3)
124
+    // Create ant balloons (4-6)
125
-    let numBalloons = Math.floor(random(2, 4));
125
+    let numBalloons = Math.floor(random(4, 7));
126
     for (let i = 0; i < numBalloons; i++) {
126
     for (let i = 0; i < numBalloons; i++) {
127
         let attempts = 0;
127
         let attempts = 0;
128
         let placed = false;
128
         let placed = false;
129
         
129
         
130
         while (!placed && attempts < 30) {
130
         while (!placed && attempts < 30) {
131
-            let x = random(120, width - 120);
131
+            let x = random(80, width - 80);
132
-            let y = random(80, height * 0.5); // Balloons float in upper half
132
+            let y = random(60, height * 0.55); // Balloons float in upper half
133
-            let radius = random(40, 55); // Bigger
133
+            let radius = random(35, 45); // Good size for hopping
134
             
134
             
135
             let valid = true;
135
             let valid = true;
136
             // Check distance from other obstacles
136
             // Check distance from other obstacles
137
             for (let obstacle of obstacles) {
137
             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) {
139
                     valid = false;
139
                     valid = false;
140
                     break;
140
                     break;
141
                 }
141
                 }
@@ -144,7 +144,7 @@ function setup() {
144
             // Check distance from home branch
144
             // Check distance from home branch
145
             if (valid && window.homeBranch) {
145
             if (valid && window.homeBranch) {
146
                 let branchY = window.homeBranch.y;
146
                 let branchY = window.homeBranch.y;
147
-                if (Math.abs(y - branchY) < radius + 50) {
147
+                if (Math.abs(y - branchY) < radius + 35) {
148
                     valid = false;
148
                     valid = false;
149
                 }
149
                 }
150
             }
150
             }
@@ -157,20 +157,20 @@ function setup() {
157
         }
157
         }
158
     }
158
     }
159
     
159
     
160
-    // Create beetles (2-3)
160
+    // Create beetles (3-5)
161
-    let numBeetles = Math.floor(random(2, 4));
161
+    let numBeetles = Math.floor(random(3, 6));
162
     for (let i = 0; i < numBeetles; i++) {
162
     for (let i = 0; i < numBeetles; i++) {
163
         let attempts = 0;
163
         let attempts = 0;
164
         let placed = false;
164
         let placed = false;
165
         
165
         
166
         while (!placed && attempts < 30) {
166
         while (!placed && attempts < 30) {
167
-            let x = random(100, width - 100);
167
+            let x = random(70, width - 70);
168
-            let y = random(height * 0.3, height * 0.7); // Middle areas
168
+            let y = random(height * 0.2, height * 0.8); // Spread throughout middle/lower
169
-            let radius = random(35, 50);
169
+            let radius = random(30, 40);
170
             
170
             
171
             let valid = true;
171
             let valid = true;
172
             for (let obstacle of obstacles) {
172
             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) {
174
                     valid = false;
174
                     valid = false;
175
                     break;
175
                     break;
176
                 }
176
                 }
@@ -179,7 +179,7 @@ function setup() {
179
             // Check distance from home branch
179
             // Check distance from home branch
180
             if (valid && window.homeBranch) {
180
             if (valid && window.homeBranch) {
181
                 let branchY = window.homeBranch.y;
181
                 let branchY = window.homeBranch.y;
182
-                if (Math.abs(y - branchY) < radius + 40) {
182
+                if (Math.abs(y - branchY) < radius + 30) {
183
                     valid = false;
183
                     valid = false;
184
                 }
184
                 }
185
             }
185
             }
@@ -192,20 +192,23 @@ function setup() {
192
         }
192
         }
193
     }
193
     }
194
     
194
     
195
-    // Create leaves (3-4) for more stable anchor points
195
+    // Create LOTS of leaves (8-12) for excellent hopping coverage
196
-    let numLeaves = Math.floor(random(3, 5));
196
+    let numLeaves = Math.floor(random(8, 13));
197
     for (let i = 0; i < numLeaves; i++) {
197
     for (let i = 0; i < numLeaves; i++) {
198
         let attempts = 0;
198
         let attempts = 0;
199
         let placed = false;
199
         let placed = false;
200
         
200
         
201
         while (!placed && attempts < 30) {
201
         while (!placed && attempts < 30) {
202
-            let x = random(80, width - 80);
202
+            // Distribute leaves more evenly across the screen
203
-            let y = random(100, height - 150);
203
+            let gridX = (i % 4) * (width / 4) + random(50, width/4 - 50);
204
-            let radius = random(30, 40);
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);
205
             
208
             
206
             let valid = true;
209
             let valid = true;
207
             for (let obstacle of obstacles) {
210
             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) {
209
                     valid = false;
212
                     valid = false;
210
                     break;
213
                     break;
211
                 }
214
                 }
@@ -219,15 +222,41 @@ function setup() {
219
         }
222
         }
220
     }
223
     }
221
     
224
     
222
-    // Add guaranteed edge anchor points (smaller, stable leaves)
225
+    // Add even more guaranteed coverage points (smaller leaves)
223
-    obstacles.push(new Obstacle(50, height/2, 25, 'leaf'));
226
+    // Corners
224
-    obstacles.push(new Obstacle(width - 50, height/2, 25, 'leaf'));
227
+    obstacles.push(new Obstacle(50, 80, 18, 'leaf'));
225
-    obstacles.push(new Obstacle(width/2, 60, 25, 'leaf'));
228
+    obstacles.push(new Obstacle(width - 50, 80, 18, 'leaf'));
226
-    
229
+    obstacles.push(new Obstacle(50, height - 100, 18, 'leaf'));
227
-    // Bottom anchors for better coverage
230
+    obstacles.push(new Obstacle(width - 50, height - 100, 18, 'leaf'));
228
-    if (width > 1000) {
231
+    
229
-        obstacles.push(new Obstacle(width/3, height - 130, 25, 'leaf'));
232
+    // Edge midpoints
230
-        obstacles.push(new Obstacle(2*width/3, height - 130, 25, 'leaf'));
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
+        }
231
     }
260
     }
232
     
261
     
233
     // Spawn initial food boxes
262
     // Spawn initial food boxes