File size: 4,777 Bytes
a3b97ad a4b6ccc a3b97ad ae20685 a4b6ccc ae20685 a3b97ad 5994a14 ae20685 5994a14 ae20685 5994a14 ae20685 a4b6ccc 5994a14 a3b97ad ae20685 b00bf58 484355f ae20685 484355f 25cc5de 8d12a80 a3b97ad a4b6ccc ae20685 a4b6ccc a3b97ad ae20685 a3b97ad ae20685 a4b6ccc a3b97ad ae20685 fc7647d ae20685 fc7647d ae20685 fc7647d ae20685 fc7647d a3b97ad a4b6ccc ae20685 a4b6ccc ae20685 a4b6ccc ae20685 a4b6ccc ae20685 a4b6ccc ae20685 a3b97ad 5994a14 a3b97ad |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
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;
// Closest point on paddle to ball's center
let closestX = ballX;
if (isLeftPaddle) {
closestX = paddleRight;
} else {
closestX = paddleX;
}
let closestY = ballY;
if (ballY < paddleTop) {
closestY = paddleTop;
} else if (ballY > paddleBottom) {
closestY = paddleBottom;
}
// Vector from ball to closest point
const dx = ballX - closestX;
const dy = ballY - closestY;
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= ballRadius) {
// Collision occurs
// Calculate normal vector
const normalX = isLeftPaddle ? 1 : -1;
const normalY = 0;
// Current velocity
const velocity = { x: ballSpeedX, y: ballSpeedY };
// Reflect velocity over the normal
const dot = velocity.x * normalX + velocity.y * normalY;
const reflected = {
x: velocity.x - 2 * dot * normalX,
y: velocity.y - 2 * dot * normalY
};
// Adjust Y velocity based on hit position
const hitPosition = (closestY - (paddleTop + paddleHeight / 2)) / (paddleHeight / 2);
const angle = hitPosition * maxAngle * (Math.PI / 180);
reflected.y = Math.sin(angle) * Math.abs(reflected.x);
// Set new velocity
ballSpeedX = reflected.x;
ballSpeedY = reflected.y;
// Reposition ball outside the paddle
const overlap = ballRadius - distance;
ballX += normalX * overlap;
}
}
function update() {
if (!isGamePaused) {
let previousBallX = ballX;
ballX += ballSpeedX;
ballY += ballSpeedY;
// Ball collision with top and bottom walls
if (ballY <= 0 || ballY >= window.innerHeight - ballSize) {
ballSpeedY = -ballSpeedY;
}
// Check collision with left paddle using swept collision detection
handlePaddleCollision(paddleLeftY, paddleWidth, true);
// Check collision with right paddle using swept collision detection
handlePaddleCollision(paddleRightY, window.innerWidth - paddleWidth - 25, false);
// Ball out of bounds
if (ballX <= 0) {
botScore++;
botScoreDisplay.textContent = botScore;
resetBall('right');
} else if (ballX >= window.innerWidth) {
playerScore++;
playerScoreDisplay.textContent = playerScore;
resetBall('left');
}
}
// Bot AI movement
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;
}
// Start the game loop
update(); |