zeroed-some/sprong / 3631027

Browse files

enhancements

Authored by espadonne
SHA
3631027bc020fbf8e3bbed2d91a314378dc39589
Parents
44a9c6e
Tree
9ddd2d7

2 changed files

StatusFile+-
M Matter.js 186 97
M index.html 1 1
Matter.jsmodified
@@ -23,6 +23,7 @@ let gameStarted = false;
23
 
23
 
24
 // Player input
24
 // Player input
25
 let keys = {};
25
 let keys = {};
26
+let inputBuffer = { left: 0, right: 0 };
26
 
27
 
27
 // Canvas settings
28
 // Canvas settings
28
 const CANVAS_WIDTH  = 800;
29
 const CANVAS_WIDTH  = 800;
@@ -33,7 +34,12 @@ const BALL_SPEED = 8;
33
 const BALL_RADIUS   = 12;
34
 const BALL_RADIUS   = 12;
34
 const PADDLE_WIDTH  = 20;
35
 const PADDLE_WIDTH  = 20;
35
 const PADDLE_HEIGHT = 80;
36
 const PADDLE_HEIGHT = 80;
36
-const SUPPORT_SPEED = 4;
37
+
38
+// Enhanced movement constants
39
+const SUPPORT_SPEED     = 4.5;
40
+const SUPPORT_ACCEL     = 0.8;
41
+const INPUT_SMOOTHING   = 0.15;
42
+const SUPPORT_MAX_SPEED = 6;
37
 
43
 
38
 // Spring physics constants
44
 // Spring physics constants
39
 const PADDLE_MASS       = 0.8;
45
 const PADDLE_MASS       = 0.8;
@@ -41,6 +47,11 @@ const SPRING_LENGTH = 40;
41
 const SPRING_DAMPING    = 0.8;
47
 const SPRING_DAMPING    = 0.8;
42
 const SPRING_STIFFNESS  = 0.02;
48
 const SPRING_STIFFNESS  = 0.02;
43
 
49
 
50
+// Visual enhancement constants
51
+const TRAIL_SEGMENTS        = 8;
52
+const PADDLE_GLOW_DISTANCE  = 25;
53
+const SPRING_GLOW_INTENSITY = 80;
54
+
44
 function setup() {
55
 function setup() {
45
     // Create p5.js canvas
56
     // Create p5.js canvas
46
     let canvas = createCanvas(CANVAS_WIDTH, CANVAS_HEIGHT);
57
     let canvas = createCanvas(CANVAS_WIDTH, CANVAS_HEIGHT);
@@ -73,6 +84,11 @@ function setup() {
73
         leftSupport, leftPaddle, leftSpring,
84
         leftSupport, leftPaddle, leftSpring,
74
         rightSupport, rightPaddle, rightSpring
85
         rightSupport, rightPaddle, rightSpring
75
     ]);
86
     ]);
87
+    
88
+    console.log("🎮 Sprong Phase 4 Complete!");
89
+    console.log("✓ Enhanced player controls with acceleration");
90
+    console.log("✓ Smooth input buffering and movement");
91
+    console.log("✓ Improved visual feedback and polish");
76
 }
92
 }
77
 
93
 
