// Game variables let ball = { x: 400, y: 250, dx: 5, dy: 5, radius: 10 }; let leftPaddle = { y: 200, height: 100, width: 15, speed: 8 }; let rightPaddle = { y: 200, height: 100, width: 15, speed: 8 }; let score = { left: 0, right: 0 }; let gameRunning = false; let animationId; // DOM elements const ballElement = document.getElementById('ball'); const paddleLeftElement = document.getElementById('paddle-left'); const paddleRightElement = document.getElementById('paddle-right'); const scoreElement = document.getElementById('score'); const gameContainer = document.getElementById('game-container'); const startButton = document.getElementById('start-btn'); const resetButton = document.getElementById('reset-btn'); // Initialize game elements function initGame() { const containerRect = gameContainer.getBoundingClientRect(); // Ball position ball.x = containerRect.width / 2; ball.y = containerRect.height / 2; // Random initial direction ball.dx = Math.random() > 0.5 ? 5 : -5; ball.dy = (Math.random() * 4) - 2; // Paddle positions leftPaddle.y = (containerRect.height - leftPaddle.height) / 2; rightPaddle.y = (containerRect.height - rightPaddle.height) / 2; updateElements(); } // Update DOM elements positions function updateElements() { ballElement.style.left = `${ball.x}px`; ballElement.style.top = `${ball.y}px`; paddleLeftElement.style.top = `${leftPaddle.y}px`; paddleLeftElement.style.left = '20px'; paddleRightElement.style.top = `${rightPaddle.y}px`; paddleRightElement.style.right = '20px'; scoreElement.textContent = `${score.left} - ${score.right}`; } // Game loop function gameLoop() { if (!gameRunning) return; const containerRect = gameContainer.getBoundingClientRect(); // Move ball ball.x += ball.dx; ball.y += ball.dy; // Ball collision with top and bottom if (ball.y - ball.radius <= 0 || ball.y + ball.radius >= containerRect.height) { ball.dy = -ball.dy; ballElement.classList.add('ball-hit'); setTimeout(() => ballElement.classList.remove('ball-hit'), 200); } // Ball collision with paddles if ( (ball.x - ball.radius <= 35 && ball.y >= leftPaddle.y && ball.y <= leftPaddle.y + leftPaddle.height) || (ball.x + ball.radius >= containerRect.width - 35 && ball.y >= rightPaddle.y && ball.y <= rightPaddle.y + rightPaddle.height) ) { ball.dx = -ball.dx * 1.05; // Increase speed slightly on hit ball.dy += (Math.random() * 2) - 1; // Add slight randomness ballElement.classList.add('ball-hit'); setTimeout(() => ballElement.classList.remove('ball-hit'), 200); } // Score points if (ball.x - ball.radius <= 0) { score.right++; resetBall(); } else if (ball.x + ball.radius >= containerRect.width) { score.left++; resetBall(); } // Update elements updateElements(); // Continue game loop animationId = requestAnimationFrame(gameLoop); } // Reset ball to center function resetBall() { const containerRect = gameContainer.getBoundingClientRect(); ball.x = containerRect.width / 2; ball.y = containerRect.height / 2; ball.dx = score.right > score.left ? -5 : 5; // Direction towards losing player ball.dy = (Math.random() * 4) - 2; // Pause briefly before continuing gameRunning = false; setTimeout(() => { gameRunning = true; gameLoop(); }, 1000); } // Keyboard controls const keys = { w: false, s: false, ArrowUp: false, ArrowDown: false }; document.addEventListener('keydown', (e) => { if (['w', 's', 'ArrowUp', 'ArrowDown'].includes(e.key)) { keys[e.key] = true; } }); document.addEventListener('keyup', (e) => { if (['w', 's', 'ArrowUp', 'ArrowDown'].includes(e.key)) { keys[e.key] = false; } }); // Paddle movement function movePaddles() { const containerRect = gameContainer.getBoundingClientRect(); // Left paddle (W/S keys) if (keys.w && leftPaddle.y > 0) { leftPaddle.y -= leftPaddle.speed; } if (keys.s && leftPaddle.y < containerRect.height - leftPaddle.height) { leftPaddle.y += leftPaddle.speed; } // Right paddle (Up/Down arrows) if (keys.ArrowUp && rightPaddle.y > 0) { rightPaddle.y -= rightPaddle.speed; } if (keys.ArrowDown && rightPaddle.y < containerRect.height - rightPaddle.height) { rightPaddle.y += rightPaddle.speed; } updateElements(); } // Start game startButton.addEventListener('click', () => { if (!gameRunning) { gameRunning = true; startButton.disabled = true; initGame(); gameLoop(); // Paddle movement interval setInterval(movePaddles, 16); } }); // Reset game resetButton.addEventListener('click', () => { gameRunning = false; cancelAnimationFrame(animationId); score.left = 0; score.right = 0; startButton.disabled = false; initGame(); updateElements(); }); // Initialize game on load document.addEventListener('DOMContentLoaded', () => { initGame(); });