HTML5 Game Development – Lesson 6

Image Tutorials

This is our next game development article. We continue a series of articles on game development in HTML5 using canvas. Today this is quite complete game example – it will reincarnation of old computer game – Battle City. I will teach you to use alternative array-maps plus I will show – how to detect collision of active object (Tank) with environment (array based map).

Here you can read our previous lesson: Developing Your First HTML5 Game – Lesson 5.

Here are our demo and downloadable package:

Live Demo
download in package

Ok, download the example files and lets start coding !


Step 1. HTML

As always – very small HTML markup.

index.html

01 <!DOCTYPE html>
02 <html lang="en" >
03     <head>
04         <meta charset="utf-8" />
05         <title>HTML5 Game Development - Lesson 6 | Script Tutorials</title>
06         <link href="css/main.css" rel="stylesheet" type="text/css" />
07         <script src="js/jquery-1.5.2.min.js"></script>
08         <script src="js/script.js"></script>
09     </head>
10     <body>
11         <header>
12             <h2>HTML5 Game Development - Lesson 6</h2>
13             <a href="https://www.script-tutorials.com/html5-game-development-lesson-6/" class="stuts">Back to original tutorial on <span>Script Tutorials</span></a>
14         </header>
15         <div class="container">
16             <canvas id="scene" width="800" height="600"></canvas>
17         </div>
18     </body>
19 </html>

Step 2. CSS

css/main.css

I won’t publish CSS styles today, there are only a few page layout styles. You can find this file in our package.

Step 3. JS

js/jquery-1.5.2.min.js

We use jQuery for our lesson. Available in package. Next file most important (here are all our html5 functional):

js/script.js

