Pong Game in HTML, JS and CSS [with Demo and Source Code]

Do not miss this exclusive book on Binary Tree Problems. Get it now for free.

Table of Contents

  1. Introduction
  2. Setting up the game
  3. Defining Variables
  4. Updating Game Logic
  5. Rendering the Game
  6. Determining the Winner
  7. Final Product
  8. Conclusion

Introduction

Pong is a timeless classic in the world of video games, and building it from scratch using JavaScript can be a fun and educational experience. In this article at OpenGenus, we will explore the process of creating a fully functional Pong game using JavaScript and HTML5 canvas.

We will delve into the game's basic rules, implement the necessary game logic, and understand how the different components interact to create an engaging gameplay experience.

Game Rules:
Pong is a two-player game where each player controls a paddle. The goal is to hit the ball past the opponent's paddle and score points. The following rules govern the gameplay:

  1. Paddle Movement: Players control their paddles vertically, moving them up or down within their designated half of the game board. The paddle follows the movement of the mouse cursor or touch input.
  2. Ball Mechanics: The ball starts at the center of the game board and moves at a constant speed. It bounces off the paddles, the top, and the bottom edges of the canvas.
  3. Scoring Points: When a player fails to hit the ball with their paddle, the opposing player scores a point. The ball is then reset to the center, and the game continues.
  4. Winning the Game: The game is typically played to a predetermined winning score. The first player to reach or exceed this score wins the game.

Setting up the Game

To begin, we need to set up the basic structure of our game. We create an HTML file and embed a canvas element with an id of "gc" to serve as our game board. The canvas acts as a drawing surface that allows us to render the game's elements.

<canvas id="gc" width="640" height="480"></canvas>

Defining Variables:

Next, we define several variables that will hold the positions, sizes, and scores of various game components. These variables include paddle positions (paddle1_y and paddle2_y), paddle dimensions (paddle_thickness and paddle_height), ball position (ball_x and ball_y), ball size (ball_dimension), speed variables (x_velocity, y_velocity, and computer_speed), and player scores (player1_score and player2_score). We will set numbers that allow for smooth interactions with the game. You can always change the numbers if you'd like.

// set paddle position
var paddle1_y = 40;
var paddle2_y = 40;

// set paddle size
var paddle_thickness = 10;
var paddle_height = 100;

// set ball position
var ball_x = 50;
var ball_y = 50;

// set ball size
var ball_dimension = 6;

// set speed variables
var x_velocity = 5;
var y_velocity = x_velocity;
var computer_speed = 3;

// create variables to hold the player scores
var player1_score = 0;
var player2_score = 0;

// Set the score that wins
var winning_score = 5;
var reset_game = false;

Handling User Input:

We add an event listener to the canvas element, allowing us to control the movement of one of the paddles. By tracking the mouse's vertical position within the canvas, we can adjust the y-coordinate of the paddle accordingly. This enables the player to control the paddle's movement and participate in the game. We will listen to user's mouse movement and have the paddle follow user's mouse here.

canvas.addEventListener('mousemove', function (e) {
				paddle1_y = e.clientY - paddle_height/2;
		});

Updating Game Logic:

To make the game interactive, we implement several functions that handle critical aspects of the game's logic. These functions include resetting the ball's position and direction (reset_ball), moving the ball (move_ball), controlling the AI paddle's movement (computer_paddle), and bouncing the ball off various surfaces (bounce_off).

reset_ball : the ball will be reset automatically when someone scores and the location will be at the center of the canvas. We will also reset the velocity of the ball and the ball will go towards whoever lost.

move_ball : we simply change the x and y position of the ball by adding the velocity to it at each frame.

computer_paddle: the AI will move towards the ball at any moment to try to save the ball.

bounce_off: we add our collision detection logic here. Whenever the position of the ball has contact with the paddle the ball should bounce off. We also need to add the logic where the bounce should bounce off if it touches the top or the bottom of the canvas.

