zoukankan      html  css  js  c++  java
  • 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的游戏--坦克大战。我非常乐意看见你的谢意和评论。好运!

  • 相关阅读:
    Shooting Algorithm
    Subgradient Algorithm
    Factorization Machine
    支持向量机
    Hashing Trick
    Science上发表的超赞聚类算法
    Contractive Auto-Encoder
    Shell之数学计算
    牛顿方法(Newton-Raphson Method)
    泊松回归(Poisson Regression)
  • 原文地址:https://www.cnblogs.com/pigzhu/p/3195998.html
Copyright © 2011-2022 走看看