001 // inner variables
002 var canvas, context; // canvas and context objects
003 var imgBrick, imgSteel, imgWater, imgForest, imgTank; // images
004 var aMap; // map array
005 var oTank; // tank object
006 var iCellSize = 24; // cell wide
007 var iXCnt = 26; // amount of X cells
008 var iYCnt = 26; // amount of Y cells
009 // objects :
010 function Tank(x, y, w, h, image) {
011     this.x = x;
012     this.y = y;
013     this.w = w;
014     this.h = h;
015     this.i = 0;
016     this.image = image;
017 }
018 // functions
019 function clear() { // clear canvas function
020     context.clearRect(0, 0, canvas.width, canvas.height);
021 }
022 function drawScene() { // main drawScene function
023     clear(); // clear canvas
024     // fill background
025     context.fillStyle = '#111';
026     context.fillRect(0, 0, canvas.width, canvas.height);
027     // save current context
028     context.save();
029     // walk through our array
030     for (var y = 0; y < iYCnt; y++) {
031         for (var x = 0; x < iXCnt; x++) {
032             switch (aMap[y][x]) {
033                 case 0: // skip
034                     break;
035                 case 1: // draw brick block
036                     context.drawImage(imgBrick, 0, 0, iCellSize, iCellSize, x*iCellSize, y*iCellSize, iCellSize, iCellSize);
037                     break;
038                 case 2: // draw steel block
039                     context.drawImage(imgSteel, 0, 0, iCellSize, iCellSize, x*iCellSize, y*iCellSize, iCellSize, iCellSize);
040                     break;
041                 case 3: // draw forest block
042                     context.drawImage(imgForest, 0, 0, iCellSize, iCellSize, x*iCellSize, y*iCellSize, iCellSize, iCellSize);
043                     break;
044                 case 4: // draw water block
045                     context.drawImage(imgWater, 0, 0, iCellSize, iCellSize, x*iCellSize, y*iCellSize, iCellSize, iCellSize);
046                     break;
047             }
048         }
049     }
050     // restore current context
051     context.restore();
052     // draw tank
053     context.drawImage(oTank.image, oTank.i*oTank.w, 0, oTank.w, oTank.h, oTank.x, oTank.y, oTank.w, oTank.h);
054 }
055 // -------------------------------------------------------------
056 // initialization
057 $(function(){
058     canvas = document.getElementById('scene');
059     canvas.width  = iXCnt * iCellSize;
060     canvas.height = iYCnt * iCellSize;
061     context = canvas.getContext('2d');
062     // main scene Map array
063     aMap = ([
064       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0],
065       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0],
066       [0, 0, 1, 1, 4, 4, 4, 4, 0, 0, 2, 2, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
067       [0, 0, 1, 1, 4, 4, 4, 4, 0, 0, 2, 2, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
068       [0, 0, 0, 0, 4, 4, 4, 4, 1, 1, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 0, 0, 2, 2, 0, 0],
069       [0, 0, 0, 0, 4, 4, 4, 4, 1, 1, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 0, 0, 2, 2, 0, 0],
070       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 1, 1, 0, 0, 0, 0],
071       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 1, 1, 0, 0, 0, 0],
072       [0, 0, 2, 2, 0, 0, 0, 0, 4, 4, 4, 4, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
073       [0, 0, 2, 2, 0, 0, 0, 0, 4, 4, 4, 4, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
074       [3, 3, 3, 3, 1, 1, 0, 0, 4, 4, 4, 4, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0],
075       [3, 3, 3, 3, 1, 1, 0, 0, 4, 4, 4, 4, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0],
076       [3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 2, 2],
077       [3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 2, 2],
078       [0, 0, 1, 1, 4, 4, 4, 4, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
079       [0, 0, 1, 1, 4, 4, 4, 4, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
080       [2, 2, 0, 0, 4, 4, 4, 4, 3, 3, 3, 3, 4, 4, 4, 4, 3, 3, 3, 3, 0, 0, 1, 1, 0, 0],
081       [2, 2, 0, 0, 4, 4, 4, 4, 3, 3, 3, 3, 4, 4, 4, 4, 3, 3, 3, 3, 0, 0, 1, 1, 0, 0],
082       [0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 4, 4, 4, 4, 3, 3, 3, 3, 4, 4, 4, 4, 0, 0],
083       [0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 4, 4, 4, 4, 3, 3, 3, 3, 4, 4, 4, 4, 0, 0],
084       [0, 0, 0, 0, 0, 0, 2, 2, 3, 3, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 4, 4, 4, 4, 0, 0],
085       [0, 0, 0, 0, 0, 0, 2, 2, 3, 3, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 4, 4, 4, 4, 0, 0],
086       [0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
087       [0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
088       [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 2, 2, 0, 0, 0, 0],
089       [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 2, 2, 0, 0, 0, 0]
090     ]);
091     // load images
092     imgBrick = new Image();
093     imgBrick.src = 'images/brick.png';
094     imgSteel = new Image();
095     imgSteel.src = 'images/steel.png';
096     imgWater = new Image();
097     imgWater.src = 'images/water.png';
098     imgForest = new Image();
099     imgForest.src = 'images/forest.png';
100     imgTank = new Image();
101     imgTank.src = 'images/tank.png';
102     oTank = new Tank(iCellSize*9, iCellSize*24, 48, 48, imgTank);
103     $(window).keydown(function(event){ // keyboard alerts
104         switch (event.keyCode) {
105             case 38: // Up key
106                 oTank.i = 2;
107                 // checking collisions
108                 var iCurCelX = (2 * oTank.x) / 48;
109                 var iCurCelY = (2 * oTank.y) / 48;
110                 if (iCurCelY) {
111                     var iTest1 = aMap[iCurCelY-1][iCurCelX];
112                     var iTest2 = aMap[iCurCelY-1][iCurCelX+1];
113                     if ((iTest1 == 0 || iTest1 == 3) && (iTest2 == 0 || iTest2 == 3)) {
114                         oTank.y-=24;
115                         if (oTank.y < 0) {
116                             oTank.y = 0;
117                         }
118                     }
119                 }
120                 break;
121             case 40: // Down key
122                 oTank.i = 3;
123                 // checking collisions
124                 var iCurCelX = (2 * oTank.x) / 48;
125                 var iCurCelY = (2 * oTank.y) / 48;
126                 if (iCurCelY+2 < iYCnt) {
127                     var iTest1 = aMap[iCurCelY+2][iCurCelX];
128                     var iTest2 = aMap[iCurCelY+2][iCurCelX+1];
129                     if ((iTest1 == 0 || iTest1 == 3) && (iTest2 == 0 || iTest2 == 3)) {
130                         oTank.y+=24;
131                         if (oTank.y > 576) { //iCellSize * (iYCnt-2)
132                             oTank.y = 576;
133                         }
134                     }
135                 }
136                 break;
137             case 37: // Left key
138                 oTank.i = 1;
139                 // checking collisions
140                 var iCurCelX = (2 * oTank.x) / 48;
141                 var iCurCelY = (2 * oTank.y) / 48;
142                 var iTest1 = aMap[iCurCelY][iCurCelX-1];
143                 var iTest2 = aMap[iCurCelY+1][iCurCelX-1];
144                 if ((iTest1 == 0 || iTest1 == 3) && (iTest2 == 0 || iTest2 == 3)) {
145                     oTank.x-=24;
146                     if (oTank.x < 0) {
147                         oTank.x = 0;
148                     }
149                 }
150                 break;
151             case 39: // Right key
152                 oTank.i = 0;
153                 // checking collisions
154                 var iCurCelX = (2 * oTank.x) / 48;
155                 var iCurCelY = (2 * oTank.y) / 48;
156                 var iTest1 = aMap[iCurCelY][iCurCelX+2];
157                 var iTest2 = aMap[iCurCelY+1][iCurCelX+2];
158                 if ((iTest1 == 0 || iTest1 == 3) && (iTest2 == 0 || iTest2 == 3)) {
159                     oTank.x+=24;
160                     if (oTank.x > 576) { //iCellSize * (iXCnt-2)
161                         oTank.x = 576;
162                     }
163                 }
164                 break;
165         }
166     });
167     setInterval(drawScene, 40); // loop drawScene
168 });

I have added my comments everywhere, hope that all this code is pretty understandable.


Live Demo
download in package

Conclusion

Today, we have made quite complete HTML5 game – BattleCity. I will be glad to see your thanks and comments. Good luck!

Rate article