Here is free Pong Game source code built with HTML, CSS and JavaScript. Learn how to create and customize a classic two-player HTML5 browser game.
If you are learning HTML, CSS, and JavaScript and want to build a simple browser game, Pong is a great project to try.
Pong is one of the classic arcade games. The idea is very simple: two paddles move up and down while a ball travels between them. The goal is to stop the ball from passing your paddle and score points against your opponent.
This version is made with HTML5 Canvas and JavaScript. It does not require any external library, framework, or game engine. You can save the complete code in one HTML file and run it directly in your browser.
What Is a Pong Game?
Pong is a simple two-player arcade game based on table tennis.
Each player controls a paddle on one side of the screen. The ball moves across the game area and bounces from the top and bottom walls.
When the ball reaches a player’s side, the player must move the paddle into its path. If the ball passes the paddle, the other player receives a point.
Although the game looks simple, it is a useful project for learning game development because it involves animation, keyboard controls, collision detection, scoring, and game loops.
Features of This Pong Game
This free Pong game includes:
- Two-player gameplay
- HTML5 Canvas
- JavaScript game loop
- Keyboard controls
- Score counter
- Paddle movement
- Automatic ball reset
- Start and restart button
- Responsive game area
- No external libraries
- Single HTML file
- Easy-to-customize code
Free Pong Game Source Code
Below is the complete Pong game source code. You can copy it into a new HTML file and open it in a modern web browser.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pong Game</title>
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: Arial, sans-serif;
background: #111827;
color: white;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
padding: 20px;
}
.game-container {
width: 100%;
max-width: 900px;
text-align: center;
}
h1 {
margin-bottom: 10px;
font-size: 38px;
}
.description {
color: #cbd5e1;
margin-bottom: 18px;
}
.score-board {
display: flex;
justify-content: center;
gap: 80px;
margin-bottom: 15px;
font-size: 24px;
font-weight: bold;
}
.game-wrapper {
width: 100%;
background: #020617;
border: 3px solid #334155;
border-radius: 14px;
padding: 10px;
overflow: hidden;
}
canvas {
display: block;
width: 100%;
height: auto;
background: #000;
border-radius: 8px;
}
.controls {
margin-top: 18px;
color: #cbd5e1;
line-height: 1.7;
}
.start-btn {
margin-top: 18px;
padding: 12px 28px;
border: none;
border-radius: 8px;
background: #2563eb;
color: white;
font-size: 17px;
font-weight: bold;
cursor: pointer;
}
.start-btn:hover {
background: #1d4ed8;
}
@media (max-width: 600px) {
h1 {
font-size: 30px;
}
.score-board {
gap: 45px;
font-size: 20px;
}
}
</style>
</head>
<body>
<div class="game-container">
<h1>Pong Game</h1>
<p class="description">
Classic two-player Pong game built with HTML, CSS and JavaScript.
</p>
<div class="score-board">
<div>
Player 1:
<span id="player1Score">0</span>
</div>
<div>
Player 2:
<span id="player2Score">0</span>
</div>
</div>
<div class="game-wrapper">
<canvas id="gameCanvas" width="800" height="450"></canvas>
</div>
<div class="controls">
<strong>Player 1:</strong> W / S
|
<strong>Player 2:</strong> Arrow Up / Arrow Down
</div>
<button class="start-btn" id="startBtn">
Start Game
</button>
</div>
<script>
const canvas = document.getElementById("gameCanvas");
const ctx = canvas.getContext("2d");
const player1ScoreElement =
document.getElementById("player1Score");
const player2ScoreElement =
document.getElementById("player2Score");
const startBtn =
document.getElementById("startBtn");
const paddleWidth = 12;
const paddleHeight = 90;
const paddleSpeed = 7;
const ballSize = 12;
let player1 = {
x: 20,
y: canvas.height / 2 - paddleHeight / 2,
score: 0,
direction: 0
};
let player2 = {
x: canvas.width - 32,
y: canvas.height / 2 - paddleHeight / 2,
score: 0,
direction: 0
};
let ball = {
x: canvas.width / 2,
y: canvas.height / 2,
speedX: 5,
speedY: 4
};
let gameRunning = false;
const keys = {};
document.addEventListener("keydown", function(event) {
keys[event.key] = true;
});
document.addEventListener("keyup", function(event) {
keys[event.key] = false;
});
function resetBall(direction) {
ball.x = canvas.width / 2;
ball.y = canvas.height / 2;
ball.speedX = 5 * direction;
ball.speedY =
(Math.random() > 0.5 ? 1 : -1) * 4;
}
function resetGame() {
player1.score = 0;
player2.score = 0;
player1ScoreElement.textContent = 0;
player2ScoreElement.textContent = 0;
player1.y =
canvas.height / 2 - paddleHeight / 2;
player2.y =
canvas.height / 2 - paddleHeight / 2;
resetBall(
Math.random() > 0.5 ? 1 : -1
);
}
function update() {
if (!gameRunning) {
return;
}
// Player 1 controls
if (keys["w"] || keys["W"]) {
player1.y -= paddleSpeed;
}
if (keys["s"] || keys["S"]) {
player1.y += paddleSpeed;
}
// Player 2 controls
if (keys["ArrowUp"]) {
player2.y -= paddleSpeed;
}
if (keys["ArrowDown"]) {
player2.y += paddleSpeed;
}
// Keep paddles inside the game
player1.y = Math.max(
0,
Math.min(
canvas.height - paddleHeight,
player1.y
)
);
player2.y = Math.max(
0,
Math.min(
canvas.height - paddleHeight,
player2.y
)
);
// Move ball
ball.x += ball.speedX;
ball.y += ball.speedY;
// Top and bottom collision
if (
ball.y <= 0 ||
ball.y + ballSize >= canvas.height
) {
ball.speedY *= -1;
}
// Player 1 collision
if (
ball.x <= player1.x + paddleWidth &&
ball.x + ballSize >= player1.x &&
ball.y + ballSize >= player1.y &&
ball.y <= player1.y + paddleHeight &&
ball.speedX < 0
) {
ball.speedX *= -1;
ball.x =
player1.x + paddleWidth;
}
// Player 2 collision
if (
ball.x + ballSize >= player2.x &&
ball.x <= player2.x + paddleWidth &&
ball.y + ballSize >= player2.y &&
ball.y <= player2.y + paddleHeight &&
ball.speedX > 0
) {
ball.speedX *= -1;
ball.x =
player2.x - ballSize;
}
// Player 2 scores
if (ball.x < 0) {
player2.score++;
player2ScoreElement.textContent =
player2.score;
resetBall(1);
}
// Player 1 scores
if (ball.x > canvas.width) {
player1.score++;
player1ScoreElement.textContent =
player1.score;
resetBall(-1);
}
}
function draw() {
// Clear canvas
ctx.fillStyle = "#000";
ctx.fillRect(
0,
0,
canvas.width,
canvas.height
);
// Center line
ctx.strokeStyle = "#334155";
ctx.lineWidth = 3;
ctx.setLineDash([10, 12]);
ctx.beginPath();
ctx.moveTo(
canvas.width / 2,
0
);
ctx.lineTo(
canvas.width / 2,
canvas.height
);
ctx.stroke();
ctx.setLineDash([]);
// Player 1
ctx.fillStyle = "#22c55e";
ctx.fillRect(
player1.x,
player1.y,
paddleWidth,
paddleHeight
);
// Player 2
ctx.fillStyle = "#3b82f6";
ctx.fillRect(
player2.x,
player2.y,
paddleWidth,
paddleHeight
);
// Ball
ctx.fillStyle = "#ffffff";
ctx.fillRect(
ball.x,
ball.y,
ballSize,
ballSize
);
}
function gameLoop() {
update();
draw();
requestAnimationFrame(gameLoop);
}
startBtn.addEventListener(
"click",
function() {
if (!gameRunning) {
resetGame();
gameRunning = true;
startBtn.textContent =
"Restart Game";
} else {
resetGame();
}
}
);
draw();
gameLoop();
</script>
</body>
</html>
How to Run the Pong Game
You do not need to install anything to run this game.
Step 1: Create an HTML File
Open Notepad, VS Code, or another code editor.
Create a new file and name it:
index.html
Step 2: Paste the Source Code
Copy the complete code above and paste it into your HTML file.
Save the file.
Step 3: Open the File
Double-click the index.html file.
Your browser will open the Pong game and you can start playing immediately.
How to Play
This version supports two players.
Player 1
Use:
- W — Move Up
- S — Move Down
Player 2
Use:
- Arrow Up — Move Up
- Arrow Down — Move Down
The objective is to stop the ball from passing your paddle.
When the ball passes your opponent’s paddle, you receive one point.
How the Pong Game Works
The game uses the HTML5 Canvas element to draw the paddles, ball, and playing area.
You can also change the game so that the first player to reach a certain score wins.
For example, you could set the winning score to 10.
The JavaScript can check the score after every point and display a winner when someone reaches the target.
This is a good next step if you want to practice conditional statements and game states.
Make the Game More Advanced
Once you understand the basic version, there are many ways to improve it.
You could add:
- Sound effects
- Background music
- Single-player mode
- Computer-controlled opponent
- Difficulty levels
- Winning score
- Pause button
- Mobile touch controls
- Player names
- Different paddle designs
- Ball speed increases
- Power-ups
- High-score system
- Game animations
