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:
Ok, download the example files and lets start coding !
Step 1. HTML
As always – very small HTML markup.
index.html
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> |
12 | <h2>HTML5 Game Development - Lesson 6</h2> |
15 | <div class="container"> |
16 | <canvas id="scene" width="800" height="600"></canvas> |
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
003 | var imgBrick, imgSteel, imgWater, imgForest, imgTank; |
010 | function Tank(x, y, w, h, image) { |
020 | context.clearRect(0, 0, canvas.width, canvas.height); |
022 | function drawScene() { |
025 | context.fillStyle = '#111'; |
026 | context.fillRect(0, 0, canvas.width, canvas.height); |
030 | for (var y = 0; y < iYCnt; y++) { |
031 | for (var x = 0; x < iXCnt; x++) { |
032 | switch (aMap[y][x]) { |
036 | context.drawImage(imgBrick, 0, 0, iCellSize, iCellSize, x*iCellSize, y*iCellSize, iCellSize, iCellSize); |
039 | context.drawImage(imgSteel, 0, 0, iCellSize, iCellSize, x*iCellSize, y*iCellSize, iCellSize, iCellSize); |
042 | context.drawImage(imgForest, 0, 0, iCellSize, iCellSize, x*iCellSize, y*iCellSize, iCellSize, iCellSize); |
045 | context.drawImage(imgWater, 0, 0, iCellSize, iCellSize, x*iCellSize, y*iCellSize, iCellSize, iCellSize); |
053 | context.drawImage(oTank.image, oTank.i*oTank.w, 0, oTank.w, oTank.h, oTank.x, oTank.y, oTank.w, oTank.h); |
058 | canvas = document.getElementById('scene'); |
059 | canvas.width = iXCnt * iCellSize; |
060 | canvas.height = iYCnt * iCellSize; |
061 | context = canvas.getContext('2d'); |
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] |
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){ |
104 | switch (event.keyCode) { |
108 | var iCurCelX = (2 * oTank.x) / 48; |
109 | var iCurCelY = (2 * oTank.y) / 48; |
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)) { |
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)) { |
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)) { |
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)) { |
167 | setInterval(drawScene, 40); |
I have added my comments everywhere, hope that all this code is pretty understandable.
Conclusion
Today, we have made quite complete HTML5 game – BattleCity. I will be glad to see your thanks and comments. Good luck!