Open In App

Pong Game in JavaScript

Improve
Improve
Like Article
Like
Save
Share
Report

Pong game is a two-player table tennis-themed video game. The game involves two paddles and a moving ball. The players have to move paddles in an upwards or downward direction and save the ball from getting hit by the wall. If the ball hits the wall then it’s a score for another player.

Prerequisite: Must be aware of HTML, CSS, and JavaScript.

Procedure:

  • Create an HTML file with the name index.html.
  • Create a CSS file with the name styles.css and link it in the index.html file using the link tag.
  • Create a JS file with the name index.js and link it to the index.html file using a script tag.
  • Create a div for the game board, ball, and 2 divs for paddles, i.e. player-1 and player-2.
  • Give some style to your game in the CSS file.
  • Get a reference to paddles, balls, and game boards in JS.
  • Create a function in the index.js file with the name move ball.
  • Give the ball a random direction and a random speed by changing the x and y coordinates of the ball.
  • Apply collision with the ball and the game board’s top/bottom side, i.e. if the ball touches the top/bottom of the board then multiply -1 * y velocity of the ball.
  • Apply collision with the ball and game left and right sides of the game board. i.e. increase the score and change the game state to serve the state.
  • Apply collision with the ball and paddles. i.e. multiply -1 * by x velocity of the ball.

Direction to play:

  • To Start the Game Press the “ENTER” key.
  • Player 1: Player 1 can control the left side paddle i.e, PADDLE_1 by using the ‘W‘ key to move upwards and to go downwards ‘S‘ key should be used.
  • Player 2: Player 2 can control the left side paddle i.e, PADDLE_2 by using the ‘UP Arrow‘ key to move upwards and to go downwards ‘Down Arrow‘ key should be used.

HTML Code: In this section, we will create the basic structure of the game

CSS Code: In this section, we will create the design of the game

JavaScript Code: In this section, we will create the logic for scoring and movement in the game

HTML




<!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>
    <link rel="stylesheet" href="style.css">
</head>
  
<body>
    <div class="board">
        <div class='ball'>
            <div class="ball_effect"></div>
        </div>
        <div class="paddle_1 paddle"></div>
        <div class="paddle_2  paddle"></div>
        <h1 class="player_1_score">0</h1>
        <h1 class="player_2_score">0</h1>
        <h1 class="message">
            Press Enter to Play Pong
        </h1>
    </div>
      
    <script src="index.js"></script>
</body>
  
</html>


CSS




* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}
  
