Writing My First HTML5 Game

Writing My First HTML5 Game Recently I started studying about game development in HTML5 using canvas feature of HTML5. HTML5 canvas is really a good place to start game development. I tried writing a simple game called ‘Beerchaser’. This game uses very basic HTML5 canvas objects like arc, rectangle, and radialgradients. Although the game is very simple and primitive, it helped me a lot in learning animations on HTML5 canvas. I have added sound effects to the game to make it little bit fancy. You can play it here.
Live Demo Download Script
Edit and play with code 😉

Courtesy: All sound effects have been taken from www.soundjay.com

The HTML Code

<html>
<head>
<title>Beerchaser HTML5 Game by WebSpeaks.in</title>
<script src="jquery-1.7.1.min.js"></script>
<script src="library.js"></script>
<style>
#main{
width:100%;
font: 14px/100% Arial, Helvetica, sans-serif;
color: #4784EC;
}
#play{
margin:auto;
border:2px groove #ececec;
width:500px;
}
#toolbar{
width:100px;
margin:20px auto;
}
.timer{
width:100px;
margin:20px auto;
font-size:60px;
font-family:Console;
font-weight:bold;
}
.button {
display: inline-block;
outline: none;
cursor: pointer;
text-align: center;
text-decoration: none;
padding: .5em 2em .55em;
text-shadow: 0 1px 1px rgba(0,0,0,.3);
-webkit-border-radius: .5em;
-moz-border-radius: .5em;
border-radius: .5em;
-webkit-box-shadow: 0 1px 2px rgba(0,0,0,.2);
-moz-box-shadow: 0 1px 2px rgba(0,0,0,.2);
box-shadow: 0 1px 2px rgba(0,0,0,.2);
}
.button:hover {
text-decoration: none;
}
.button:active {
position: relative;
top: 1px;
}
.inst{
width:500px;
margin:10px auto;
}
.inst li{
padding-top:10px;
}
</style>
</head>
<body>
<div id="main">
<div id="play">
<canvas id="canvas" width="500" height="500">
<p>This example requires a browser that supports the
<a href="http://www.w3.org/html/wg/html5/">HTML5</a> &lt;canvas&gt; feature.</p>
</canvas>
</div>
<div id="toolbar">
<button id="start" class="button blue">Start</button>
<div class="timer"></div>
</div>
<div class="inst">
<h2>Instructions</h2>
<ul>
<li>Use Left/Right arrow keys or your mouse to move the paddle.</li>
<li>Red balls will empty the beer from your mug. Blue balls will fill beer for you.</li>
</ul>
</div>
</div>
</body>
</html>

The JavaScript Code

//BEGIN LIBRARY CODE
var x = 250;
var y = 0;
var dx = 0;
var dy = 7;
var WIDTH;
var HEIGHT;
var ctx;

var mugCenterX;
var mugCenterY;
var mugLeft = 150;
var mugtop = 200;
var mugWidth = 200;
var mugHeight = 300;
var mugBoundary = 5;
var initBeerHeight = 100;
var currentBeerHeight = initBeerHeight;
var rad = 10;
var intervalId = 0;
var circleType = 'drug';

var paddlex;
var paddley;
var paddleh = 10;
var paddlew = 50;
var rightDown = false;
var leftDown = false;

var canvasMinX;
var canvasMaxX;

var Xhit = false;
var Yhit = false;

var start = new Date().getTime();
var time = 0;
var elapsed = '0.0';
var game_over = false;

var audioType;
var sfx;
var browser;

function init_config() {
if (navigator.userAgent.indexOf('Firefox') !== -1) {
browser = 'firefox';
} else if (navigator.userAgent.indexOf('Chrome') !== -1) {
browser = 'chrome';
} else {
browser = 'other';
}
ctx = document.getElementById("canvas").getContext("2d");
if (!ctx) {
document.writeln('Please use HTML5 enabled browser.');
return false;
}
WIDTH = $("#canvas").width();
HEIGHT = $("#canvas").height();
}
function init() {
init_config();
mugCenterX = parseInt(WIDTH / 2);
mugCenterY = parseInt(HEIGHT / 2);

ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
ctx.shadowBlur = 0;

window.setTimeout(instance, 1000);

var minX = parseInt(mugLeft)+parseInt(mugBoundary)+parseInt(rad);
var maxX = parseInt(mugLeft)+parseInt(mugBoundary) + parseInt(mugWidth-(2*mugBoundary));
x = getRandomInt(minX,maxX);
return intervalId = setInterval(draw, 10);
}

function drawMug() {
ctx.fillStyle = "rgba(232,230,231, 1)";
ctx.fillRect(mugLeft, mugtop, mugWidth, mugHeight);
}

function fillBeer() {
//Color of the beer
if (browser=='firefox') {
var radgrad = ctx.createRadialGradient(mugCenterX,400,100,mugCenterX,200,100);
radgrad.addColorStop(0, 'rgba(233,183,58, 0.9)');
radgrad.addColorStop(0.5, 'rgba(241,180,37,1)');
radgrad.addColorStop(1, 'rgba(233,169,19,1)');
ctx.fillStyle = radgrad;
} else {
ctx.fillStyle = 'rgba(233,169,19,1)';
}
//beer filled in the mug
var bx = parseInt(mugLeft)+parseInt(mugBoundary);
var by = HEIGHT - currentBeerHeight;
var bWidth = mugWidth-(2*mugBoundary);
var bHeight = currentBeerHeight - mugBoundary;
ctx.fillRect(bx, by, bWidth, bHeight);
}

function circle(x,y,r) {
if (circleType=='ice') {
ctx.fillStyle = "blue";
} else {
ctx.fillStyle = "red";
}
ctx.beginPath();
ctx.arc(x, y, r, 0, Math.PI*2, true);
ctx.closePath();
ctx.fill();

}

function rect(x,y,w,h) {
ctx.fillStyle = "green";
ctx.beginPath();
ctx.rect(x,y,w,h);
ctx.closePath();
ctx.fill();
}

function init_paddle() {
paddlex = WIDTH / 2;
paddley = HEIGHT-paddleh-mugHeight;
}

//set rightDown or leftDown if the right or left keys are down
function onKeyDown(evt) {
if (evt.keyCode == 39) rightDown = true;
else if (evt.keyCode == 37) leftDown = true;
}

//and unset them when the right or left key is released
function onKeyUp(evt) {
if (evt.keyCode == 39) rightDown = false;
else if (evt.keyCode == 37) leftDown = false;
}

$(document).keydown(onKeyDown);
$(document).keyup(onKeyUp);

function init_mouse() {
canvasMinX = $("#canvas").offset().left;
canvasMaxX = canvasMinX + WIDTH;
}

function onMouseMove(evt) {
if (evt.pageX > canvasMinX && evt.pageX < canvasMaxX) {
paddlex = evt.pageX - canvasMinX;

//Limit paddle when mouse is moved
var bWidth = mugWidth-(2*mugBoundary);
var maxR = parseInt(mugLeft) + parseInt(bWidth);
if (paddlex > maxR) {
paddlex = maxR;
}
if (paddlex < mugLeft-30) {
paddlex = mugLeft-30;
}
}
}

$(document).mousemove(onMouseMove);

function clear() {
ctx.clearRect(0, 0, WIDTH, HEIGHT);
}

function draw() {
clear();
drawMug();
fillBeer();
circle(x, y, rad);

//move the paddle if left or right is currently pressed
if (rightDown) {
paddlex += 5;
var bWidth = mugWidth-(2*mugBoundary);
var maxR = parseInt(mugLeft) + parseInt(bWidth);
if (paddlex > maxR) {
paddlex = maxR;
}
}
else if (leftDown){
paddlex -= 5;
if (paddlex < mugLeft-30) {
paddlex = mugLeft-30;
}
}
rect(paddlex, paddley, paddlew, paddleh);

//check if paddle hits the circle
var paddleMaxW = parseInt(paddlex) + parseInt(paddlew);
if (x > paddlex && x <= paddleMaxW) {
Xhit = true;
} else {
Xhit = false;
}

var paddleMaxH = parseInt(paddley) + parseInt(paddleh);
if (y >= paddley && y < paddleMaxH) {
Yhit = true;
} else {
Yhit = false;
}

if (Xhit && Yhit) {
playWhip();
dx = -20;
dy = -10;
initCircle();
initDeviations();
}
x += dx;
y += dy;

//The circle is drops on the beer surface
var bHeight = parseInt(HEIGHT - currentBeerHeight - mugBoundary) + parseInt(2*rad);
//If the height of beer is more than the Mug
if (y >= bHeight) {
clearInterval(intervalId);
playDip();

if (circleType == 'ice') {
currentBeerHeight += 10;
} else {
currentBeerHeight -= 20;
}

initCircle();

if (currentBeerHeight<mugHeight) {
intervalId = setInterval(draw, 10);
} else {
youWin();
clearInterval(intervalId);
}
if (currentBeerHeight <= 0) {
gameOver();
}
}

}

function initCircle() {
var rand = getRandomInt(0, 100);
if (rand%5==0) {
circleType = 'ice';
} else {
circleType = 'drug';
}

var minX = parseInt(mugLeft)+parseInt(mugBoundary)+parseInt(rad);
var maxX = parseInt(mugLeft)+parseInt(mugBoundary) + parseInt(mugWidth-(2*mugBoundary));
x = getRandomInt(minX,maxX);
y = 0;
}

function initDeviations() {
dx = 0;
dy = 7;
}

function gameOver() {
playFail();
game_over = true;
clearInterval(intervalId);
clear();

ctx.shadowOffsetX = 2;
ctx.shadowOffsetY = 2;
ctx.shadowBlur = 2;
ctx.shadowColor = "rgba(0, 0, 0, 0.5)";

ctx.font = "48px Lucida Console";
ctx.fillStyle = "Black";
ctx.fillText("Game Over", 120, 150);
}

function youWin() {
playWin();
clearInterval(intervalId);
clear();

ctx.shadowOffsetX = 2;
ctx.shadowOffsetY = 2;
ctx.shadowBlur = 2;
ctx.shadowColor = "rgba(0, 0, 0, 0.5)";

ctx.font = "48px Lucida Console";
ctx.fillStyle = "Black";
ctx.fillText("Cheers!!!", 130, 150);
game_over = true;
}

function startBanner() {
ctx.shadowOffsetX = 2;
ctx.shadowOffsetY = 2;
ctx.shadowBlur = 2;
ctx.shadowColor = "rgba(0, 0, 0, 0.5)";

ctx.font = "48px Lucida Console";
ctx.fillStyle = "Black";
ctx.fillText("Start", 180, 150);

ctx.font = "20px Lucida Console";
ctx.fillStyle = "#4784EC";
ctx.fillText("BeerChaser by Arvind Bhardwaj", 90, 450);
ctx.fillText("www.webspeaks.in", 150, 480);
}

function playDip() {
sfx = new Audio(getFilePath() + 'water-droplet' + audioType);
sfx.play();
}

function playWhip() {
sfx = new Audio(getFilePath() + 'shovel' + audioType);
sfx.play();
}

function playFail() {
sfx = new Audio(getFilePath() + 'laughter' + audioType);
sfx.play();
}

function playWin() {
sfx = new Audio(getFilePath() + 'applause' + audioType);
sfx.play();
}

function getFilePath() {
return 'sounds/';
}

function getAudioType() {
var audio = new Audio();
if( audio.canPlayType("audio/mp3") )
audioType = '.mp3';
else
audioType = '.wav';
}

function getRandomInt (min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}

function instance() {
if (!game_over) {
time += 100;
elapsed = Math.floor(time / 100) / 10;
if(Math.round(elapsed) == elapsed) { elapsed += '.0'; }
$('.timer').text(elapsed);
var diff = (new Date().getTime() - start) - time;
window.setTimeout(instance, (100 - diff));
}
}

$(document).ready(function(){
init_config();
getAudioType();
startBanner();
$('#start').click(function(){
$(this).hide();
$('.inst').hide();
init();
init_paddle();
init_mouse();
});
});

Written by Arvind Bhardwaj

Arvind is a Magento and WordPress expert with more than 6 years of industry wide experience.

Website: http://www.webspeaks.in/

2 thoughts on “Writing My First HTML5 Game

  1. You need targeted traffic to your Writing My First HTML5 Game – WebSpeaks website so why not try some for free? There is a VERY POWERFUL and POPULAR company out there who now lets you try their traffic service for 7 days free of charge. I am so glad they opened their traffic system back up to the public! Sign up before it is too late: http://2u4.us/1qkx

Comments are closed.