HTML5游戏开发系列教程6(译)

原文地址:http://www.script-tutorials.com/html5-game-development-lesson-6/

这是我们最新一篇HTML5游戏开发系列文章。我们将继续使用canvas来进行HTML5游戏开发系列的文章。这次是个完整的游戏例子,再现一款经典的电脑游戏--坦克大战。我将教你们使用交替的数组地图(alternative array-maps),同时将说明如何检测活动对象(坦克)和周围环境之间的碰撞。

前一篇的的介绍在HTML5游戏开发系列教程5(译)。

第一步:HTML

index.html

 1 <!DOCTYPE html>
 2 <html lang="en">
 3     <head>
 4         <meta charset="utf-8" />
 5         <title>HTML5 Game Development - Lesson 6 | Script Tutorials</title>
 6         <link href="css/main.css" rel="stylesheet" type="text/css" />
 7         <script src="js/jquery-2.0.0.min.js"></script>
 8         <script src="js/script.js"></script>
 9     </head>
10     <body>
11         <header>
12             <h2>HTML5 Game Development - Lesson 6</h2>
13             <a href="http://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>

第二步:CSS

css/main.css

我将不会把css文件内容发布出来,css文件里面仅仅是一些页面的层叠样式,你可以在源代码包中找到该文件。

第三步:JS

js/jquery-2.0.0.min.js(原文是1.5.2版本)

我们的代码使用了JQuery。JQuery文件在源代码包中。下面的js文件是最重要的对于我们的游戏,因为它实现了我们游戏所有的逻辑。

