Html5 Game Tutorial: Pong

Comments 2 Standard

This is a simple HTML5 version of the classic game of pong. Play against the computer for as many levels as you can. The computer gets faster and more competitive the higher the level gets. The game can easily be customized to grow/shrink the paddles and the computer’s difficulty if you’re looking for a challenge after you’ve finished putting the tutorial together. You’ll need a current version of a browser (Chrome, Firefox) that supports HTML5 in order to complete this tutorial. Enjoy!

Download the Code or Fork on Plunker or Try the Working Version

Create the HTML File

The beauty of html5 is that you can program it using javascript. This makes your html file small and super simple. All we need to do is create a canvas for the game and then include the javascript file:

<html>
<canvas id="battlePong"></canvas>
< script type="text/javascript" src="battlePong.js"></script>
</html>

Create the Javascript File

/**
* File: BattlePong.js
* Purpose: HTML5 pong game
* Author: Design1Online.com, LLC <jade@design1online.com>
* Created: 6/7/2016
**/

//global game variables
var game = {
 debug: true,
 canvas: null,
 canvasContext: null,
 frameRate: 1000,
 framesPerSecond: 30,
 fonts: {
 header: '30px Arial',
 regular: '15px Arial'
 },
 colors: {
 net: 'gray',
 background: 'black',
 header: 'red',
 text: 'white'
 },
 screens: {
 winner: false,
 startGame: true,
 levelUp: false,
 continue: false
 },
 ball: {
 x: 50,
 y: 50,
 speedX: 10,
 speedY: 4,
 threshold: 35,
 radius: 10,
 color: 'blue'
 },
 level: 1,
 pointsPerLevel: 3,
 player: {
 score: 0,
 lives: 5,
 paddle: {
 y: 250,
 thickness: 10,
 height: 100,
 color: 'green'
 }
 },
 computer: {
 score: 0,
 paddle: {
 y: 250,
 thickness: 10,
 height: 100,
 speed: 6,
 color: 'red'
 }
 }
};

/**
* Start the game when the window loads
**/
window.onload = function() {

 //init the canvas
 game.canvas = document.getElementById('battlePong');

 //adjust canvas to window size
 game.canvas.width = window.innerWidth - game.computer.paddle.thickness;
 game.canvas.height = window.innerHeight;

 //create the context
 game.canvasContext = game.canvas.getContext('2d');

 //add event listeners
 game.canvas.addEventListener('mousedown', mouseClickHandler);
 game.canvas.addEventListener('mousemove', mouseMoveHandler);

 //start buffering the screen
 setInterval(function() { buffer(); }, game.frameRate / game.framesPerSecond);
};

/**
* Figure out the player's mouse position
**/
function mouseMoveHandler(e) {
 var mousePos = mousePosition(e);
 game.player.paddle.y = mousePos.y - (game.player.paddle.height / 2);
}

/**
* Return the x,y coordinates of the mouse in
* relation to the screen
**/
function mousePosition(e) {
 var rect = game.canvas.getBoundingClientRect();
 var root = document.documentElement;

 return {
 x: e.clientX - rect.left - root.scrollLeft,
 y: e.clientY - rect.top - root.scrollTop
 };
}

/**
* Handle mouse clicks
**/
function mouseClickHandler(e) {

 if (game.debug) {
 console.log('mouseClickHandler()');
 }

 if (game.screens.startGame) {

 if (game.debug) {
 console.log('Removing start screen');
 }

 game.screens.startGame = false;
 }
 else if (game.screens.continue) {

 if (game.debug) {
 console.log('Removing start screen');
 }

 game.screens.continue = false;
 }
 else if (game.screens.levelUp) {

 if (game.debug) {
 console.log('Removing level up screen');
 }

 game.screens.levelUp = false;
 }
 else if (game.screens.winner) {

 resetGame();

 if (game.debug) {
 console.log('Removing winner screen, showing start screen');
 }

 game.player.score = 0;
 game.computer.score = 0;
 game.screens.winner = false;
 game.screens.startGame = true;
 }
}

/**
* Start the game
**/
function startGame() {

 if (game.debug) {
 console.log('Starting game...');
 }

 if (game.player.lives <= 0) {
 game.screens.winner = true;
 }

 game.ball.speedX = -game.ball.speedX;
 game.ball.x = game.canvas.width / 2;
 game.ball.y = game.canvas.height / 2;
}

/**
* Move the ball and the computer mouse paddle
**/
function move() {

 var deltaY = 0;

 //move computer paddle
 var center = game.computer.paddle.y + (game.computer.paddle.height / 2);

 if (center < game.ball.y - game.ball.threshold) {
 game.computer.paddle.y = game.computer.paddle.y + game.computer.paddle.speed;
 } else if (center > game.ball.y + game.ball.threshold) {
 game.computer.paddle.y = game.computer.paddle.y - game.computer.paddle.speed;
 }

 //move ball
 game.ball.x = game.ball.x + game.ball.speedX;
 game.ball.y = game.ball.y + game.ball.speedY;

 //check for paddle collisions
 hitCollision();

 if (game.ball.y < 0) {
 if (game.debug) {
 console.log('Inverting ball Y speed 1');
 }

 game.ball.speedY = -game.ball.speedY;
 }
 if (game.ball.y > game.canvas.height) {

 if (game.debug) {
 console.log('Inverting ball Y speed 2');
 }

 game.ball.speedY = -game.ball.speedY;
 }
}

/**
* Check for ball/paddle collisions
**/
function hitCollision()
{
 //player paddle check
 if (game.ball.x <= 0) {

 if (game.debug) {
 console.log('player paddle collision check');
 console.log('ball', game.ball);
 console.log('player paddle', game.player.paddle);
 console.log(
 'hit or miss',
 game.ball.y > game.player.paddle.y,
 game.ball.y < (game.player.paddle.y + game.player.paddle.height + game.ball.radius)
 );
 }

 if (game.ball.y > (game.player.paddle.y) &&
 game.ball.y < (game.player.paddle.y + game.player.paddle.height + game.ball.radius)
 ) {
 game.ball.speedX = -game.ball.speedX;

 deltaY = game.ball.y - (game.player.paddle.y + game.player.paddle.height / 2);
 game.ball.speedY = deltaY * 0.35;
 } else {
 game.computer.score++;
 game.player.lives--;
 game.screens.continue = true;
 startGame();
 }
 }

 //computer paddle check
 if (game.ball.x >= game.canvas.width) {

 if (game.debug) {
 console.log('player paddle collision check');
 console.log('ball', game.ball);
 console.log('player paddle', game.computer.paddle);
 console.log(
 'hit or miss',
 game.ball.y > game.computer.paddle.y,
 game.ball.y < (game.computer.paddle.y + game.computer.paddle.height + game.ball.height)
 );
 }

 if (game.ball.y > (game.computer.paddle.y) &&
 game.ball.y < (game.computer.paddle.y + game.computer.paddle.height + game.ball.radius)
 ) {
 game.ball.speedX = -game.ball.speedX;

 deltaY = game.ball.y - (game.computer.paddle.y + game.computer.paddle.height / 2);
 game.ball.speedY = deltaY * 0.35;
 } else {
 game.player.score++; //increase score

 //level up
 if (game.player.score > 0 && game.player.score % game.pointsPerLevel === 0) {
 game.player.lives++; //get another life
 game.level++; //level up
 game.computer.paddle.speed += 1.3; //increase computer paddle speed
 game.screens.levelUp = true;
 } else {
 game.screens.continue = true;
 }

 startGame();
 }
 }
}

/**
* Draw the game board
**/
function drawBoard() {

 //draw the net
 for (var i = 0; i < game.canvas.height; i += 10) {
 drawRectangle(game.canvas.width / 2 - 1, i, 2, 1, game.colors.net);
 }

 //draw the score text
 var offset = 100;

 //set the header text
 var header = "BattlePong!";
 game.canvasContext.fillStyle = game.colors.header;
 game.canvasContext.font = game.fonts.header;
 game.canvasContext.fillText(header, offset, 30);

 //set the colors and font style
 game.canvasContext.fillStyle = game.colors.net;
 game.canvasContext.font = game.fonts.regular;

 //set the score text
 var score = "Score: " + game.player.score;
 game.canvasContext.font = game.fonts.text;
 var scoreSize = game.canvasContext.measureText(score);
 game.canvasContext.fillText(score, offset + 5, 50);

 //set the lives text
 var lives = "Lives: " + game.player.lives;
 var livesSize = game.canvasContext.measureText(lives);
 game.canvasContext.fillText(lives, offset + scoreSize.width + 25, 50);

 //set the copyright text
 var copyright = "Games by design1online.com, LLC";
 var copyrightSize = game.canvasContext.measureText(copyright);
 game.canvasContext.fillText(copyright, game.canvas.width - copyrightSize.width - offset/4, game.canvas.height - offset/4);

 //player paddle
 drawRectangle(
 0,
 game.player.paddle.y,
 game.player.paddle.thickness,
 game.player.paddle.height,
 game.player.paddle.color
 );

 //computer paddle
 drawRectangle(
 game.canvas.width - game.computer.paddle.thickness,
 game.computer.paddle.y,
 game.computer.paddle.thickness,
 game.computer.paddle.height,
 game.computer.paddle.color
 );

 //ball
 drawBall(game.ball.x, game.ball.y, game.ball.radius, game.ball.color);
}

/**
* Draw the ball
**/
function drawBall(centerX, centerY, radius, color) {
 game.canvasContext.fillStyle = color;
 game.canvasContext.beginPath();
 game.canvasContext.arc(centerX, centerY, radius, 0, Math.PI * 2, true);
 game.canvasContext.fill();
}

/**
* Draw paddle
**/
function drawRectangle(leftX, topY, width, height, color) {
 game.canvasContext.fillStyle = color;
 game.canvasContext.fillRect(leftX, topY, width, height);
}

/**
* Reset for a new game
**/
function resetGame()
{

 if (game.debug) {
 console.log('Resetting game...');
 }

 game.level = 1;
 game.computer.paddle.speed = 6;
 game.player.score = 0;
 game.computer.score = 0;
 game.player.lives = 5;
}

/**
* Draw the winner screen
**/
function screenWinner() {
 var center = game.canvas.width / 2;
 var height = game.canvas.height / 2;
 var header = "Game Over!";
 var score = "Score: " + game.player.score;

 //set the header text
 game.canvasContext.fillStyle = game.colors.header;
 game.canvasContext.font = game.fonts.header;
 var headerSize = game.canvasContext.measureText(header);
 game.canvasContext.fillText(header, center - headerSize.width/2, height);

 //set the score text
 game.canvasContext.fillStyle = game.colors.text;
 game.canvasContext.font = game.fonts.regular;
 var scoreSize = game.canvasContext.measureText(score);
 game.canvasContext.fillText(score, center - scoreSize.width/2, height + 25);
}

/**
* Draw the continue screen
**/
function screenContinue() {
 var center = game.canvas.width / 2;
 var height = game.canvas.height / 2;

 //set the header text
 var header = "Missed Ball!";
 game.canvasContext.fillStyle = game.colors.header;
 game.canvasContext.font = game.fonts.header;
 var headerSize = game.canvasContext.measureText(header);
 game.canvasContext.fillText(header, center - headerSize.width/2, height);

 //set the info text
 var info = "Click anywhere to start the next ball";
 game.canvasContext.fillStyle = game.colors.text;
 game.canvasContext.font = game.fonts.regular;
 var infoSize = game.canvasContext.measureText(info);
 game.canvasContext.fillText(info, center - infoSize.width/2, height + 25);
}

/**
* Draw the level up screen
**/
function screenLevelUp() {
 var center = game.canvas.width / 2;
 var height = game.canvas.height / 2;

 //set header
 var header = "Level " + game.level;
 game.canvasContext.fillStyle = game.colors.header;
 game.canvasContext.font = game.fonts.header;
 var headerSize = game.canvasContext.measureText(header);
 game.canvasContext.fillText(header, center - headerSize.width/2, height);

 //set the regular text color and font
 game.canvasContext.fillStyle = game.colors.text;
 game.canvasContext.font = game.fonts.regular;

 //set the level text
 var info = "Click anywhere to start the next ball";
 var infoSize = game.canvasContext.measureText(info);
 game.canvasContext.fillText(info, center - infoSize.width/2, height + 25);
}

/**
* Draw the start screen
**/
function screenStartGame() {
 var center = game.canvas.width / 2;
 var height = game.canvas.height / 2;

 //set the header text
 var header = "BattlePong!";
 game.canvasContext.fillStyle = game.colors.header;
 game.canvasContext.font = game.fonts.header;
 var headerSize = game.canvasContext.measureText(header);
 game.canvasContext.fillText(header, center - headerSize.width/2, height);

 //set the info text
 var info = "Click anywhere to start playing";
 game.canvasContext.fillStyle = game.colors.text;
 game.canvasContext.font = game.fonts.regular;
 var infoSize = game.canvasContext.measureText(info);
 game.canvasContext.fillText(info, center - infoSize.width/2, height + 25);
}

/**
* Buffer the screen
**/
function buffer() {

 //black out the screen
 drawRectangle(0, 0, game.canvas.width, game.canvas.height, game.colors.background);

 //draw one if the screens if they're active
 if (game.screens.winner) {
 screenWinner();
 return;
 }
 else if (game.screens.continue) {
 screenContinue();
 return;
 }
 else if (game.screens.levelUp) {
 screenLevelUp();
 return;
 }
 else if (game.screens.startGame) {
 screenStartGame();
 return;
 }

 //playing the game
 move();
 drawBoard();
}

Test Your File

Open your html file in a browser. Make sure that your javascript file is located in the same place. Voila! Now you can tweak and refine it to your hearts content.

Advertisements