|
const gameArea = document.getElementById('gameArea'); |
|
const paddleLeft = document.getElementById('paddleLeft'); |
|
const paddleRight = document.getElementById('paddleRight'); |
|
const ball = document.getElementById('ball'); |
|
const playerScoreDisplay = document.getElementById('playerScore'); |
|
const botScoreDisplay = document.getElementById('botScore'); |
|
|
|
let paddleLeftY = window.innerHeight / 2 - 40; |
|
let paddleRightY = window.innerHeight / 2 - 40; |
|
let ballX = window.innerWidth / 2; |
|
let ballY = window.innerHeight / 2; |
|
let ballSpeedX = 3; |
|
let ballSpeedY = 0; |
|
let playerScore = 0; |
|
let botScore = 0; |
|
let isGamePaused = true; |
|
|
|
const paddleHeight = 80; |
|
const paddleWidth = 10; |
|
const ballSize = 15; |
|
const maxAngle = 45; |
|
|
|
gameArea.addEventListener('touchmove', (e) => { |
|
e.preventDefault(); |
|
let touchY = e.touches[0].clientY; |
|
|
|
if (e.touches[0].clientX < window.innerWidth / 2) { |
|
paddleLeftY = touchY - paddleHeight / 2; |
|
paddleLeftY = Math.max(0, Math.min(paddleLeftY, window.innerHeight - paddleHeight)); |
|
|
|
if (isGamePaused) { |
|
isGamePaused = false; |
|
} |
|
} |
|
}); |
|
|
|
function handlePaddleCollision(paddleY, paddleX, isLeftPaddle) { |
|
const ballRadius = ballSize / 2; |
|
const paddleRight = paddleX + paddleWidth; |
|
const paddleTop = paddleY; |
|
const paddleBottom = paddleY + paddleHeight; |
|
|
|
|
|
let closestX = ballX; |
|
if (isLeftPaddle) { |
|
closestX = paddleRight; |
|
} else { |
|
closestX = paddleX; |
|
} |
|
|
|
let closestY = ballY; |
|
if (ballY < paddleTop) { |
|
closestY = paddleTop; |
|
} else if (ballY > paddleBottom) { |
|
closestY = paddleBottom; |
|
} |
|
|
|
|
|
const dx = ballX - closestX; |
|
const dy = ballY - closestY; |
|
const distance = Math.sqrt(dx * dx + dy * dy); |
|
|
|
if (distance <= ballRadius) { |
|
|
|
|
|
const normalX = isLeftPaddle ? 1 : -1; |
|
const normalY = 0; |
|
|
|
|
|
const velocity = { x: ballSpeedX, y: ballSpeedY }; |
|
|
|
|
|
const dot = velocity.x * normalX + velocity.y * normalY; |
|
const reflected = { |
|
x: velocity.x - 2 * dot * normalX, |
|
y: velocity.y - 2 * dot * normalY |
|
}; |
|
|
|
|
|
const hitPosition = (closestY - (paddleTop + paddleHeight / 2)) / (paddleHeight / 2); |
|
const angle = hitPosition * maxAngle * (Math.PI / 180); |
|
reflected.y = Math.sin(angle) * Math.abs(reflected.x); |
|
|
|
|
|
ballSpeedX = reflected.x; |
|
ballSpeedY = reflected.y; |
|
|
|
|
|
const overlap = ballRadius - distance; |
|
ballX += normalX * overlap; |
|
} |
|
} |
|
|
|
function update() { |
|
if (!isGamePaused) { |
|
let previousBallX = ballX; |
|
ballX += ballSpeedX; |
|
ballY += ballSpeedY; |
|
|
|
|
|
if (ballY <= 0 || ballY >= window.innerHeight - ballSize) { |
|
ballSpeedY = -ballSpeedY; |
|
} |
|
|
|
|
|
handlePaddleCollision(paddleLeftY, paddleWidth, true); |
|
|
|
|
|
handlePaddleCollision(paddleRightY, window.innerWidth - paddleWidth - 25, false); |
|
|
|
|
|
if (ballX <= 0) { |
|
botScore++; |
|
botScoreDisplay.textContent = botScore; |
|
resetBall('right'); |
|
} else if (ballX >= window.innerWidth) { |
|
playerScore++; |
|
playerScoreDisplay.textContent = playerScore; |
|
resetBall('left'); |
|
} |
|
} |
|
|
|
|
|
if (ballSpeedX > 0) { |
|
if (paddleRightY + paddleHeight / 2 < ballY) { |
|
paddleRightY += 3; |
|
} else if (paddleRightY + paddleHeight / 2 > ballY) { |
|
paddleRightY -= 3; |
|
} |
|
} |
|
|
|
paddleRightY = Math.max(0, Math.min(paddleRightY, window.innerHeight - paddleHeight)); |
|
|
|
ball.style.left = ballX + 'px'; |
|
ball.style.top = ballY + 'px'; |
|
paddleLeft.style.top = paddleLeftY + 'px'; |
|
paddleRight.style.top = paddleRightY + 'px'; |
|
|
|
requestAnimationFrame(update); |
|
} |
|
|
|
function resetBall(side) { |
|
isGamePaused = true; |
|
|
|
if (side === 'left') { |
|
ballX = paddleWidth + 10; |
|
ballY = paddleLeftY + paddleHeight / 2; |
|
ballSpeedX = Math.abs(ballSpeedX); |
|
} else { |
|
ballX = window.innerWidth - paddleWidth - 25; |
|
ballY = paddleRightY + paddleHeight / 2; |
|
ballSpeedX = -Math.abs(ballSpeedX); |
|
} |
|
|
|
ballSpeedY = 0; |
|
} |
|
|
|
|
|
update(); |