Building a Pong Game in JavaScript
March 7th, 2026 11:29 PM Mr. Q Categories: JavaScript
If you’re ready to create a classic Pong game using JavaScript, this guide will outline the essential requirements and structure needed to develop your game. We’ll cover everything from the game environment to player controls, ball mechanics, and game states. Let’s get started!
1. Game Environment
- Screen Width: 800 pixels
- Screen Height: 400 pixels
- Background Color: Black
- FPS (Frames Per Second): 60
2. Player Setup
- Controls for Player 1:
- Move Up: W Key
- Move Down: S Key
- Controls for Player 2:
- Move Up: Up Arrow Key
- Move Down: Down Arrow Key
- Player Selection:
- Single-player mode can be considered, but initially set up for two players.
3. Paddle Properties
| Paddle Name | Width (pixels) | Height (pixels) | Speed (pixels/frame) | Position (x, y) | Capabilities |
|---|---|---|---|---|---|
| Player 1 Paddle | 10 | 80 | 5 | (30, 50) | Moves up and down; can block the ball. |
| Player 2 Paddle | 10 | 80 | 5 | (760, 50) | Moves up and down; can block the ball. |
4. Ball Properties
| Ball Name | Diameter (pixels) | Speed (pixels/frame) | Position (x, y) | Capabilities |
|---|---|---|---|---|
| Game Ball | 10 | 4 | (400, 200) | Bounces off paddles and walls. |
5. Game States
- Game States: The game will manage different states for better gameplay experience:
- Start: Initial screen displaying the title and instructions.
- Playing: Main game loop where players interact with paddles and the ball.
- Game Over: Displays the score and options to restart or exit.
- Transition Between States:
- Implement a state management system to facilitate smooth transitions and handle user input based on the current game state.
6. Game Loop Details
- Initialization:
- Set up the canvas and context.
- Load assets (if any).
- Main Game Loop:
- Update:
- Update paddle positions based on player input.
- Update ball position and check for collisions with paddles and walls.
- Render:
- Clear the canvas and redraw all elements (paddles and ball).
- Check for Scoring:
- Implement scoring logic for when the ball passes a paddle.
- Pause/Resume:
- Implement functionality to pause and resume the game as needed.
7. Sounds and Music
- Background Music: Optional ambient music.
- Sound Effects:
- Paddle hit sound when the ball hits a paddle.
- Scoring sound when a player scores.
Example Class Structure
Here’s a simple structure for the classes you might use in your game, including state management:
class Game {
constructor() {
this.state = 'start'; // Possible states: 'start', 'playing', 'gameOver'
this.player1 = new Paddle(30, 50); // Player 1 paddle
this.player2 = new Paddle(760, 50); // Player 2 paddle
this.ball = new Ball(400, 200);
this.score1 = 0;
this.score2 = 0;
this.init();
}
init() {
// Set up canvas and context
// Load assets if needed
this.startScreen();
}
startScreen() {
// Display start screen with options and instructions
}
startGame() {
this.state = 'playing';
this.gameLoop();
}
gameLoop() {
if (this.state === 'playing') {
this.update();
this.render();
requestAnimationFrame(() => this.gameLoop());
} else if (this.state === 'gameOver') {
this.showGameOver();
}
}
update() {
// Update player paddle positions based on input
this.player1.update();
this.player2.update();
this.ball.update(this.player1, this.player2);
}
render() {
// Clear canvas and draw paddles and ball
const ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
this.player1.draw(ctx);
this.player2.draw(ctx);
this.ball.draw(ctx);
}
showGameOver() {
// Display game over screen and score
}
}
class Paddle {
constructor(x, y) {
this.width = 10;
this.height = 80;
this.speed = 5;
this.x = x;
this.y = y;
this.score = 0;
}
moveUp() {
this.y -= this.speed;
if (this.y < 0) this.y = 0; // Prevent going out of bounds
}
moveDown() {
this.y += this.speed;
if (this.y + this.height > canvas.height) this.y = canvas.height - this.height; // Prevent going out of bounds
}
update() {
// Logic to update paddle position based on input
}
draw(ctx) {
ctx.fillStyle = "#FFFFFF"; // Paddle color
ctx.fillRect(this.x, this.y, this.width, this.height);
}
}
class Ball {
constructor(x, y) {
this.diameter = 10;
this.x = x;
this.y = y;
this.speedX = 4; // Horizontal speed
this.speedY = 4; // Vertical speed
}
update(paddle1, paddle2) {
this.x += this.speedX;
this.y += this.speedY;
// Collision with top and bottom walls
if (this.y <= 0 || this.y + this.diameter >= canvas.height) {
this.speedY = -this.speedY; // Reverse vertical direction
}
// Collision with paddles
if (
(this.x <= paddle1.x + paddle1.width && this.y + this.diameter >= paddle1.y && this.y <= paddle1.y + paddle1.height) ||
(this.x + this.diameter >= paddle2.x && this.y + this.diameter >= paddle2.y && this.y <= paddle2.y + paddle2.height)
) {
this.speedX = -this.speedX; // Reverse horizontal direction
}
// Scoring
if (this.x < 0) {
// Player 2 scores
paddle2.score++;
this.reset();
} else if (this.x > canvas.width) {
// Player 1 scores
paddle1.score++;
this.reset();
}
}
reset() {
this.x = canvas.width / 2; // Reset to center
this.y = canvas.height / 2;
this.speedX = 4 * (Math.random() > 0.5 ? 1 : -1); // Randomize horizontal direction
}
draw(ctx) {
ctx.fillStyle = "#FFFFFF"; // Ball color
ctx.fillRect(this.x, this.y, this.diameter, this.diameter);
}
}
// Example instantiation
const game = new Game();
Conclusion
By following these requirements and structure, you can build a classic Pong game in JavaScript. The clear organization of components will allow you to create a reusable codebase that can be expanded with new features and improvements in the future. Enjoy coding your Pong game!