How To Create Ping Pong Game With Javascript

In this tutorial we will learn to create fun ping pong game with HTML,CSS and Javascript

HTML

<body>
    <canvas id="gameCanvas" width="600" height="500"></canvas>
</body>

JS

let canvas;
let canvasContext;
let ball = {
    x: 50,
    speedX: 7,
    y: 250,
    speedY: 3,
    radius: 8
}
let paddle = {
    height: 85,
    width: 10,
}
let paddleLeft = {
    posY: 200,
    move_up: false,
    move_down: false,
}
let paddleRight = {
    posY: 200
}
const WINNING_SCORE = 5;
let display_winner = false;
let score = {
    player1: 0,
    player2: 0
}

document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, false);

window.addEventListener("load", (event) => {
    canvas = document.querySelector("#gameCanvas");
    canvasContext = canvas.getContext('2d');
    let framesPerSecond = 30;
    setInterval(function () {
        animate();
        drawCanvas();

    }, 1000 / framesPerSecond);
    canvas.addEventListener('click', handleClick)
});

function drawCanvas() {
    drawRect(0, 0, canvas.width, canvas.height, "#000");
    if (display_winner) {
        canvasContext.fillStyle = '#fff';
        if (score.player1 >= WINNING_SCORE) {
            canvasContext.fillText("Player Left Won", 250, 100);
        }
        if (score.player2 >= WINNING_SCORE) {
            canvasContext.fillText("Player Right Won", 250, 100);
        }
        canvasContext.fillText("Click To Continue", 250, 450);
        return;
    }
    drawCircle(ball.x, ball.y, ball.radius, '#fff');
    drawRect(canvas.width - 585, paddleLeft.posY, paddle.width, paddle.height, '#fff');
    drawRect(canvas.width - 25, paddleRight.posY, paddle.width, paddle.height, '#fff');

    canvasContext.fillText(score.player1, 100, 100);
    canvasContext.fillText(score.player2, canvas.width - 100, 100);
}
function drawRect(leftX, topY, width, height, drawColor) {
    canvasContext.fillStyle = drawColor;
    canvasContext.fillRect(leftX, topY, width, height)
}
function drawCircle(centerX, centerY, radius, drawColor) {
    canvasContext.fillStyle = drawColor;
    canvasContext.beginPath();
    canvasContext.arc(centerX, centerY, radius, 0, Math.PI * 2, true);
    canvasContext.fill();
}

function animate() {
    if (display_winner) {
        return
    }
    ball.x += ball.speedX;
    ball.y += ball.speedY;
    if (ball.x > canvas.width - 5) {
        score.player1++;
        ballReset();
    }
    if (ball.x < 0) {
        score.player2++;
        ballReset();
    }
    if (ball.y > canvas.height - 5) {
        ball.speedY = -ball.speedY;
    }
    if (ball.y < 0) {
        ball.speedY = -ball.speedY;
    }
    //paddleLeft Movement
    if (paddleLeft.move_up) {
        paddleLeft.posY = Math.max(paddleLeft.posY - 7, 0);
    }
    else if (paddleLeft.move_down) {
        paddleLeft.posY = Math.min(paddleLeft.posY + 7, canvas.height - paddle.height);
    }
    //ball and paddleLeft collision
    if (ball.y - 8 > paddleLeft.posY && ball.y + 8 < paddleLeft.posY + paddle.height && ball.x - 8 < canvas.width - 575) {
        ball.speedX = -ball.speedX;
        let deltaY = ball.y - (paddleLeft.posY + paddle.height / 2);
        ball.speedY = deltaY * 0.35
    }
    //ball and paddleRight collision
    if (ball.y - 8 > paddleRight.posY && ball.y + 8 < paddleRight.posY + paddle.height && ball.x + 8 > canvas.width - 25) {
        ball.speedX = -ball.speedX;
        let deltaY = ball.y - (paddleRight.posY + paddle.height / 2);
        ball.speedY = deltaY * 0.35
    }
    paddleRightMove();
}

function keyDownHandler(e) {
    if (e.key === "Up" || e.key === "ArrowUp") {
        paddleLeft.move_up = true;
    } else if (e.key === "Down" || e.key === "ArrowDown") {
        paddleLeft.move_down = true;
    }
}

function keyUpHandler(e) {
    if (e.key === "Up" || e.key === "ArrowUp") {
        paddleLeft.move_up = false;
    } else if (e.key === "Down" || e.key === "ArrowDown") {
        paddleLeft.move_down = false;
    }
}

function paddleRightMove() {
    let paddleRightCenter = paddleRight.posY + (paddle.height / 2);
    if (paddleRightCenter < ball.y - 20) {
        paddleRight.posY = Math.min(paddleRight.posY + 7, canvas.height - paddle.height);
    } else if (paddleRightCenter > ball.y + 20) {
        paddleRight.posY = Math.max(paddleRight.posY - 7, 0);
    }
}

function ballReset() {
    if (score.player1 >= WINNING_SCORE || score.player2 >= WINNING_SCORE) {
        display_winner = true;
    }
    ball.speedX = -ball.speedX
    ball.x = canvas.width / 2;
    ball.y = canvas.height / 2
}

function handleClick() {
    if (display_winner) {
        score.player1 = 0;
        score.player2 = 0;
        paddleLeft.posY = 200;
        paddleRight.posY = 200;
        display_winner = false;
    }
}