HTML5 Zone is brought to you in partnership with:

I was born in 1981 in one little city. Since I was 10y/o I programmed in different languages. My first languages were basic, then C++/MFC, after .Net (C#, VB.Net, J#, ASP.Net), XSL+XML processing). In the last 5 years I worked with web languages (HTML, CSS, PHP, SQL, XML, XSL, JavaScript). After university I worked in several different companies, eventually becoming a blogger. This is my hobby too. Andrey is a DZone MVB and is not an employee of DZone and has posted 106 posts at DZone. You can read more from them at their website. View Full User Profile

HTML5 Game Development – Lesson 4 - Sprites and Sounds

11.28.2011
| 2603 views |
  • submit to reddit
HTML5 Game Development - Lesson 4

Today we continue a series of articles on game development in HTML5 using canvas. Today we going to learn next elements: animation with sprites and basic work with sound. In our demonstration you will see a flying dragon. We will hear the sounds of wings all time (we will loop this sound), and another sound – dragon’s roar (on mouseup event). And finally we will teach our dragon be closer to the mouse cursor (when we hold down the mouse).

Our previous article you can read here: Developing Your First HTML5 Game – Lesson 3. Our new script is new enhanced version of previous one.

Here are our demo and downloadable package:

Live Demodownload in package

Ok, download the example files and lets start coding !


Step 1. HTML


Here are all html of my demo.

index.html
01<!DOCTYPE html>
02<html lang="en" >
03    <head>
04        <meta charset="utf-8" />
05        <title>HTML5 Game Development - Lesson 4 | Script Tutorials</title>
06 
07        <link href="css/main.css" rel="stylesheet" type="text/css" />
08 
09        <!--[if lt IE 9]>
10          <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
11        <![endif]-->
12        <script src="http://code.jquery.com/jquery-latest.min.js"></script>
13        <script type="text/javascript" src="js/script.js"></script>
14    </head>
15    <body>
16        <div class="container">
17            <canvas id="scene" width="1000" height="600"></canvas>
18        </div>
19 
20        <footer>
21            <h2>HTML5 Game Development - Lesson 4</h2>
22            <a href="http://www.script-tutorials.com/html5-game-development-lesson-4/" class="stuts">Back to original tutorial on <span>Script Tutorials</span></a>
23        </footer>
24    </body>
25</html>


Step 2. CSS


Here are used CSS styles.

css/main.css

I will not publish styles today – this is just page layout styles, nothing special. Available in package.


Step 3. JS


js/script.js
001// inner variables
002var canvas, ctx;
003var backgroundImage;
004var iBgShiftX = 100;
005var dragon;
006var dragonW = 75; // dragon width
007var dragonH = 70; // dragon height
008var iSprPos = 0; // initial sprite frame
009var iSprDir = 4; // initial dragon direction
010var dragonSound; // dragon sound
011var wingsSound; // wings sound
012var bMouseDown = false; // mouse down state
013var iLastMouseX = 0;
014var iLastMouseY = 0;
015// -------------------------------------------------------------
016 
017// objects :
018function Dragon(x, y, w, h, image) {
019    this.x = x;
020    this.y = y;
021    this.w = w;
022    this.h = h;
023    this.image = image;
024    this.bDrag = false;
025}
026// -------------------------------------------------------------
027 
028// draw functions :
029function clear() { // clear canvas function
030    ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
031}
032 
033function drawScene() { // main drawScene function
034    clear(); // clear canvas
035 
036    // draw background
037    iBgShiftX -= 4;
038    if (iBgShiftX <= 0) {
039        iBgShiftX = 1045;
040    }
041    ctx.drawImage(backgroundImage, 0 + iBgShiftX, 0, 1000, 940, 0, 0, 1000, 600);
042 
043    // update sprite positions
044    iSprPos++;
045    if (iSprPos >= 9) {
046        iSprPos = 0;
047    }
048 
049    // in case of mouse down - move dragon more close to our mouse
050    if (bMouseDown) {
051        if (iLastMouseX > dragon.x) {
052            dragon.x += 5;
053        }
054        if (iLastMouseY > dragon.y) {
055            dragon.y += 5;
056        }
057        if (iLastMouseX < dragon.x) {
058            dragon.x -= 5;
059        }
060        if (iLastMouseY < dragon.y) {
061            dragon.y -= 5;
062        }
063    }
064 
065    // draw dragon
066    ctx.drawImage(dragon.image, iSprPos*dragon.w, iSprDir*dragon.h, dragon.w, dragon.h, dragon.x - dragon.w/2, dragon.y - dragon.h/2, dragon.w, dragon.h);
067}
068 
069// -------------------------------------------------------------
070 
071// initialization
072$(function(){
073    canvas = document.getElementById('scene');
074    ctx = canvas.getContext('2d');
075 
076    var width = canvas.width;
077    var height = canvas.height;
078 
079    // load background image
080    backgroundImage = new Image();
081    backgroundImage.src="images/hell.jpg";
082    backgroundImage.onload = function() {
083    }
084    backgroundImage.onerror = function() {
085        console.log('Error loading the background image.');
086    }
087 
088    // 'Dragon' music init
089    dragonSound = new Audio('media/dragon.wav');
090    dragonSound.volume = 0.9;
091 
092    // 'Wings' music init
093    wingsSound = new Audio('media/wings.wav');
094    wingsSound.volume = 0.9;
095    wingsSound.addEventListener('ended', function() { // looping wings sound
096        this.currentTime = 0;
097        this.play();
098    }, false);
099    wingsSound.play();
100 
101    // initialization of dragon
102    var oDragonImage = new Image();
103    oDragonImage.src="images/dragon.gif";
104    oDragonImage.onload = function() {
105    }
106    dragon = new Dragon(400, 300, dragonW, dragonH, oDragonImage);
107 
108    $('#scene').mousedown(function(e) { // binding mousedown event (for dragging)
109        var mouseX = e.layerX || 0;
110        var mouseY = e.layerY || 0;
111        if(e.originalEvent.layerX) { // changes for jquery 1.7
112            mouseX = e.originalEvent.layerX;
113            mouseY = e.originalEvent.layerY;
114        }
115 
116        bMouseDown = true;
117 
118        if (mouseX > dragon.x- dragon.w/2 && mouseX < dragon.x- dragon.w/2 +dragon.w &&
119            mouseY > dragon.y- dragon.h/2 && mouseY < dragon.y-dragon.h/2 +dragon.h) {
120 
121            dragon.bDrag = true;
122            dragon.x = mouseX;
123            dragon.y = mouseY;
124        }
125    });
126 
127    $('#scene').mousemove(function(e) { // binding mousemove event
128        var mouseX = e.layerX || 0;
129        var mouseY = e.layerY || 0;
130        if(e.originalEvent.layerX) { // changes for jquery 1.7
131            mouseX = e.originalEvent.layerX;
132            mouseY = e.originalEvent.layerY;
133        }
134 
135        // saving last coordinates
136        iLastMouseX = mouseX;
137        iLastMouseY = mouseY;
138 
139        // perform dragon dragging
140        if (dragon.bDrag) {
141            dragon.x = mouseX;
142            dragon.y = mouseY;
143        }
144 
145        // change direction of dragon (depends on mouse position)
146        if (mouseX > dragon.x && Math.abs(mouseY-dragon.y) < dragon.w/2) {
147            iSprDir = 0;
148        } else if (mouseX < dragon.x && Math.abs(mouseY-dragon.y) < dragon.w/2) {
149            iSprDir = 4;
150        } else if (mouseY > dragon.y && Math.abs(mouseX-dragon.x) < dragon.h/2) {
151            iSprDir = 2;
152        } else if (mouseY < dragon.y && Math.abs(mouseX-dragon.x) < dragon.h/2) {
153            iSprDir = 6;
154        } else if (mouseY < dragon.y && mouseX < dragon.x) {
155            iSprDir = 5;
156        } else if (mouseY < dragon.y && mouseX > dragon.x) {
157            iSprDir = 7;
158        } else if (mouseY > dragon.y && mouseX < dragon.x) {
159            iSprDir = 3;
160        } else if (mouseY > dragon.y && mouseX > dragon.x) {
161            iSprDir = 1;
162        }
163    });
164 
165    $('#scene').mouseup(function(e) { // binding mouseup event
166        dragon.bDrag = false;
167        bMouseDown = false;
168 
169        // play dragon sound
170        dragonSound.currentTime = 0;
171        dragonSound.play();
172    });
173 
174    setInterval(drawScene, 30); // loop drawScene
175});

How it work (shortly): Firstly we define canvas, context, then we load background image, two sounds, then we initialize our dragon and binding different mouse events. In our main loop draw function I am shifting background image (loop), then update sprite positions, and finally – draw our dragon. In our code you can find several new interesting methods:

1. Loop background sound

1// 'Wings' music init
2wingsSound = new Audio('media/wings.wav');
3wingsSound.volume = 0.9;
4wingsSound.addEventListener('ended', function() { // looping wings sound
5    this.currentTime = 0;
6    this.play();
7}, false);
8wingsSound.play();

2. Draw sprites

01    var oDragonImage = new Image();
02    oDragonImage.src="images/dragon.gif";
03    oDragonImage.onload = function() {
04    }
05....
06    // update sprite positions
07    iSprPos++;
08    if (iSprPos >= 9) {
09        iSprPos = 0;
10    }
11 
12    // draw dragon
13    ctx.drawImage(dragon.image, iSprPos*dragon.w, iSprDir*dragon.h, dragon.w, dragon.h, dragon.x - dragon.w/2, dragon.y - dragon.h/2, dragon.w, dragon.h);

So, we loading initial image (with set of all sub-images), then – draw part of that image, then shifting its positions, and draw again (loop).


Step 4. Custom files


images/dragon.gif, images/hell.jpg, media/dragon.wav and media/wings.wav

All these files available in our package

Live Demodownload in package


Conclusion

Are you like our new handy dragon? :-) I will be glad to see your thanks and comments. Good luck!

 

source: http://www.script-tutorials.com/html5-game-development-lesson-4/

Published at DZone with permission of Andrey Prikaznov, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)