body {
    height: 100vh;
    width: 100vw;
    background-image: linear-gradient(
            to top, #ffda77, #ffa45b);
    display: flex;
    justify-content: center;
    align-items: center;
}
  
.board {
    height: 85vh;
    width: 80vw;
    background-image: linear-gradient(
            to right, #5c6e91, #839b97);
    border-radius: 14px;
}
  
.ball {
    height: 30px;
    width: 30px;
    border-radius: 50%;
    position: fixed;
    top: calc(50% - 15px);
    left: calc(50% - 15px);
}
  
.ball_effect {
    height: 100%;
    width: 100%;
    border-radius: 100px;
    animation: spinBall 0.1s linear infinite;
    box-shadow: inset 0 0 18px #fff,
        inset 6px 0 18px violet,
        inset -6px 0 18px #0ff,
        inset 6px 0 30px violet,
        inset -6px 0 30px #0ff,
        0 0 18px #fff, -4px 0 18px
        violet, 4px 0 18px #0ff;
}
  
@keyframes spinBall {
    100% {
        -webkit-transform: rotate(360deg);
        transform: rotate(360deg);
    }
}
  
.paddle {
    height: 100px;
    width: 18px;
    border-radius: 50%;
    position: fixed;
}
  
.paddle_1 {
    top: calc(7.5vh + 55px);
    left: calc(10vw + 30px);
    box-shadow: inset 0 0 18px #fff,
        inset -6px 0 18px #f3bad6,
        inset 6px 0 18px #0ff,
        inset -6px 0 30px #f3bad6,
        inset 6px 0 30px #0ff,
        0 0 18px #fff, 4px 0 18px
        #f3bad6, -4px 0 18px #0ff;
}
  
.paddle_2 {
    top: calc(85vh + 7.5vh - 100px - 55px);
    right: calc(10vw + 30px);
    box-shadow: inset 0 0 18px #fff,
        inset 6px 0 18px #f3bad6,
        inset -6px 0 18px #0ff,
        inset 6px 0 30px #f3bad6,
        inset -6px 0 30px #0ff,
        0 0 18px #fff, -4px 0 18px
        #f3bad6, 4px 0 18px #0ff;
}
  
.player_1_score {
    height: 50px;
    width: 50px;
    color: chartreuse;
    position: fixed;
    left: 30vw;
    margin-top: 30px;
}
  
.player_2_score {
    height: 50px;
    width: 50px;
    color: chartreuse;
    position: fixed;
    left: 70vw;
    margin-top: 30px;
}
  
.message {
    position: fixed;
    /* color: #48426d; */
    height: 10vh;
    width: 30vw;
    color: #c9cbff;
    left: 38vw;
    margin: 30px auto auto auto;
}


Javascript




let gameState = 'start';
let paddle_1 = document.querySelector('.paddle_1');
let paddle_2 = document.querySelector('.paddle_2');
let board = document.querySelector('.board');
let initial_ball = document.querySelector('.ball');
let ball = document.querySelector('.ball');
let score_1 = document.querySelector('.player_1_score');
let score_2 = document.querySelector('.player_2_score');
let message = document.querySelector('.message');
let paddle_1_coord = paddle_1.getBoundingClientRect();
let paddle_2_coord = paddle_2.getBoundingClientRect();
let initial_ball_coord = ball.getBoundingClientRect();
let ball_coord = initial_ball_coord;
let board_coord = board.getBoundingClientRect();
let paddle_common =
    document.querySelector('.paddle').getBoundingClientRect();
  
let dx = Math.floor(Math.random() * 4) + 3;
let dy = Math.floor(Math.random() * 4) + 3;
let dxd = Math.floor(Math.random() * 2);
let dyd = Math.floor(Math.random() * 2);
  
document.addEventListener('keydown', (e) => {
if (e.key == 'Enter') {
    gameState = gameState == 'start' ? 'play' : 'start';
    if (gameState == 'play') {
    message.innerHTML = 'Game Started';
    message.style.left = 42 + 'vw';
    requestAnimationFrame(() => {
        dx = Math.floor(Math.random() * 4) + 3;
        dy = Math.floor(Math.random() * 4) + 3;
        dxd = Math.floor(Math.random() * 2);
        dyd = Math.floor(Math.random() * 2);
        moveBall(dx, dy, dxd, dyd);
    });
    }
}
if (gameState == 'play') {
    if (e.key == 'w') {
    paddle_1.style.top =
        Math.max(
        board_coord.top,
        paddle_1_coord.top - window.innerHeight * 0.06
        ) + 'px';
    paddle_1_coord = paddle_1.getBoundingClientRect();
    }
    if (e.key == 's') {
    paddle_1.style.top =
        Math.min(
        board_coord.bottom - paddle_common.height,
        paddle_1_coord.top + window.innerHeight * 0.06
        ) + 'px';
    paddle_1_coord = paddle_1.getBoundingClientRect();
    }
  
    if (e.key == 'ArrowUp') {
    paddle_2.style.top =
        Math.max(
        board_coord.top,
        paddle_2_coord.top - window.innerHeight * 0.1
        ) + 'px';
    paddle_2_coord = paddle_2.getBoundingClientRect();
    }
    if (e.key == 'ArrowDown') {
    paddle_2.style.top =
        Math.min(
        board_coord.bottom - paddle_common.height,
        paddle_2_coord.top + window.innerHeight * 0.1
        ) + 'px';
    paddle_2_coord = paddle_2.getBoundingClientRect();
    }
}
});
  
function moveBall(dx, dy, dxd, dyd) {
if (ball_coord.top <= board_coord.top) {
    dyd = 1;
}
if (ball_coord.bottom >= board_coord.bottom) {
    dyd = 0;
}
if (
    ball_coord.left <= paddle_1_coord.right &&
    ball_coord.top >= paddle_1_coord.top &&
    ball_coord.bottom <= paddle_1_coord.bottom
) {
    dxd = 1;
    dx = Math.floor(Math.random() * 4) + 3;
    dy = Math.floor(Math.random() * 4) + 3;
}
if (
    ball_coord.right >= paddle_2_coord.left &&
    ball_coord.top >= paddle_2_coord.top &&
    ball_coord.bottom <= paddle_2_coord.bottom
) {
    dxd = 0;
    dx = Math.floor(Math.random() * 4) + 3;
    dy = Math.floor(Math.random() * 4) + 3;
}
if (
    ball_coord.left <= board_coord.left ||
    ball_coord.right >= board_coord.right
) {
    if (ball_coord.left <= board_coord.left) {
    score_2.innerHTML = +score_2.innerHTML + 1;
    } else {
    score_1.innerHTML = +score_1.innerHTML + 1;
    }
    gameState = 'start';
  
    ball_coord = initial_ball_coord;
    ball.style = initial_ball.style;
    message.innerHTML = 'Press Enter to Play Pong';
    message.style.left = 38 + 'vw';
    return;
}
ball.style.top = ball_coord.top + dy * (dyd == 0 ? -1 : 1) + 'px';
ball.style.left = ball_coord.left + dx * (dxd == 0 ? -1 : 1) + 'px';
ball_coord = ball.getBoundingClientRect();
requestAnimationFrame(() => {
    moveBall(dx, dy, dxd, dyd);
});
}


Output: Click here for live code output



Last Updated : 15 Feb, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads