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
Live Demo Download Script
Edit and play with code ;)
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> <canvas> 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(); }); });
1 comments:
Really good job, it's a lil bit fast but really cool.
We would love to hear from you...