Pong Game in HTML
Overview
- A complete Pong game in one HTML file.
- Uses canvas for drawing and JavaScript for game logic.
- Supports two-player keyboard controls and automatic ball reset after scoring.
Controls
- Left paddle: W / S
- Right paddle: Arrow Up / Arrow Down
- Restart: R
What it includes
- Game loop with animation frame updates.
- Ball movement and wall/paddle collision.
- Score tracking for both players.
- Simple on-screen instructions.
HTML File
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Pong</title>
<style>
html, body {
margin: 0;
padding: 0;
background: #111;
color: #fff;
font-family: Arial, sans-serif;
height: 100%;
overflow: hidden;
}.wrap {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
gap: 12px;
}
canvas {
background: #000;
border: 2px solid #fff;
display: block;
}.hud {
display: flex;
gap: 24px;
font-size: 18px;
font-weight: bold;
}.help {
font-size: 14px;
color: #ccc;
text-align: center;
line-height: 1.5;
}
</style>
</head>
<body>
<div class="wrap">
<div class="hud">
<div>Left: <span id="scoreLeft">0</span></div>
<div>Right: <span id="scoreRight">0</span></div>
</div>
<canvas id="game" width="800" height="500"></canvas>
<div class="help">
Left paddle: W / S | Right paddle: ↑ / ↓ | Restart: R
</div>
</div>
<script>
const canvas = document.getElementById('game');
const ctx = canvas.getContext('2d');
const scoreLeftEl = document.getElementById('scoreLeft');
const scoreRightEl = document.getElementById('scoreRight');
const W = canvas.width;
const H = canvas.height;
const paddle = {
width: 12,
height: 90,
speed: 7
};
const left = {
x: 20,
y: H / 2 - paddle.height / 2,
dy: 0
};
const right = {
x: W - 20 - paddle.width,
y: H / 2 - paddle.height / 2,
dy: 0
};
const ball = {
x: W / 2,
y: H / 2,
r: 8,
dx: 5,
dy: 4
};
let scoreLeft = 0;
let scoreRight = 0;
const keys = {};
function resetBall(direction = 1) {
ball.x = W / 2;
ball.y = H / 2;
ball.dx = 5 * direction;
ball.dy = (Math.random() > 0.5? 4: -4);
}
function resetGame() {
scoreLeft = 0;
scoreRight = 0;
scoreLeftEl.textContent = scoreLeft;
scoreRightEl.textContent = scoreRight;
left.y = H / 2 - paddle.height / 2;
right.y = H / 2 - paddle.height / 2;
resetBall(1);
}
function clamp(val, min, max) {
return Math.max(min, Math.min(max, val));
}
function update() {
if (keys['w'] || keys['W']) left.y -= paddle.speed;
if (keys['s'] || keys['S']) left.y += paddle.speed;
if (keys['ArrowUp']) right.y -= paddle.speed;
if (keys['ArrowDown']) right.y += paddle.speed;
left.y = clamp(left.y, 0, H - paddle.height);
right.y = clamp(right.y, 0, H - paddle.height);
ball.x += ball.dx;
ball.y += ball.dy;
if (ball.y - ball.r <= 0 || ball.y + ball.r >= H) {
ball.dy *= -1;
}
const leftHit =
ball.x - ball.r <= left.x + paddle.width &&
ball.x - ball.r >= left.x &&
ball.y >= left.y &&
ball.y <= left.y + paddle.height;
const rightHit =
ball.x + ball.r >= right.x &&
ball.x + ball.r <= right.x + paddle.width &&
ball.y >= right.y &&
ball.y <= right.y + paddle.height;
if (leftHit && ball.dx < 0) {
ball.dx *= -1.05;
ball.dy += (ball.y - (left.y + paddle.height / 2)) * 0.15;
ball.x = left.x + paddle.width + ball.r;
}
if (rightHit && ball.dx > 0) {
ball.dx *= -1.05;
ball.dy += (ball.y - (right.y + paddle.height / 2)) * 0.15;
ball.x = right.x - ball.r;
}
if (ball.x + ball.r < 0) {
scoreRight++;
scoreRightEl.textContent = scoreRight;
resetBall(1);
}
if (ball.x - ball.r > W) {
scoreLeft++;
scoreLeftEl.textContent = scoreLeft;
resetBall(-1);
}
}
function drawCenterLine() {
ctx.fillStyle = '#444';
for (let y = 0; y < H; y += 30) {
ctx.fillRect(W / 2 - 2, y, 4, 18);
}
}
function draw() {
ctx.clearRect(0, 0, W, H);
drawCenterLine();
ctx.fillStyle = '#fff';
ctx.fillRect(left.x, left.y, paddle.width, paddle.height);
ctx.fillRect(right.x, right.y, paddle.width, paddle.height);
ctx.beginPath();
ctx.arc(ball.x, ball.y, ball.r, 0, Math.PI * 2);
ctx.fill();
}
function loop() {
update();
draw();
requestAnimationFrame(loop);
}
document.addEventListener('keydown', (e) => {
keys[e.key] = true;
if (e.key === 'r' || e.key === 'R') resetGame();
});
document.addEventListener('keyup', (e) => {
keys[e.key] = false;
});
resetGame();
loop();
</script>
</body>
</html>
```
How to use
- Save the code as `pong.html`.
- Open it in a browser.
- Play with the keyboard controls.