function reset_ball() {
				// Reset the ball's placement and direction after scoring
				ball_x = canvas.width / 2;
				ball_y = canvas.height/ 2;
				x_velocity = -x_velocity;
				y_velocity = 10;
		}
	
		function move_ball(){
				// Get the ball moving
				ball_x += x_velocity;
				ball_y += y_velocity;
		}

		function computer_paddle() {
				// Move the player 2 AI paddle up or down
				// based on the 'y' position of the ball
				if (paddle2_y + paddle_height/2 < ball_y){
						paddle2_y += computer_speed;
				} else {
						paddle2_y -= computer_speed;
				}
		}
	
		function bounce_off(){
			// Bounce the ball off the top of the screen
				if (ball_y < 0 && y_velocity < 0){
						y_velocity = -y_velocity;
				}

				// Bounce the ball off the bottom of the screen
				if (ball_y > canvas.height && y_velocity > 0){
						y_velocity = -y_velocity;
				}

				// Bounce the ball off the left side (where paddle)
				// Otherwise award a point to the other player
				// and reset the ball
				if (ball_x < 0){
						if (ball_y > paddle1_y && ball_y < paddle1_y + paddle_height) {
								x_velocity =- x_velocity;
								delta_y = ball_y - (paddle1_y + paddle_height/2);
								y_velocity = delta_y * 0.3;
						} else {
								player2_score++;
								reset_ball();
						}
				}

				// Bounce the ball off the right side (where paddle)
				// Otherwise award a point to the other player
				// and reset the ball
				if (ball_x > canvas.width){
						if (ball_y > paddle2_y && ball_y < paddle2_y + paddle_height) {
								x_velocity =- x_velocity;
								delta_y = ball_y - (paddle2_y + paddle_height/2);
								y_velocity = delta_y * 0.3;
						} else {
								player1_score++;
								reset_ball();
						}
				}
		}

Rendering the Game:

In the setup_canvas function, we utilize the HTML5 canvas context to draw the game elements. We set the canvas's background color, draw the paddles, ball, and score boxes, and display the player scores using text rendering functions. This function is called repeatedly within the main game loop to ensure that the game is constantly updated and rendered on the screen.

function setup_canvas() {
				//fill in the canvas with objects
				context.fillStyle = 'blue';
				context.fillRect(0, 0, canvas.width, canvas.height);

				// Add the paddles' color
				context.fillStyle = 'white';

				// Add paddle 1
				context.fillRect(0, paddle1_y, paddle_thickness, paddle_height);

				// Add paddle 2
				context.fillRect(canvas.width-paddle_thickness, paddle2_y, paddle_thickness, paddle_height);

				// Draw the ball
				context.fillRect(ball_x-ball_dimension/2, ball_y-ball_dimension/2, ball_dimension, ball_dimension);

				// Add Score board boxes
				context.fillRect(90, canvas.height - 95, 40, 40);
				context.fillRect(canvas.width - 110, 65, 40, 40);
			
				// Add the score text
				context.font = "18px serif";
				context.fillText("Your Score", 70, canvas.height - 40);
				context.fillText("AI Score", canvas.width - 120, 60);
				context.fillStyle = 'black';
				context.font = "48px serif";
				context.fillText(player1_score, 100, canvas.height - 60);
				context.fillText(player2_score, canvas.width - 100, 100);
		}

Determining the Winner:

By checking the player scores during each iteration of the game loop, we determine if a player has reached the winning score. Once a player wins, we stop the game loop and display an end-game message, declaring the winner.

function did_player_win(){
			if(player1_score === winning_score || player2_score === winning_score){
				// set variable to reset game
				reset_game = true;
				// stop the game from running
				clearTimeout(run_game);
				context.fillStyle = 'white';
				context.font = "48px serif";
				context.fillText("End of Game", canvas.width/2 - canvas.width/6, canvas.height/2);
				if (player1_score === winning_score){
					context.font = "24px serif";
					context.fillText("You won!", canvas.width/2 - canvas.width/14, canvas.height/2 + 25);
				} 
				if (player2_score === winning_score){
					context.font = "24px serif";
					context.fillText("The AI won!", canvas.width/2 - canvas.width/14, canvas.height/2 + 25);
				}
			}
		}

Final Product

Conclusion:

By following the code provided and understanding the concepts behind it, you can create a fully functional Pong game using JavaScript and HTML5 canvas. This simple implementation provides a great starting point for learning game development fundamentals and can be expanded upon to add additional features and complexity. Have fun experimenting and enhancing the game to make it your own!

Sign up for FREE 3 months of Amazon Music. YOU MUST NOT MISS.