js/script.js

  1 //内部变量
  2 var canvas, context;   //画布和其上下文对象
  3 var imgBrick, imgSteel, imgWater, imgForest, imgTank;  //各种实体的图片
  4 var aMap;  //地图数组
  5 var oTank;  //坦克对象
  6 
  7 var iCellSize = 24;  //地图单元格的大小
  8 var iXCnt = 26;
  9 var iYCnt = 26;
 10 
 11 /**
 12 * x: 坦克左上角x轴坐标
 13 * y: 坦克左上角y轴坐标
 14 * w: 坦克宽度
 15 * h: 坦克高度
 16 * image: 坦克图片
 17 */
 18 function Tank(x, y, w, h, image) {
 19     this.x = x;
 20     this.y = y;
 21     this.w = w;
 22     this.h = h;
 23     this.i = 0;
 24     this.image = image;
 25 }
 26 
 27 // 清除画布
 28 function clear() {
 29     context.clearRect(0, 0, canvas.width, canvas.height)
 30 }
 31 
 32 //重绘画布
 33 function drawScene() {
 34     clear();
 35     
 36     //填充背景
 37     context.fillStyle = '#111';
 38     context.fillRect(0, 0, canvas.width, canvas.height);
 39 
 40     context.save();
 41 
 42     //画障碍物
 43     for (var y = 0; y < iYCnt; y++) {
 44         for (var x = 0; x < iXCnt; x++) {
 45             switch (aMap[y][x]) {
 46                 case 0:
 47                     break;
 48                 case 1:
 49                     context.drawImage(imgBrick, 0, 0, iCellSize, iCellSize, x * iCellSize, y * iCellSize, iCellSize, iCellSize);
 50                     break;
 51                 case 2:
 52                     context.drawImage(imgSteel, 0, 0, iCellSize, iCellSize, x * iCellSize, y * iCellSize, iCellSize, iCellSize);
 53                     break;
 54                 case 3:
 55                     context.drawImage(imgForest, 0, 0, iCellSize, iCellSize, x * iCellSize, y * iCellSize, iCellSize, iCellSize);
 56                     break;
 57                 case 4:
 58                     context.drawImage(imgWater, 0, 0, iCellSize, iCellSize, x * iCellSize, y * iCellSize, iCellSize, iCellSize);
 59                     break;
 60             }
 61         }
 62     }
 63 
 64     context.restore();
 65 
 66     //画坦克 这里可以看出坦克占4个单元格
 67     context.drawImage(oTank.image, oTank.i * oTank.w, 0, oTank.w, oTank.h, oTank.x, oTank.y, oTank.w, oTank.h);
 68 }
 69 
 70 $(function() {
 71     canvas = document.getElementById('scene');
 72     canvas.width = iXCnt * iCellSize;
 73     canvas.height = iYCnt * iCellSize;
 74     context = canvas.getContext('2d');
 75 
 76     aMap = ([
 77           [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],
 78           [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],
 79           [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],
 80           [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],
 81           [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],
 82           [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],
 83           [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],
 84           [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],
 85           [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],
 86           [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],
 87           [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],
 88           [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],
 89           [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],
 90           [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],
 91           [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],
 92           [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],
 93           [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],
 94           [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],
 95           [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],
 96           [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],
 97           [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],
 98           [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],
 99           [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],
100           [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],
101           [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],
102           [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]
103     ]);
104 
105     //加载各个障碍物图片
106     imgBrick = new Image();
107     imgBrick.src = 'images/brick.png';
108     imgSteel = new Image();
109     imgSteel.src = 'images/steel.png';
110     imgWater = new Image();
111     imgWater.src = 'images/water.png';
112     imgForest = new Image();
113     imgForest.src = 'images/forest.png';
114 
115     //初始化坦克
116     imgTank = new Image();
117     imgTank.src = 'images/tank.png';
118     oTank = new Tank(iCellSize * 9, iCellSize * 24, 48, 48, imgTank);
119 
120     $(window).keydown(function(event) {
121         switch (event.keyCode) {
122             case 38:  // up key
123                 oTank.i = 2;
124 
125                 //碰撞检测
126                 var iCurCelX = (2 * oTank.x) / 48;  //得出目前坦克左上角所在的单元格
127                 var iCurCelY = (2 * oTank.y) / 48;
128                 if (iCurCelY) {
129                     var iTest1 = aMap[iCurCelY - 1][iCurCelX];
130                     var iTest2 = aMap[iCurCelY - 1][iCurCelX + 1];
131 
132                     if ((iTest1 == 0 || iTest1 == 3) && (iTest2 == 0 || iTest2 == 3)) {
133                         oTank.y -= 24;
134                         if (oTank.y < 0) {
135                             oTank.y = 0;
136                         }
137                     }
138                 }
139                 break;
140             case 40:  //Down key
141                 oTank.i = 3;
142                 
143                 var iCurCelX = (2 * oTank.x) / 48;
144                 var iCurCelY = (2 * oTank.y) / 48;
145                 if (iCurCelY + 2 < iYCnt) {
146                     var iTest1 = aMap[iCurCelY + 2][iCurCelX];
147                     var iTest2 = aMap[iCurCelY + 2][iCurCelX + 1];
148 
149                     if ((iTest1 == 0 || iTest1 == 3) && (iTest2 == 0 || iTest2 == 3)) {
150                         oTank.y += 24;
151                         if (oTank.y > 576) {  //576 = iCellSize * (iYCnt - 2)
152                             oTank.y = 576;
153                         }
154                     }
155                 }
156                 break;
157             case 37:   // Left key
158                 oTank.i = 1;
159 
160                 var iCurCelX = (2 * oTank.x) / 48;
161                 var iCurCelY = (2 * oTank.y) / 48;
162                 var iTest1 = aMap[iCurCelY][iCurCelX - 1];
163                 var iTest2 = aMap[iCurCelY + 1][iCurCelX - 1];
164 
165                 if ((iTest1 == 0 || iTest1 == 3) && (iTest2 == 0 || iTest2 == 3)) {
166                     oTank.x -= 24;
167                     if (oTank.x < 0) {
168                         oTank.x = 0;
169                     }
170                 }
171                 break;
172             case 39:  //Right key
173                 oTank.i = 0;
174                 
175                 var iCurCelX = (2 * oTank.x) / 48;
176                 var iCurCelY = (2 * oTank.y) / 48;
177                 var iTest1 = aMap[iCurCelY][iCurCelX + 2];
178                 var iTest2 = aMap[iCurCelY + 1][iCurCelX + 2];
179 
180                 if ((iTest1 == 0 || iTest1 == 3) && (iTest2 == 0 || iTest2 == 3)) {
181                     oTank.x += 24;
182                     if (oTank.x > 576) {
183                         oTank.x = 576;
184                     }
185                 }
186                 break;
187         }
188     });
189     setInterval(drawScene, 40);
190 });

我在很多地方加上了注释,依此希望这代码是容易理解的。

结论:

这次我们开发了一个完整的HTML5的游戏--坦克大战。我非常乐意看见你的谢意和评论。好运!

原文地址:https://www.cnblogs.com/pigzhu/p/3195998.html