Writing My First HTML5 Game

1 comment
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();
    });
});

1 comments:

Really good job, it's a lil bit fast but really cool.

We would love to hear from you...

back to top