@@ -41,11 +41,11 @@ const IMPACT_PARTICLES = 8; |
| 41 | const SPRING_PARTICLE_RATE = 0.3; | 41 | const SPRING_PARTICLE_RATE = 0.3; |
| 42 | | 42 | |
| 43 | // Bop system constants | 43 | // Bop system constants |
| 44 | -const BOP_FORCE = 0.2; // self explanatory. BOP it. | 44 | +const BOP_FORCE = 1.0; // self explanatory. BOP it. |
| 45 | -const BOP_RANGE = 40; // also self explanatory. TWIST it. | 45 | +const BOP_RANGE = 500; // also self explanatory. TWIST it. |
| 46 | -const BOP_DURATION = 1500; // traversal duration. SHAKE it. | 46 | +const BOP_DURATION = 1000; // traversal duration. SHAKE it. |
| 47 | -const BOP_COOLDOWN = 500; // also also self expl. PULL it. | 47 | +const BOP_COOLDOWN = 0; // also also self expl. PULL it. |
| 48 | -const ANCHOR_RECOIL = 40; // How far the anchor moves backward during bop | 48 | +const ANCHOR_RECOIL = 60; // How far the anchor moves backward during bop |
| 49 | const BOP_VELOCITY_BOOST = 5; // Initial velocity boost for paddle | 49 | const BOP_VELOCITY_BOOST = 5; // Initial velocity boost for paddle |
| 50 | | 50 | |
| 51 | // ============= BOP SYSTEM ============= | 51 | // ============= BOP SYSTEM ============= |
@@ -74,8 +74,9 @@ function handleBopInput(keys, aiEnabled, currentTime, leftPaddle, rightPaddle, l |
| 74 | // Left player bop - use Left Shift for both modes | 74 | // Left player bop - use Left Shift for both modes |
| 75 | let leftBopPressed = keys['Shift'] && !keys['Control']; | 75 | let leftBopPressed = keys['Shift'] && !keys['Control']; |
| 76 | | 76 | |
| | 77 | + // BOP_COOLDOWN controls the minimum time between bops |
| 77 | if (leftBopPressed && !bopState.left.active && | 78 | if (leftBopPressed && !bopState.left.active && |
| 78 | - currentTime - bopState.left.lastBopTime > bopState.left.cooldown) { | 79 | + currentTime - bopState.left.lastBopTime > BOP_COOLDOWN) { |
| 79 | activateBop('left', currentTime, leftPaddle, leftSupport, engine, particles); | 80 | activateBop('left', currentTime, leftPaddle, leftSupport, engine, particles); |
| 80 | } | 81 | } |
| 81 | | 82 | |
@@ -83,8 +84,9 @@ function handleBopInput(keys, aiEnabled, currentTime, leftPaddle, rightPaddle, l |
| 83 | if (!aiEnabled) { | 84 | if (!aiEnabled) { |
| 84 | let rightBopPressed = keys['Enter']; | 85 | let rightBopPressed = keys['Enter']; |
| 85 | | 86 | |
| | 87 | + // BOP_COOLDOWN controls the minimum time between bops |
| 86 | if (rightBopPressed && !bopState.right.active && | 88 | if (rightBopPressed && !bopState.right.active && |
| 87 | - currentTime - bopState.right.lastBopTime > bopState.right.cooldown) { | 89 | + currentTime - bopState.right.lastBopTime > BOP_COOLDOWN) { |
| 88 | activateBop('right', currentTime, rightPaddle, rightSupport, engine, particles); | 90 | activateBop('right', currentTime, rightPaddle, rightSupport, engine, particles); |
| 89 | } | 91 | } |
| 90 | } | 92 | } |
@@ -109,32 +111,35 @@ function activateBop(side, currentTime, paddle, support, engine, particles) { |
| 109 | if (magnitude > 0) { | 111 | if (magnitude > 0) { |
| 110 | dx /= magnitude; | 112 | dx /= magnitude; |
| 111 | dy /= magnitude; | 113 | dy /= magnitude; |
| 112 | - // Calculate anchor recoil distance | 114 | + |
| 113 | - let anchorRecoilDistance = ANCHOR_RECOIL * 0.3; | 115 | + // ANCHOR_RECOIL now properly controls the recoil distance |
| | 116 | + let anchorRecoilDistance = ANCHOR_RECOIL * 0.3; // Can adjust the 0.3 multiplier |
| 114 | | 117 | |
| 115 | - // Move support and paddle in one solver step (no teleport → no ghost collisions) | 118 | + // Move support and paddle backward together |
| 116 | Body.translate(support, { x: -dx * anchorRecoilDistance, y: -dy * anchorRecoilDistance }); | 119 | Body.translate(support, { x: -dx * anchorRecoilDistance, y: -dy * anchorRecoilDistance }); |
| 117 | Body.translate(paddle, { x: -dx * anchorRecoilDistance, y: -dy * anchorRecoilDistance }); | 120 | Body.translate(paddle, { x: -dx * anchorRecoilDistance, y: -dy * anchorRecoilDistance }); |
| 118 | | 121 | |
| 119 | // Remember where the support started so we can ease it back later | 122 | // Remember where the support started so we can ease it back later |
| 120 | - const preSupportPos = { x: support.position.x + dx * anchorRecoilDistance, | 123 | + bopState[side].originalPos = { |
| 121 | - y: support.position.y + dy * anchorRecoilDistance }; | 124 | + x: support.position.x + dx * anchorRecoilDistance, |
| 122 | - bopState[side].originalPos = preSupportPos; | 125 | + y: support.position.y + dy * anchorRecoilDistance |
| | 126 | + }; |
| 123 | | 127 | |
| 124 | - // Now apply forward thrust from this new position | 128 | + // BOP_VELOCITY_BOOST controls the initial forward velocity |
| 125 | - let forwardSpeed = BOP_VELOCITY_BOOST * 1.0; // Restored to full power | 129 | + let forwardSpeed = BOP_VELOCITY_BOOST; |
| 126 | Body.setVelocity(paddle, { | 130 | Body.setVelocity(paddle, { |
| 127 | x: paddle.velocity.x + dx * forwardSpeed, | 131 | x: paddle.velocity.x + dx * forwardSpeed, |
| 128 | y: paddle.velocity.y + dy * forwardSpeed | 132 | y: paddle.velocity.y + dy * forwardSpeed |
| 129 | }); | 133 | }); |
| 130 | | 134 | |
| 131 | - // Apply a forward force for continued acceleration | 135 | + // BOP_FORCE controls the sustained forward thrust |
| | 136 | + // Combined with BOP_RANGE for the total force applied |
| 132 | Body.applyForce(paddle, paddle.position, { | 137 | Body.applyForce(paddle, paddle.position, { |
| 133 | - x: dx * bopState[side].power * BOP_RANGE * 0.08, | 138 | + x: dx * BOP_FORCE * BOP_RANGE * 0.002, // Scaled down for Matter.js |
| 134 | - y: dy * bopState[side].power * BOP_RANGE * 0.08 | 139 | + y: dy * BOP_FORCE * BOP_RANGE * 0.002 |
| 135 | }); | 140 | }); |
| 136 | | 141 | |
| 137 | - // Create particle burst for visual feedback at the support position | 142 | + // Create particle burst for visual feedback |
| 138 | for (let i = 0; i < 5; i++) { | 143 | for (let i = 0; i < 5; i++) { |
| 139 | let angle = Math.atan2(dy, dx) + (Math.random() - 0.5) * 0.5; | 144 | let angle = Math.atan2(dy, dx) + (Math.random() - 0.5) * 0.5; |
| 140 | let speed = Math.random() * 4 + 2; | 145 | let speed = Math.random() * 4 + 2; |
@@ -152,7 +157,7 @@ function activateBop(side, currentTime, paddle, support, engine, particles) { |
| 152 | } | 157 | } |
| 153 | } | 158 | } |
| 154 | | 159 | |
| 155 | - console.log(side + " player BOP!"); | 160 | + console.log(`${side} player BOP! Duration: ${BOP_DURATION}ms, Cooldown: ${BOP_COOLDOWN}ms`); |
| 156 | } | 161 | } |
| 157 | | 162 | |
| 158 | function updateBopStates(currentTime, leftSupport, rightSupport, leftPaddle, rightPaddle) { | 163 | function updateBopStates(currentTime, leftSupport, rightSupport, leftPaddle, rightPaddle) { |
@@ -161,11 +166,12 @@ function updateBopStates(currentTime, leftSupport, rightSupport, leftPaddle, rig |
| 161 | // Update left bop | 166 | // Update left bop |
| 162 | if (bopState.left.active) { | 167 | if (bopState.left.active) { |
| 163 | let elapsed = currentTime - bopState.left.startTime; | 168 | let elapsed = currentTime - bopState.left.startTime; |
| 164 | - let progress = elapsed / bopState.left.duration; | 169 | + let progress = elapsed / BOP_DURATION; // BOP_DURATION controls how long the effect lasts |
| 165 | | 170 | |
| 166 | if (progress >= 1.0) { | 171 | if (progress >= 1.0) { |
| 167 | bopState.left.active = false; | 172 | bopState.left.active = false; |
| 168 | bopState.left.originalPos = null; | 173 | bopState.left.originalPos = null; |
| | 174 | + console.log("Left bop ended after", elapsed, "ms"); |
| 169 | } else { | 175 | } else { |
| 170 | if (bopState.left.originalPos) { | 176 | if (bopState.left.originalPos) { |
| 171 | let support = leftSupport; | 177 | let support = leftSupport; |
@@ -187,11 +193,12 @@ function updateBopStates(currentTime, leftSupport, rightSupport, leftPaddle, rig |
| 187 | // Update right bop (same logic) | 193 | // Update right bop (same logic) |
| 188 | if (bopState.right.active) { | 194 | if (bopState.right.active) { |
| 189 | let elapsed = currentTime - bopState.right.startTime; | 195 | let elapsed = currentTime - bopState.right.startTime; |
| 190 | - let progress = elapsed / bopState.right.duration; | 196 | + let progress = elapsed / BOP_DURATION; // BOP_DURATION controls how long the effect lasts |
| 191 | | 197 | |
| 192 | if (progress >= 1.0) { | 198 | if (progress >= 1.0) { |
| 193 | bopState.right.active = false; | 199 | bopState.right.active = false; |
| 194 | bopState.right.originalPos = null; | 200 | bopState.right.originalPos = null; |
| | 201 | + console.log("Right bop ended after", elapsed, "ms"); |
| 195 | } else { | 202 | } else { |
| 196 | if (bopState.right.originalPos) { | 203 | if (bopState.right.originalPos) { |
| 197 | let support = rightSupport; | 204 | let support = rightSupport; |
@@ -216,6 +223,7 @@ function limitBopRange(support, paddle) { |
| 216 | let currentDistance = dist(support.position.x, support.position.y, | 223 | let currentDistance = dist(support.position.x, support.position.y, |
| 217 | paddle.position.x, paddle.position.y); | 224 | paddle.position.x, paddle.position.y); |
| 218 | | 225 | |
| | 226 | + // BOP_RANGE controls the maximum extension allowed |
| 219 | let maxDistance = SPRING_LENGTH + BOP_RANGE; | 227 | let maxDistance = SPRING_LENGTH + BOP_RANGE; |
| 220 | if (currentDistance > maxDistance) { | 228 | if (currentDistance > maxDistance) { |
| 221 | let dx = paddle.position.x - support.position.x; | 229 | let dx = paddle.position.x - support.position.x; |
@@ -225,11 +233,14 @@ function limitBopRange(support, paddle) { |
| 225 | dx /= magnitude; | 233 | dx /= magnitude; |
| 226 | dy /= magnitude; | 234 | dy /= magnitude; |
| 227 | | 235 | |
| | 236 | + // Clamp paddle position to max range |
| 228 | let newX = support.position.x + dx * maxDistance; | 237 | let newX = support.position.x + dx * maxDistance; |
| 229 | let newY = support.position.y + dy * maxDistance; | 238 | let newY = support.position.y + dy * maxDistance; |
| 230 | | 239 | |
| 231 | let currentVel = paddle.velocity; | 240 | let currentVel = paddle.velocity; |
| 232 | Body.setPosition(paddle, { x: newX, y: newY }); | 241 | Body.setPosition(paddle, { x: newX, y: newY }); |
| | 242 | + |
| | 243 | + // Dampen velocity when hitting the range limit |
| 233 | Body.setVelocity(paddle, { | 244 | Body.setVelocity(paddle, { |
| 234 | x: currentVel.x * 0.7, | 245 | x: currentVel.x * 0.7, |
| 235 | y: currentVel.y * 0.7 | 246 | y: currentVel.y * 0.7 |