zeroed-some/sprong / 77dfb21

Browse files

ai can now BOPIT

Authored by espadonne
SHA
77dfb215bc8fecda1491898452d17e5374c835e1
Parents
ff3a76e
Tree
3ee498c

1 changed file

StatusFile+-
M sprong.js 77 28
sprong.jsmodified
@@ -17,7 +17,7 @@ const PADDLE_WIDTH = 20;
1717
 const PADDLE_HEIGHT = 80;
1818
 
1919
 // Enhanced movement constants (tuned for faster response)
20
-const SUPPORT_SPEED     = 6.5;  // Bumped up
20
+const SUPPORT_SPEED     = 6.5;  // Bumped up from 4.5
2121
 const SUPPORT_ACCEL     = 1.2;  // Increased acceleration
2222
 const INPUT_SMOOTHING   = 0.25; // More responsive
2323
 const SUPPORT_MAX_SPEED = 8;    // Higher max speed
@@ -35,22 +35,22 @@ const SPRING_STIFFNESS = 0.025;
3535
 
3636
 // Visual enhancement constants
3737
 const TRAIL_SEGMENTS        = 8;
38
-const PADDLE_GLOW_DISTANCE  = 25;
39
-const SPRING_GLOW_INTENSITY = 120; // More intense glow
38
+const PADDLE_GLOW_DISTANCE  = 25;   // self explanatory
39
+const SPRING_GLOW_INTENSITY = 120;  // self explanatory. so why add a comment? because I'm anal.
4040
 
4141
 // Particle system constants
42
-const MAX_PARTICLES         = 100;
43
-const PARTICLE_LIFE         = 60;
44
-const IMPACT_PARTICLES      = 8;
45
-const SPRING_PARTICLE_RATE  = 0.3;
42
+const MAX_PARTICLES         = 100;  // dont get carried away    
43
+const PARTICLE_LIFE         = 60;   // dont get carried away
44
+const IMPACT_PARTICLES      = 8;    // dont get carried away
45
+const SPRING_PARTICLE_RATE  = 0.3;  // get carried away.
4646
 
4747
 // Bop system constants
48
-const BOP_FORCE             = 1.0;
49
-const BOP_DURATION          = 300;
50
-const BOP_COOLDOWN          = 500;
51
-const ANCHOR_RECOIL         = 40;     // How far the anchor moves backward during bop
52
-const BOP_RANGE             = 600;    // How far the paddle can thrust forward
53
-const BOP_VELOCITY_BOOST    = 12;     // Initial velocity boost for paddle
48
+const BOP_FORCE             = 1.0;  // self explanatory.      BOP   it.
49
+const BOP_RANGE             = 50;   // also self explanatory. TWIST it.
50
+const BOP_DURATION          = 300;  // traversal duration.    SHAKE it.
51
+const BOP_COOLDOWN          = 500;  // also also self expl.   PULL  it.
52
+const ANCHOR_RECOIL         = 40;   // How far the anchor moves backward during bop
53
+const BOP_VELOCITY_BOOST    = 12;   // Initial velocity boost for paddle
5454
 
5555
 // Game variables
5656
 let ball;
@@ -351,7 +351,8 @@ const AI_SETTINGS = {
351351
         speed: 0.8,           // Increased from 0.6
352352
         prediction: 0.3,      // 30% prediction vs reaction
353353
         aggression: 0.2,      // Low aggression
354
-        oscillation: 0.3      // Minimal oscillation
354
+        oscillation: 0.3,     // Minimal oscillation
355
+        bopChance: 0.25       // 25% chance to bop when in range
355356
     },