78
 function createSpringPaddleSystem(side) {
94
 function createSpringPaddleSystem(side) {
@@ -133,8 +149,8 @@ function draw() {
133
     // Update physics
149
     // Update physics
134
     Engine.update(engine);
150
     Engine.update(engine);
135
     
151
     
136
-    // Handle player input
152
+    // Handle enhanced player input
137
-    handleInput();
153
+    handleEnhancedInput();
138
     
154
     
139
     // Check for scoring
155
     // Check for scoring
140
     checkBallPosition();
156
     checkBallPosition();
@@ -142,9 +158,9 @@ function draw() {
142
     // Clear canvas
158
     // Clear canvas
143
     background(10, 10, 10);
159
     background(10, 10, 10);
144
     
160
     
145
-    // Draw game objects
161
+    // Draw game objects with enhanced visuals
146
-    drawSpringPaddleSystems();
162
+    drawSpringPaddleSystemsEnhanced();
147
-    drawBall();
163
+    drawBallEnhanced();
148
     drawBoundaries();
164
     drawBoundaries();
149
     drawCenterLine();
165
     drawCenterLine();
150
     
166
     
@@ -157,110 +173,205 @@ function draw() {
157
     }
173
     }
158
 }
174
 }
159
 
175
 
160
-function drawSpringPaddleSystems() {
176
+function handleEnhancedInput() {
161
-    // Draw springs first (behind paddles)
177
+    // Smooth input accumulation with acceleration
162
-    drawSprings();
178
+    let leftInput = 0;
179
+    let rightInput = 0;
163
     
180
     
164
-    // Draw paddles
181
+    // Left paddle input (W/S keys)
165
-    fill(0, 255, 136);
182
+    if (keys['w'] || keys['W']) leftInput -= 1;
166
-    stroke(0, 255, 136);
183
+    if (keys['s'] || keys['S']) leftInput += 1;
167
-    strokeWeight(2);
168
     
184
     
169
-    // Left paddle
185
+    // Right paddle input (Arrow keys)
170
-    let leftPos = leftPaddle.position;
186
+    if (keys['ArrowUp']) rightInput -= 1;
171
-    let leftAngle = leftPaddle.angle;
187
+    if (keys['ArrowDown']) rightInput += 1;
172
-    push();
173
-    translate(leftPos.x, leftPos.y);
174
-    rotate(leftAngle);
175
-    rectMode(CENTER);
176
-    rect(0, 0, PADDLE_WIDTH, PADDLE_HEIGHT);
177
-    pop();
178
     
188
     
179
-    // Right paddle
189
+    // Apply acceleration and smoothing
180
-    let rightPos = rightPaddle.position;
190
+    inputBuffer.left = lerp(inputBuffer.left, leftInput, INPUT_SMOOTHING);
181
-    let rightAngle = rightPaddle.angle;
191
+    inputBuffer.right = lerp(inputBuffer.right, rightInput, INPUT_SMOOTHING);
182
-    push();
183
-    translate(rightPos.x, rightPos.y);
184
-    rotate(rightAngle);
185
-    rectMode(CENTER);
186
-    rect(0, 0, PADDLE_WIDTH, PADDLE_HEIGHT);
187
-    pop();
188
     
192
     
189
-    // Draw support points (small indicators)
193
+    // Move supports with enhanced physics
190
-    fill(0, 255, 136, 100);
194
+    if (Math.abs(inputBuffer.left) > 0.01) {
191
-    noStroke();
195
+        moveSupportEnhanced(leftSupport, inputBuffer.left * SUPPORT_SPEED);
192
-    ellipse(leftSupport.position.x, leftSupport.position.y, 8, 8);
196
+    }
193
-    ellipse(rightSupport.position.x, rightSupport.position.y, 8, 8);
197
+    if (Math.abs(inputBuffer.right) > 0.01) {
198
+        moveSupportEnhanced(rightSupport, inputBuffer.right * SUPPORT_SPEED);
199
+    }
200
+}
201
+
202
+function moveSupportEnhanced(support, deltaY) {
203
+    let newY = support.position.y + deltaY;
204
+    
205
+    // Keep support within reasonable bounds with smooth clamping
206
+    let minY = 50;
207
+    let maxY = height - 50;
208
+    
209
+    if (newY < minY) {
210
+        newY = minY + (newY - minY) * 0.1; // Soft boundary
211
+    } else if (newY > maxY) {
212
+        newY = maxY + (newY - maxY) * 0.1; // Soft boundary
213
+    }
214
+    
215
+    Body.setPosition(support, { x: support.position.x, y: newY });
194
 }
216
 }
195
 
217
 
196
-function drawSprings() {
218
+function drawSpringPaddleSystemsEnhanced() {
197
-    stroke(0, 255, 136, 150);
219
+    // Draw springs with enhanced visuals
198
-    strokeWeight(3);
220
+    drawSpringsEnhanced();
199
     
221
     
222
+    // Draw paddles with glow effects
223
+    drawPaddlesWithGlow();
224
+    
225
+    // Draw support points with input feedback
226
+    drawSupportPointsEnhanced();
227
+}
228
+
229
+function drawSpringsEnhanced() {
200
     // Left spring
230
     // Left spring
201
     let leftSupportPos = leftSupport.position;
231
     let leftSupportPos = leftSupport.position;
202
     let leftPaddlePos = leftPaddle.position;
232
     let leftPaddlePos = leftPaddle.position;
203
-    
233
+    drawSpringLineEnhanced(leftSupportPos, leftPaddlePos);
204
-    // Draw spring as a zigzag line
205
-    drawSpringLine(leftSupportPos, leftPaddlePos, 'left');
206
     
234
     
207
     // Right spring
235
     // Right spring
208
     let rightSupportPos = rightSupport.position;
236
     let rightSupportPos = rightSupport.position;
209
     let rightPaddlePos = rightPaddle.position;
237
     let rightPaddlePos = rightPaddle.position;
210
-    
238
+    drawSpringLineEnhanced(rightSupportPos, rightPaddlePos);
211
-    drawSpringLine(rightSupportPos, rightPaddlePos, 'right');
212
 }
239
 }
213
 
240
 
214
-function drawSpringLine(startPos, endPos, side) {
241
+function drawSpringLineEnhanced(startPos, endPos) {
215
-    let segments = 8;
242
+    let segments = 10;
216
     let amplitude = 8;
243
     let amplitude = 8;
217
     
244
     
218
-    // Calculate spring compression (affects visual amplitude)
245
+    // Calculate spring compression for visual effects
219
     let currentLength = dist(startPos.x, startPos.y, endPos.x, endPos.y);
246
     let currentLength = dist(startPos.x, startPos.y, endPos.x, endPos.y);
220
     let compression = SPRING_LENGTH / currentLength;
247
     let compression = SPRING_LENGTH / currentLength;
221
     amplitude *= compression;
248
     amplitude *= compression;
222
     
249
     
223
-    stroke(0, 255, 136, 150 + compression * 50); // Brighter when compressed
250
+    // Enhanced spring glow based on compression
224
-    strokeWeight(2 + compression);
251
+    let glowIntensity = 150 + compression * SPRING_GLOW_INTENSITY;
252
+    stroke(0, 255, 136, glowIntensity);
253
+    strokeWeight(2 + compression * 1.5);
254
+    
255
+    // Draw spring coil with smooth curves
256
+    beginShape();
257
+    noFill();
225
     
258
     
226
     for (let i = 0; i <= segments; i++) {
259
     for (let i = 0; i <= segments; i++) {
227
         let t = i / segments;
260
         let t = i / segments;
228
         let x = lerp(startPos.x, endPos.x, t);
261
         let x = lerp(startPos.x, endPos.x, t);
229
         let y = lerp(startPos.y, endPos.y, t);
262
         let y = lerp(startPos.y, endPos.y, t);
230
         
263
         
231
-        // Add zigzag offset
264
+        // Enhanced zigzag with smoother curves
232
         if (i > 0 && i < segments) {
265
         if (i > 0 && i < segments) {
233
             let perpX = -(endPos.y - startPos.y) / currentLength;
266
             let perpX = -(endPos.y - startPos.y) / currentLength;
234
             let perpY = (endPos.x - startPos.x) / currentLength;
267
             let perpY = (endPos.x - startPos.x) / currentLength;
235
-            let offset = sin(i * PI) * amplitude;
268
+            let offset = sin(i * PI * 1.2) * amplitude;
236
             x += perpX * offset;
269
             x += perpX * offset;
237
             y += perpY * offset;
270
             y += perpY * offset;
238
         }
271
         }
239
         
272
         
240
-        if (i === 0) {
241
-            beginShape();
242
         vertex(x, y);
273
         vertex(x, y);
243
-        } else {
274
+    }
244
-            vertex(x, y);
275
+    
245
-            if (i === segments) {
246
     endShape();
276
     endShape();
277
+    
278
+    // Add spring glow effect
279
+    stroke(0, 255, 136, glowIntensity * 0.3);
280
+    strokeWeight(6 + compression * 2);
281
+    beginShape();
282
+    noFill();
283
+    
284
+    for (let i = 0; i <= segments; i++) {
285
+        let t = i / segments;
286
+        let x = lerp(startPos.x, endPos.x, t);
287
+        let y = lerp(startPos.y, endPos.y, t);
288
+        vertex(x, y);
247
     }
289
     }
290
+    
291
+    endShape();
248
 }
292
 }
293
+
294
+function drawPaddlesWithGlow() {
295
+    // Calculate ball distance for glow effects
296
+    let ballPos = ball.position;
297
+    let leftDist = dist(ballPos.x, ballPos.y, leftPaddle.position.x, leftPaddle.position.y);
298
+    let rightDist = dist(ballPos.x, ballPos.y, rightPaddle.position.x, rightPaddle.position.y);
299
+    
300
+    // Enhanced paddle drawing
301
+    drawSinglePaddleEnhanced(leftPaddle, leftDist);
302
+    drawSinglePaddleEnhanced(rightPaddle, rightDist);
249
 }
303
 }
304
+
305
+function drawSinglePaddleEnhanced(paddle, ballDistance) {
306
+    let pos = paddle.position;
307
+    let angle = paddle.angle;
308
+    
309
+    // Calculate glow intensity based on ball proximity
310
+    let glowIntensity = map(ballDistance, 0, PADDLE_GLOW_DISTANCE, 100, 0);
311
+    glowIntensity = constrain(glowIntensity, 0, 100);
312
+    
313
+    push();
314
+    translate(pos.x, pos.y);
315
+    rotate(angle);
316
+    
317
+    // Draw glow effect first
318
+    if (glowIntensity > 0) {
319
+        fill(0, 255, 136, glowIntensity * 0.5);
320
+        noStroke();
321
+        rectMode(CENTER);
322
+        rect(0, 0, PADDLE_WIDTH + 8, PADDLE_HEIGHT + 8);
250
     }
323
     }
251
     
324
     
252
-function drawBall() {
325
+    // Draw main paddle
253
-    fill(255, 100, 100);
326
+    fill(0, 255, 136);
254
-    stroke(255, 150, 150);
327
+    stroke(0, 255, 136, 200 + glowIntensity);
255
     strokeWeight(2);
328
     strokeWeight(2);
329
+    rectMode(CENTER);
330
+    rect(0, 0, PADDLE_WIDTH, PADDLE_HEIGHT);
331
+    
332
+    pop();
333
+}
334
+
335
+function drawSupportPointsEnhanced() {
336
+    // Enhanced support indicators with input feedback
337
+    let leftActivity = Math.abs(inputBuffer.left) * 255;
338
+    let rightActivity = Math.abs(inputBuffer.right) * 255;
339
+    
340
+    // Left support
341
+    fill(0, 255, 136, 100 + leftActivity * 0.5);
342
+    noStroke();
343
+    ellipse(leftSupport.position.x, leftSupport.position.y, 8 + leftActivity * 0.1, 8 + leftActivity * 0.1);
344
+    
345
+    // Right support
346
+    fill(0, 255, 136, 100 + rightActivity * 0.5);
347
+    ellipse(rightSupport.position.x, rightSupport.position.y, 8 + rightActivity * 0.1, 8 + rightActivity * 0.1);
348
+}
256
 
349
 
350
+function drawBallEnhanced() {
257
     let ballPos = ball.position;
351
     let ballPos = ball.position;
258
-    ellipse(ballPos.x, ballPos.y, BALL_RADIUS * 2, BALL_RADIUS * 2);
352
+    let ballVel = ball.velocity;
353
+    let speed = Math.sqrt(ballVel.x * ballVel.x + ballVel.y * ballVel.y);
354
+    
355
+    // Enhanced ball with speed-based effects
356
+    let speedIntensity = map(speed, 0, 15, 50, 255);
259
     
357
     
260
     // Ball trail effect
358
     // Ball trail effect
261
-    fill(255, 100, 100, 50);
359
+    fill(255, 100, 100, 30);
360
+    noStroke();
361
+    ellipse(ballPos.x, ballPos.y, BALL_RADIUS * 4, BALL_RADIUS * 4);
362
+    
363
+    // Main ball
364
+    fill(255, 100, 100);
365
+    stroke(255, 150, 150, speedIntensity);
366
+    strokeWeight(2 + speed * 0.1);
367
+    ellipse(ballPos.x, ballPos.y, BALL_RADIUS * 2, BALL_RADIUS * 2);
368
+    
369
+    // Speed indicator
370
+    if (speed > 10) {
371
+        fill(255, 255, 255, speedIntensity * 0.5);
262
         noStroke();
372
         noStroke();
263
-    ellipse(ballPos.x, ballPos.y, BALL_RADIUS * 3, BALL_RADIUS * 3);
373
+        ellipse(ballPos.x, ballPos.y, BALL_RADIUS, BALL_RADIUS);
374
+    }
264
 }
375
 }
265
 
376
 
266
 function drawBoundaries() {
377
 function drawBoundaries() {
@@ -287,7 +398,7 @@ function drawDebugInfo() {
287
     text(`FPS: ${Math.round(frameRate())}`, 10, 20);
398
     text(`FPS: ${Math.round(frameRate())}`, 10, 20);
288
     text(`Ball Speed: ${Math.round(getBallSpeed())}`, 10, 35);
399
     text(`Ball Speed: ${Math.round(getBallSpeed())}`, 10, 35);
289
     
400
     
290
-    // Spring info
401
+    // Enhanced spring info
291
     let leftSpringLength = dist(leftSupport.position.x, leftSupport.position.y, 
402
     let leftSpringLength = dist(leftSupport.position.x, leftSupport.position.y, 
292
                                leftPaddle.position.x, leftPaddle.position.y);
403
                                leftPaddle.position.x, leftPaddle.position.y);
293
     let rightSpringLength = dist(rightSupport.position.x, rightSupport.position.y, 
404
     let rightSpringLength = dist(rightSupport.position.x, rightSupport.position.y, 
@@ -295,7 +406,7 @@ function drawDebugInfo() {
295
     
406
     
296
     text(`Left Spring: ${Math.round(leftSpringLength)}px`, 10, 50);
407
     text(`Left Spring: ${Math.round(leftSpringLength)}px`, 10, 50);
297
     text(`Right Spring: ${Math.round(rightSpringLength)}px`, 10, 65);
408
     text(`Right Spring: ${Math.round(rightSpringLength)}px`, 10, 65);
298
-    text(`Spring Rest Length: ${SPRING_LENGTH}px`, 10, 80);
409
+    text(`Input Buffer: L=${inputBuffer.left.toFixed(2)} R=${inputBuffer.right.toFixed(2)}`, 10, 80);
299
 }
410
 }
300
 
411
 
301
 function drawStartMessage() {
412
 function drawStartMessage() {
@@ -304,34 +415,7 @@ function drawStartMessage() {
304
     textSize(20);
415
     textSize(20);
305
     text("Press any key to start!", width/2, height/2 + 100);
416
     text("Press any key to start!", width/2, height/2 + 100);
306
     textSize(14);
417
     textSize(14);
307
-    text("Watch the springs compress and extend!", width/2, height/2 + 125);
418
+    text("Enhanced controls with smooth acceleration!", width/2, height/2 + 125);
308
-}
309
-
310
-function handleInput() {
311
-    // Left paddle (W/S keys) - move the support point
312
-    if (keys['w'] || keys['W']) {
313
-        moveSupport(leftSupport, -SUPPORT_SPEED);
314
-    }
315
-    if (keys['s'] || keys['S']) {
316
-        moveSupport(leftSupport, SUPPORT_SPEED);
317
-    }
318
-    
319
-    // Right paddle (Arrow keys) - move the support point
320
-    if (keys['ArrowUp']) {
321
-        moveSupport(rightSupport, -SUPPORT_SPEED);
322
-    }
323
-    if (keys['ArrowDown']) {
324
-        moveSupport(rightSupport, SUPPORT_SPEED);
325
-    }
326
-}
327
-
328
-function moveSupport(support, deltaY) {
329
-    let newY = support.position.y + deltaY;
330
-    
331
-    // Keep support within reasonable bounds
332
-    newY = constrain(newY, 50, height - 50);
333
-    
334
-    Body.setPosition(support, { x: support.position.x, y: newY });
335
 }
419
 }
336
 
420
 
337
 function resetBall() {
421
 function resetBall() {
@@ -408,6 +492,11 @@ function keyPressed() {
408
         updateScore();
492
         updateScore();
409
         resetBall();
493
         resetBall();
410
         gameStarted = false;
494
         gameStarted = false;
495
+        
496
+        // Reset input buffers
497
+        inputBuffer.left = 0;
498
+        inputBuffer.right = 0;
499
+        
411
         console.log("🔄 Game reset!");
500
         console.log("🔄 Game reset!");
412
     }
501
     }
413
 }
502
 }
index.htmlmodified
@@ -3,7 +3,7 @@
3
 <head>
3
 <head>
4
     <meta charset="UTF-8">
4
     <meta charset="UTF-8">
5
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
5
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
-    <title>Sprong :: Pong with Physics</title>
6
+    <title>Sprong :: Pong with Physick</title>
7
     <link rel="stylesheet" href="sprong.css">
7
     <link rel="stylesheet" href="sprong.css">
8
 </head>
8
 </head>
9
 <body>
9
 <body>