zeroed-some/cob / 3dd0bf8

Browse files

web physics?

Authored by espadonne
SHA
3dd0bf8cafc6dcb26fe8e448a840c00d0ad76c00
Parents
86f4d57
Tree
4bc36f9

1 changed file

StatusFile+-
M js/physics.js 88 3
js/physics.jsmodified
@@ -7,11 +7,51 @@ class WebStrand {
77
         this.strength = 1;
88
         this.vibration = 0;
99
         this.path = [];
10
+        this.segments = []; // For physics simulation
11
+        this.maxLength = 200; // Maximum strand length before it breaks
12
+        this.tension = 0;
13
+        this.broken = false;
1014
     }
1115
 
1216
     update() {
1317
         this.vibration *= 0.95;
1418
         
19
+        // Calculate strand length and tension
20
+        if (this.end) {
21
+            let length = dist(this.start.x, this.start.y, this.end.x, this.end.y);
22
+            this.tension = length / this.maxLength;
23
+            
24
+            // Break if overstretched or unsupported arc
25
+            if (this.tension > 1.5 || this.checkUnsupportedArc()) {
26
+                this.broken = true;
27
+            }
28
+        }
29
+        
30
+        // Apply gravity to path points for realistic sagging
31
+        if (this.path && this.path.length > 2 && !this.broken) {
32
+            for (let i = 1; i < this.path.length - 1; i++) {
33
+                // Don't move the anchor points
34
+                let point = this.path[i];
35
+                
36
+                // Check if this point is supported by anything
37
+                let supported = false;
38
+                for (let obstacle of obstacles) {
39
+                    if (dist(point.x, point.y, obstacle.x, obstacle.y) < obstacle.radius + 5) {
40
+                        supported = true;
41
+                        break;
42
+                    }
43
+                }
44
+                
45
+                // Apply gravity if not supported
46
+                if (!supported) {
47
+                    point.y += 0.3; // Gravity effect
48
+                    
49
+                    // Add slight pendulum motion
50
+                    point.x += sin(frameCount * 0.02 + i) * 0.1;
51
+                }
52
+            }
53
+        }
54
+        
1555
         for (let node of webNodes) {
1656
             if (dist(node.x, node.y, this.start.x, this.start.y) < 5 ||
1757
                 dist(node.x, node.y, this.end.x, this.end.y) < 5) {
@@ -19,18 +59,57 @@ class WebStrand {
1959
             }
2060
         }
2161
     }
62
+    
63
+    checkUnsupportedArc() {
64
+        if (!this.path || this.path.length < 3) return false;
65
+        
66
+        // Check if the web forms an unsupported arc (both ends lower than middle)
67
+        let startY = this.start.y;
68
+        let endY = this.end ? this.end.y : this.path[this.path.length - 1].y;
69
+        let lowestPoint = startY;
70
+        let highestPoint = startY;
71
+        
72
+        for (let point of this.path) {
73
+            if (point.y > lowestPoint) lowestPoint = point.y;
74
+            if (point.y < highestPoint) highestPoint = point.y;
75
+        }
76
+        
77
+        // If the arc goes up significantly and both ends are near bottom, it's unsupported
78
+        let arcHeight = lowestPoint - highestPoint;
79
+        let bothEndsLow = startY > height - 200 && endY > height - 200;
80
+        let significantArc = arcHeight > 100;
81
+        
82
+        // Check if there's any support in the middle
83
+        let hasMiddleSupport = false;
84
+        for (let i = Math.floor(this.path.length * 0.3); i < Math.floor(this.path.length * 0.7); i++) {
85
+            let point = this.path[i];
86
+            for (let obstacle of obstacles) {
87
+                if (dist(point.x, point.y, obstacle.x, obstacle.y) < obstacle.radius + 10) {
88
+                    hasMiddleSupport = true;
89
+                    break;
90
+                }
91
+            }
92
+            if (hasMiddleSupport) break;
93
+        }
94
+        
95
+        return bothEndsLow && significantArc && !hasMiddleSupport;
96
+    }
2297
 
2398
     display() {
99
+        if (this.broken) return; // Don't display broken strands
100
+        
24101
         push();
25102
         
26
-        if (gamePhase === 'NIGHT') {
103
+        // Change color based on tension
104
+        if (this.tension > 0.8) {
105
+            stroke(255, 200, 200, 200); // Reddish when strained
106
+        } else if (gamePhase === 'NIGHT') {
27107
             stroke(255, 255, 255, 250);
28
-            strokeWeight(2);
29108
         } else {
30109
             stroke(255, 255, 255, 200);
31
-            strokeWeight(1.5);
32110
         }
33111
         
112
+        strokeWeight(gamePhase === 'NIGHT' ? 2 : 1.5);
34113
         noFill();
35114
         
36115
         if (this.path && this.path.length > 2) {
@@ -60,6 +139,11 @@ class WebStrand {
60139
             let midX = (this.start.x + this.end.x) / 2;
61140
             let midY = (this.start.y + this.end.y) / 2 + this.vibration * sin(frameCount * 0.3);
62141
             
142
+            // Add sag based on horizontal distance
143
+            let horizontalDist = abs(this.end.x - this.start.x);
144
+            let sag = horizontalDist * 0.1; // More sag for longer horizontal spans
145
+            midY += sag;
146
+            
63147
             beginShape();
64148
             curveVertex(this.start.x, this.start.y);
65149
             curveVertex(this.start.x, this.start.y);
@@ -87,6 +171,7 @@ class WebStrand {
87171
     }
88172
 }
89173
 
174
+
90175
 class WebNode {
91176
     constructor(x, y) {
92177
         this.x = x;