356357
     medium: {
357358
         reactionTime: 250,
@@ -359,7 +360,8 @@ const AI_SETTINGS = {
359360
         speed: 1.0,           // Increased from 0.8
360361
         prediction: 0.6,
361362
         aggression: 0.5,      // Moderate aggression
362
-        oscillation: 0.7      // Good oscillation technique
363
+        oscillation: 0.7,     // Good oscillation technique
364
+        bopChance: 0.55       // 55% chance to bop when in range
363365
     },
364366
     hard: {
365367
         reactionTime: 150,
@@ -367,7 +369,8 @@ const AI_SETTINGS = {
367369
         speed: 1.2,           // Increased from 1.0 
368370
         prediction: 0.8,
369371
         aggression: 0.8,      // High aggression
370
-        oscillation: 1.0      // Master-level oscillation
372
+        oscillation: 1.0,     // Master-level oscillation
373
+        bopChance: 0.85       // 85% chance to bop when in range
371374
     }
372375
 };
373376
 
@@ -744,33 +747,64 @@ function handleAITracking(currentTime, ballPos, ballVel, aiSettings) {
744747
     aiState.targetY = lerp(aiState.targetY, targetAnchorY, trackingIntensity);
745748
     
746749
     // AI Bop decision logic
747
-    if (ballApproaching && ballDistance < 150 && !aiState.consideringBop) {
748
-        // Consider bopping if ball is close and conditions are right
749
-        let shouldConsiderBop = ballSpeed > 8 &&  // Fast incoming ball
750
-                               Math.abs(ballVel.y) < 4 &&  // Not too much vertical movement
751
-                               random() < aiSettings.aggression * 0.4; // Chance based on aggression
750
+    if (ballApproaching && !aiState.consideringBop && !bopState.right.active) {
751
+        // Calculate if ball will be within bop range
752
+        let timeToReach = ballDistance / Math.abs(ballVel.x);
753
+        let predictedBallY = ballPos.y + ballVel.y * timeToReach;
754
+        
755
+        // Account for wall bounces in prediction
756
+        if (predictedBallY < 50) {
757
+            predictedBallY = 100 - predictedBallY;
758
+        } else if (predictedBallY > height - 50) {
759
+            predictedBallY = 2 * (height - 50) - predictedBallY;
760
+        }
761
+        
762
+        // Check if paddle will be close enough to ball for effective bop
763
+        let paddleY = rightPaddle.position.y;
764
+        let distanceToIntercept = Math.abs(predictedBallY - paddleY);
765
+        
766
+        // Bop is effective if paddle is within a reasonable range of the ball
767
+        let bopEffectiveRange = PADDLE_HEIGHT / 2 + 30; // Paddle can reach ball with bop
768
+        
769
+        // Consider bopping if:
770
+        // 1. Ball is approaching at good speed
771
+        // 2. Ball will be within bop effective range
772
+        // 3. Ball is at the right distance for timing
773
+        // 4. Random chance based on difficulty
774
+        let shouldConsiderBop = ballSpeed > 5 &&  // Minimum speed worth bopping
775
+                               distanceToIntercept < bopEffectiveRange &&
776
+                               ballDistance > 80 && ballDistance < 200 && // Sweet spot for bop timing
777
+                               currentTime - bopState.right.lastBopTime > BOP_COOLDOWN &&
778
+                               random() < aiSettings.bopChance; // Difficulty-based chance
752779
         
753780
         if (shouldConsiderBop) {
754781
             aiState.consideringBop = true;
755782
             aiState.bopDecisionTime = currentTime;
783
+            // Adjust bop timing based on ball speed and distance
784
+            aiState.bopTiming = Math.max(50, Math.min(200, ballDistance * 2 - ballSpeed * 10));
756785
         }
757786
     }
758787
     
759788
     // Execute bop at the right moment
760789
     if (aiState.consideringBop && ballApproaching) {
761790
         let timeToBop = currentTime - aiState.bopDecisionTime;
791
+        let paddleY = rightPaddle.position.y;
792
+        let distanceToBall = Math.abs(ballPos.y - paddleY);
793
+        
794
+        // Refined bop execution conditions
762795
         let shouldBop = timeToBop > aiState.bopTiming && 
763
-                       ballDistance < 100 && 
764
-                       !bopState.right.active &&
765
-                       currentTime - bopState.right.lastBopTime > BOP_COOLDOWN;
796
+                       ballDistance < 150 && // Close enough
797
+                       distanceToBall < PADDLE_HEIGHT / 2 + 20 && // Paddle can reach ball
798
+                       !bopState.right.active;
766799
         
767800
         if (shouldBop) {
768801
             activateBop('right', currentTime);
769802
             aiState.consideringBop = false;
803
+            console.log(`AI BOP! Difficulty: ${aiState.difficulty}, Speed: ${ballSpeed.toFixed(1)}`);
770804
         }
771805
         
772
-        // Cancel bop consideration if ball gets too far
773
-        if (ballDistance > 150) {
806
+        // Cancel bop if opportunity missed
807
+        if (ballDistance > 200 || ballDistance < 50) {
774808
             aiState.consideringBop = false;
775809
         }
776810
     }
@@ -1209,7 +1243,7 @@ function drawSinglePaddleEnhanced(paddle, ballDistance) {
12091243
     if (isLeft && bopState.left.active) {
12101244
         let bopProgress = (millis() - bopState.left.startTime) / bopState.left.duration;
12111245
         bopGlow = (1 - bopProgress) * 100; // Fade out over bop duration
1212
-    } else if (!isLeft && !isAI && bopState.right.active) {
1246
+    } else if (!isLeft && bopState.right.active) {
12131247
         let bopProgress = (millis() - bopState.right.startTime) / bopState.right.duration;
12141248
         bopGlow = (1 - bopProgress) * 100;
12151249
     }
@@ -1244,8 +1278,14 @@ function drawSinglePaddleEnhanced(paddle, ballDistance) {
12441278
     }
12451279
     
12461280
     // Bop color override
1247
-    if ((isLeft && bopState.left.active) || (!isLeft && !isAI && bopState.right.active)) {
1281
+    if ((isLeft && bopState.left.active) || (!isLeft && bopState.right.active)) {
12481282
         paddleColor = [255, 255, 100]; // Bright yellow during bop
1283
+        
1284
+        // Special effect for AI bop
1285
+        if (isAI && bopState.right.active) {
1286
+            paddleColor = [255, 50, 255]; // Purple for AI bop
1287
+            glowIntensity = Math.min(255, glowIntensity + 50); // Extra glow
1288
+        }
12491289
     }
12501290
     
12511291
     // Draw enhanced glow effect first
@@ -1389,6 +1429,15 @@ function drawDebugInfo() {
13891429
         } else if (aiState.mode === 'SWINGING') {
13901430
             fill(255, 50, 50, 200);
13911431
             text("⚡ AI POWER SWING!", 10, 175);
1432
+        } else if (aiState.consideringBop) {
1433
+            fill(255, 255, 100, 200);
1434
+            text("💥 AI PREPARING BOP!", 10, 175);
1435
+        }
1436
+        
1437
+        // Bop status
1438
+        if (bopState.right.active) {
1439
+            fill(255, 255, 0, 255);
1440
+            text("🚀 AI BOPPING!", 10, 190);
13921441
         }
13931442
     }
13941443