zoukankan      html  css  js  c++  java
  • 【javascript面向对象之路】让我们一起来坦克大战吧01

    提问

    不知道大家发现没有,运行时候浏览器或者电脑会变得很卡哦。根据我们之前的学习,你知道是什么原因导致的吗?

    若是各位有兴趣,请你回答卡的原因,并提出优化方案。 

    前言

    PS 各位要看效果还是使用ff或者google吧,ie7以下好像有问题。

    最近大家都在坦克大战,我突然想了下我是不是也应该坦克大战一番呢?于是,我们就有了今天的东西。

    其实做坦克大战并不是为了坦克大战,而是为了javascript面向对象!所以我这里并不会完成这个游戏,做到哪步是哪步吧。

    怎么说呢?javascript面向对象大家都听得很多了,但能真正理解的人并不多,我事实上也是水的,知道一点皮毛是没用的,所以想以此提升面向对象的思想。

    PS:最近其实事情挺多的,HTML5+CSS3、CSS、javascript、bootstrap、响应式布局......我现在是想到哪打哪啊!

    算了,扯远了,我们开始今天的学习吧。

    PS:运行的时候请使用高版本浏览器,这里暂时没有做浏览器兼容

    工欲善其事必先利其器

    刚开始干我就在想,我是不是该写个类库神马的,于是在这里磨磨蹭蹭的搞了一个多小时,硬是挤出了以下代码:

     1 function getById(id) {
     2     return !id ? null : document.getElementById(id);
     3 }
     4 
     5 function getAttr(el, k) {
     6     if (el) {
     7         var v = el.getAttribute[k] ? el.getAttribute[k] : null;
     8         return v;
     9     }
    10 }
    11 
    12 function setAttr(el, k, v) {
    13     if (el) {
    14        el.setAttribute(k, v);
    15     }
    16 }
    17 
    18 function getCss(el, k) {
    19     if (el) {
    20        
    21         if (el.style[k]) {
    22             return el.style[k];
    23         }  
    24         return null;
    25     }
    26 }
    27 
    28 function setCss(el, k, v) {
    29     if (el) {
    30         if (!el.style || el.style.length == 0) {
    31             el.style = {};
    32         }
    33         el.style[k] = v;
    34     }
    35 }

    不用看,也不用说,光是想求得元素的样式这块我就知道有问题,但是我们不能舍本逐末,这里暂时不管他(因为我搞了个把小时了),我们还是按着逻辑往下走吧。

    资料准备

    我们这里需要一点点坦克的图片,于是打开我们的PS,PS之:

    这个坦克的资源,我不知道原来从哪里来的,这里先私自用了,原作者若是觉得有问题请留言。

    PS:我们这里先不考虑小图标的问题,一点点来吧

    首先是我们的子弹爆炸要用到的图片:

    看到这个图片各位就应该要想到炮弹爆炸式怎么实现的了哦!

    然后我们的主角,坦克的图片:

    下面是我们的子弹:

    于是我们几个坦克也有了,子弹也有了,好了我们先不关注其它,看看我们能不能把坦克给搞出来(话说我PS不是太好,这个也必须纳入必学范围)。

    移动的坦克

    我们搞移动的坦克之前,在页面上先弄一张地图,作为坦克使用:

     1 <html xmlns="http://www.w3.org/1999/xhtml">
     2 <head>
     3     <title></title>
     4     <style type="text/css">
     5         .map { background: gray; border: 1px solid black; position: relative; margin: 50px auto; width: 416px; height: 416px; }
     6     </style>
     7 </head>
     8 <body>
     9     <div class="map" id="map">
    10         <div id="me" class="tank">
    11         </div>
    12     </div>
    13 </body>
    14 </html>

    好了,让我们主角坦克登场吧,注意其中的me:

     1 <html xmlns="http://www.w3.org/1999/xhtml">
     2 <head>
     3     <title></title>
     4     <style type="text/css">
     5         .map { background: gray; border: 1px solid black; position: relative; margin: 50px auto; width: 416px; height: 416px; }
     6          .tank { background-image: url("images/tank.gif"); overflow: hidden; position: absolute; width: 32px; height: 32px; z-index: 3; }
     7          
     8     </style>
     9 </head>
    10 <body>
    11     <div class="map" id="map">
    12         <div id="me" class="tank">
    13         </div>
    14     </div>
    15 </body>
    16 </html>

    我们可爱的坦克,还是2二级的坦克出现啦,现在我们为他加上移动效果,这里就要开始写代码啦,首先我们定义一个坦克类:

     1 var Tank = function (id, dir, x, y) {
     2     this.el = getById(id);
     3     this.direction = dir ? dir : 'up';
     4     this.tid = null;
     5     this.speed = 10;
     6     //坦克活动状态 0 未活动 1 正在活动
     7     this.activeState = 0;
     8     this.x = x ? x : 100;
     9     this.y = y ? y : 200;
    10     this.dirState = {
    11         up: 1,
    12         right: 1,
    13         down: 1,
    14         left: 1
    15     };
    16 }

    我现在能想到坦克具有的属性便是:

    1 坦克对应的html标签

    2 坦克的初始化方向

    3 坦克的初始化位置

    在修改一点点,我们就能控制坦克转向了:

      1 <html xmlns="http://www.w3.org/1999/xhtml">
      2 <head>
      3     <title></title>
      4     <style type="text/css">
      5         .map { background: gray; border: 1px solid black; position: relative; margin: 50px auto;  416px; height: 416px; }
      6          .tank { background-image: url("images/tank.gif"); background-repeat: no-repeat; overflow: hidden; position: absolute;  32px; height: 32px; z-index: 3; }
      7     </style>
      8 </head>
      9 <body>
     10     <div class="map" id="map">
     11         <div id="me" class="tank">
     12         </div>
     13     </div>
     14 
     15     <script src="../06tank/js/core.js" type="text/javascript"></script>
     16     <script type="text/javascript">
     17         var Tank = function (id, dir, x, y) {
     18             this.el = getById(id);
     19             this.direction = dir ? dir : 'up';
     20             this.tid = null;
     21             this.speed = 10;
     22             //坦克活动状态 0 未活动 1 正在活动
     23             this.activeState = 0;
     24             this.x = x ? x : 100;
     25             this.y = y ? y : 200;
     26             this.dirState = {
     27                 up: 1,
     28                 right: 1,
     29                 down: 1,
     30                 left: 1
     31             };
     32         };
     33         Tank.prototype.init = function () {
     34             var dir = this.direction;
     35             var tank = this.el;
     36             setCss(tank, 'left', this.x + 'px');
     37             setCss(tank, 'top', this.y + 'px');
     38             this.setDirection(dir);
     39         };
     40         Tank.prototype.setDirection = function (dir) {
     41             var tank = this.el;
     42             if (dir == 'up') {
     43                 setCss(tank, 'backgroundPosition', '0 0');
     44             }
     45             if (dir == 'right') {
     46                 setCss(tank, 'backgroundPosition', '-5px -36px');
     47             }
     48             if (dir == 'down') {
     49                 setCss(tank, 'backgroundPosition', '0 -73px');
     50             }
     51             if (dir == 'left') {
     52                 setCss(tank, 'backgroundPosition', '0 -105px');
     53             }
     54             this.dirState[dir] = 1;
     55         };
     56 
     57         var tank = new Tank('me', 'right', 100, 100);
     58         tank.init();
     59 
     60         function getDir(code) {
     61             if (code == '87' || code == '119') {
     62                 return 'up';
     63             }
     64             if (code == '100' || code == '68') {
     65                 return 'right';
     66             }
     67             if (code == '115' || code == '83') {
     68                 return 'down';
     69             }
     70             if (code == '97' || code == '65') {
     71                 return 'left';
     72             }
     73             return null;
     74         }
     75 
     76         document.onkeydown = function (evt) {
     77             evt = (evt) ? evt : window.event;
     78             var keyCode = evt.keyCode;
     79             var charCode = evt.charCode;
     80             var dir = getDir();
     81             if (keyCode) {
     82                 dir = getDir(keyCode.toString());
     83             }
     84             if (charCode) {
     85                 dir = getDir(charCode.toString());
     86             }
     87             tank.setDirection(dir);
     88 
     89             evt.preventDefault();
     90             return false;
     91         };
     92         document.onkeyup = function (evt) {
     93         };
     94         document.onkeypress = function (evt) {
     95             evt = (evt) ? evt : window.event;
     96             var keyCode = evt.keyCode;
     97             var charCode = evt.charCode;
     98             var dir = getDir();
     99             if (keyCode) {
    100                 dir = getDir(keyCode.toString());
    101             }
    102             if (charCode) {
    103                 dir = getDir(charCode.toString());
    104             }
    105             evt.preventDefault();
    106             return false;
    107         };
    108     </script>
    109 </body>
    110 </html>
    View Code

    运行效果(此处可运行):

    然后我们来加上移动的动画,各位注意啦,我们这里要使用js实现动画啦!我们来看看这段代码:

      1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      2 <html xmlns="http://www.w3.org/1999/xhtml">
      3 <head>
      4     <title></title>
      5     <style type="text/css">
      6         .map { background: gray; border: 1px solid black; position: relative; margin: 50px auto; width: 416px; height: 416px; }
      7         .tank { background-image: url("//images0.cnblogs.com/blog/294743/201306/12123133-eaa9ada8690e4216a2bee3e56442e032.gif"); background-repeat: no-repeat; overflow: hidden; position: absolute; width: 32px; height: 32px; z-index: 3; }
      8     </style>
      9 </head>
     10 <body>
     11     <div class="map" id="map">
     12         <div id="me" class="tank">
     13         </div>
     14     </div>
     15     <script type="text/javascript">
     16         function getById(id) {
     17             return !id ? null : document.getElementById(id);
     18         }
     19 
     20         function getAttr(el, k) {
     21             if (el) {
     22                 var v = el.getAttribute[k] ? el.getAttribute[k] : null;
     23                 return v;
     24             }
     25         }
     26 
     27         function setAttr(el, k, v) {
     28             if (el) {
     29                 el.setAttribute(k, v);
     30             }
     31         }
     32 
     33         function getCss(el, k) {
     34             if (el) {
     35 
     36                 if (el.style[k]) {
     37                     return el.style[k];
     38                 }
     39                 return null;
     40             }
     41         }
     42 
     43         function setCss(el, k, v) {
     44             if (el) {
     45                 if (!el.style || el.style.length == 0) {
     46                     el.style = {};
     47                 }
     48                 el.style[k] = v;
     49             }
     50         }
     51 
     52         var MyGlobal = {
     53             mapWidth: 416,
     54             mapHeight: 416,
     55              448,
     56             height: 512
     57         };
     58 
     59         var Tank = function (id, dir, x, y) {
     60             this.el = getById(id);
     61             this.direction = dir ? dir : 'up';
     62             this.tid = null;
     63             this.speed = 10;
     64             //坦克活动状态 0 未活动 1 正在活动
     65             this.activeState = 0;
     66             this.x = x ? x : 100;
     67             this.y = y ? y : 200;
     68             this.dirState = {
     69                 up: 1,
     70                 right: 1,
     71                 down: 1,
     72                 left: 1
     73             };
     74         };
     75         Tank.prototype.init = function () {
     76             var dir = this.direction;
     77             var tank = this.el;
     78             setCss(tank, 'left', this.x + 'px');
     79             setCss(tank, 'top', this.y + 'px');
     80             this.setDirection(dir);
     81         };
     82         Tank.prototype.setDirection = function (dir) {
     83             var tank = this.el;
     84             if (dir == 'up') {
     85                 setCss(tank, 'backgroundPosition', '0 0');
     86             }
     87             if (dir == 'right') {
     88                 setCss(tank, 'backgroundPosition', '-5px -36px');
     89             }
     90             if (dir == 'down') {
     91                 setCss(tank, 'backgroundPosition', '0 -73px');
     92             }
     93             if (dir == 'left') {
     94                 setCss(tank, 'backgroundPosition', '0 -105px');
     95             }
     96             this.dirState[dir] = 1;
     97         };
     98 
     99         Tank.prototype.move = function (dir) {
    100             if (this.activeState != 0) return false; //正在运动我们便不管他
    101             this.activeState = 1; //将当前状态设置为正在运动
    102             if (this.direction != dir) {
    103                 this.direction = dir;
    104                 this.setDirection(dir);
    105             }
    106             //处理运动中的定时器
    107             if (this.tid) {
    108                 clearTimeout(this.tid);
    109                 this.tid = null;
    110             }
    111             var state = this.dirState[dir];
    112             var tank = this.el;
    113             if (state == 1 || state == -1) {
    114                 var strPos = getCss(tank, 'backgroundPosition');
    115                 var arrPos = strPos.split(' ');
    116                 var l = arrPos ? arrPos[0] : 0;
    117                 var t = arrPos ? arrPos[1] : 0;
    118                 var curPos = parseInt(l);
    119                 var top = parseInt(t);
    120                 var po = curPos - (43) * (state);
    121                 var curPos = po + 'px ' + t + 'px';
    122                 setCss(tank, 'backgroundPosition', curPos);
    123             }
    124             var xpos = getCss(tank, 'left') ? getCss(tank, 'left') : 0;
    125             var ypos = getCss(tank, 'top') ? getCss(tank, 'top') : 0;
    126             xpos = parseInt(xpos);
    127             ypos = parseInt(ypos);
    128             var mx = MyGlobal.mapWidth - 32;
    129             var my = MyGlobal.mapHeight - 32;
    130             switch (dir) {
    131                 case 'up': ypos <= 0 ? 0 : ypos--; break;
    132                 case 'right': xpos >= mx ? mx : xpos++; break;
    133                 case 'down': ypos >= my ? my : ypos++; break;
    134                 case 'left': xpos <= 0 ? 0 : xpos--; break;
    135             }
    136             setCss(tank, 'left', xpos + 'px');
    137             setCss(tank, 'top', ypos + 'px');
    138             var scope = this;
    139             var speed = this.speed;
    140             var repeat = function () {
    141                 scope.move(dir);
    142             };
    143             if (!this.tid) {
    144                 this.tid = setTimeout(repeat, speed);
    145             }
    146             //移动结束
    147             this.activeState = 0;
    148         }
    149         Tank.prototype.stop = function () {
    150             clearTimeout(this.tid);
    151             this.tid = null;
    152         };
    153 
    154         var tank = new Tank('me', 'up', 100, 100);
    155         tank.init();
    156 
    157         function getDir(code) {
    158             if (code == '87' || code == '119') {
    159                 return 'up';
    160             }
    161             if (code == '100' || code == '68') {
    162                 return 'right';
    163             }
    164             if (code == '115' || code == '83') {
    165                 return 'down';
    166             }
    167             if (code == '97' || code == '65') {
    168                 return 'left';
    169             }
    170             return null;
    171         }
    172 
    173         document.onkeydown = function (evt) {
    174             evt = (evt) ? evt : window.event;
    175             var keyCode = evt.keyCode;
    176             var charCode = evt.charCode;
    177             var dir = getDir();
    178             if (keyCode) {
    179                 dir = getDir(keyCode.toString());
    180             }
    181             if (charCode) {
    182                 dir = getDir(charCode.toString());
    183             }
    184             tank.move(dir);
    185 
    186             evt.preventDefault();
    187             return false;
    188         };
    189         document.onkeyup = function (evt) {
    190             tank.stop();
    191         };
    192         document.onkeypress = function (evt) {
    193             evt = (evt) ? evt : window.event;
    194             var keyCode = evt.keyCode;
    195             var charCode = evt.charCode;
    196             var dir = getDir();
    197             if (keyCode) {
    198                 dir = getDir(keyCode.toString());
    199             }
    200             if (charCode) {
    201                 dir = getDir(charCode.toString());
    202             }
    203             tank.move(dir);
    204 
    205             evt.preventDefault();
    206             return false;
    207         };
    208     </script>
    209 </body>
    210 </html>
    完整代码
     1 Tank.prototype.move = function (dir) {
     2     if (this.activeState != 0) return false; //正在运动我们便不管他
     3     this.activeState = 1; //将当前状态设置为正在运动
     4     if (this.direction != dir) {
     5         this.direction = dir;
     6         this.setDirection(dir);
     7     }
     8     //处理运动中的定时器
     9     if (this.tid) {
    10         clearTimeout(this.tid);
    11         this.tid = null;
    12     }
    13     var state = this.dirState[dir];
    14     var tank = this.el;
    15     if (state == 1 || state == -1) {
    16         var strPos = getCss(tank, 'backgroundPosition');
    17         var arrPos = strPos.split(' ');
    18         var l = arrPos ? arrPos[0] : 0;
    19         var t = arrPos ? arrPos[1] : 0;
    20         var curPos = parseInt(l);
    21         var top = parseInt(t);
    22         var po = curPos - (43) * (state);
    23         var curPos = po + 'px ' + t + 'px';
    24         setCss(tank, 'backgroundPosition', curPos);
    25     }
    26     var xpos = getCss(tank, 'left') ? getCss(tank, 'left') : 0;
    27     var ypos = getCss(tank, 'top') ? getCss(tank, 'top') : 0;
    28     xpos = parseInt(xpos);
    29     ypos = parseInt(ypos);
    30     var mx = MyGlobal.mapWidth - 32;
    31     var my = MyGlobal.mapHeight - 32;
    32     switch (dir) {
    33         case 'up': ypos <= 0 ? 0 : ypos--; break;
    34         case 'right': xpos >= mx ? mx : xpos++; break;
    35         case 'down': ypos >= my ? my : ypos++; break;
    36         case 'left': xpos <= 0 ? 0 : xpos--; break;
    37     }
    38     setCss(tank, 'left', xpos + 'px');
    39     setCss(tank, 'top', ypos + 'px');
    40     var scope = this;
    41     var speed = this.speed;
    42     var repeat = function () {
    43         scope.move(dir);
    44     };
    45     if (!this.tid) {
    46         this.tid = setTimeout(repeat, speed);
    47     }
    48     //移动结束
    49     this.activeState = 0;
    50 };

    这个代码其实没什么好说的,只不过我们每次运动后会改变其方向的状态值,为的就是不停的改变背景,以达到坦克前进的效果。

    运行效果(此处可运行):

    于是我们简单的完成了坦克移动的功能了,现在我们来考虑炮弹的问题了。

    炮弹对象

    上面的是坦克对象,我们现在来看看炮弹对象,我们将坦克,炮弹,砖块各自看做一个对象,这样不知道面向对象没。。。

      1 //子弹对象
      2 var Bullet = function (dir) {
      3     this.direction = dir ? dir : 'up';
      4     this.speed = 5;
      5     var factor = 0;
      6     this.tid = null;
      7     this.activeState = 0;
      8     this.blastState = 0; //爆炸状态 0-4
      9     this.blastReason = 0; //爆炸原因 0一般爆炸,4 集中坦克 3......
     10     this.x = 0;
     11     this.y = 0;
     12     if (dir) {
     13         switch (dir) {
     14             case 'up': factor = 0; break;
     15             case 'right': factor = 1; break;
     16             case 'down': factor = 2; break;
     17             case 'left': factor = 3; break;
     18         }
     19     }
     20     var el = document.createElement('div');
     21     var bp = 'background-position :' + (0 - 8 * factor) + 'px  0 ;';
     22     el.setAttribute('style', bp);
     23     el.setAttribute('class', 'bullet');
     24     this.el = el;
     25 };
     26 
     27 Bullet.prototype.move = function () {
     28 
     29     var bullet = this.el;
     30     var dir = this.direction;
     31     var xpos = getCss(bullet, 'left') ? getCss(bullet, 'left') : 0;
     32     var ypos = getCss(bullet, 'top') ? getCss(bullet, 'top') : 0;
     33     xpos = parseInt(xpos);
     34     ypos = parseInt(ypos);
     35     var mx = MyGlobal.mapWidth - 8;
     36     var my = MyGlobal.mapHeight - 8;
     37     var stop = false;
     38     switch (dir) {
     39         case 'up':
     40             if (ypos <= 0) {
     41                 stop = true;
     42             } else {
     43                 ypos--;
     44             }
     45             break;
     46         case 'right':
     47             if (xpos >= mx) {
     48                 stop = true;
     49             } else {
     50                 xpos++;
     51             }
     52             break;
     53         case 'down':
     54             if (ypos >= my) {
     55                 stop = true;
     56             } else {
     57                 ypos++;
     58             }
     59             break;
     60         case 'left':
     61             if (xpos <= 0) {
     62                 stop = true;
     63             } else {
     64                 xpos--;
     65             }
     66             break;
     67     }
     68 
     69     setCss(bullet, 'left', xpos + 'px');
     70     setCss(bullet, 'top', ypos + 'px');
     71     this.x = xpos;
     72     this.y = ypos;
     73 
     74     var scope = this;
     75     var speed = this.speed;
     76     var repeat = function () {
     77         scope.move();
     78     };
     79     if (this.tid) {
     80         clearTimeout(this.tid);
     81         this.tid = null;
     82     }
     83     if (!this.tid) {
     84         this.tid = setTimeout(repeat, speed);
     85     }
     86     if (stop) {
     87         this.blast();
     88     }
     89 };
     90 
     91 Bullet.prototype.blast = function (reason) {
     92     var el = this.el;
     93     var x = this.x - 28;
     94     var y = this.y - 28;
     95     setCss(el, 'left', x + 'px');
     96     setCss(el, 'top', y + 'px');
     97     this.x = x;
     98     this.y = y;
     99     var scope = this;
    100     setAttr(el, 'class', 'Boom');
    101     setCss(scope.el, 'backgroundPosition', '0 0');
    102     var action = function () {
    103         if (scope.blastState < (scope.blastReason + 1)) {
    104             var b = scope.blastState * 64 * (-1);
    105             b = b + 'px 0';
    106             setCss(scope.el, 'backgroundPosition', b);
    107             scope.blastState++;
    108             setTimeout(action, 20);
    109         } else {
    110             getById('map').removeChild(scope.el);
    111             delete scope;
    112         }
    113     };
    114     if (reason) {
    115         this.blastReason = reason;
    116     }
    117     setTimeout(action, 20);
    118 
    119     clearTimeout(this.tid);
    120     this.tid = null;
    121 
    122     //    this.blastState
    123 
    124 };

    完整代码:

      1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      2 <html xmlns="http://www.w3.org/1999/xhtml">
      3 <head>
      4     <title></title>
      5     <style type="text/css">
      6         .map { background: gray; border: 1px solid black; position: relative; margin: 50px auto; width: 416px; height: 416px; }
      7         .tank { background-image: url("//images0.cnblogs.com/blog/294743/201306/12123133-eaa9ada8690e4216a2bee3e56442e032.gif"); background-repeat: no-repeat; overflow: hidden; position: absolute; width: 32px; height: 32px; z-index: 3; }
      8         .bullet { background-image: url('//images0.cnblogs.com/blog/294743/201306/12123510-662de29d9e0c447389b42fcb47bff652.gif'); width: 8px; height: 8px; position: absolute; z-index: 4; background-repeat: no-repeat; }
      9         .Boom { background-image: url('//images0.cnblogs.com/blog/294743/201306/12121341-0e6fba003915418a909cde86d0b8aac6.png'); width: 64px; height: 64px; position: absolute; z-index: 4; }
     10     </style>
     11 </head>
     12 <body>
     13     <div class="map" id="map">
     14         <div id="me" class="tank">
     15         </div>
     16     </div>
     17     <script type="text/javascript">
     18         function getById(id) {
     19             return !id ? null : document.getElementById(id);
     20         }
     21 
     22         function getAttr(el, k) {
     23             if (el) {
     24                 var v = el.getAttribute[k] ? el.getAttribute[k] : null;
     25                 return v;
     26             }
     27         }
     28 
     29         function setAttr(el, k, v) {
     30             if (el) {
     31                 el.setAttribute(k, v);
     32             }
     33         }
     34 
     35         function getCss(el, k) {
     36             if (el) {
     37 
     38                 if (el.style[k]) {
     39                     return el.style[k];
     40                 }
     41                 return null;
     42             }
     43         }
     44 
     45         function setCss(el, k, v) {
     46             if (el) {
     47                 if (!el.style || el.style.length == 0) {
     48                     el.style = {};
     49                 }
     50                 el.style[k] = v;
     51             }
     52         }
     53 
     54         var MyGlobal = {
     55             mapWidth: 416,
     56             mapHeight: 416,
     57              448,
     58             height: 512
     59         };
     60 
     61         //子弹对象
     62         var Bullet = function (dir) {
     63             this.direction = dir ? dir : 'up';
     64             this.speed = 5;
     65             var factor = 0;
     66             this.tid = null;
     67             this.activeState = 0;
     68             this.blastState = 0; //爆炸状态 0-4
     69             this.blastReason = 0; //爆炸原因 0一般爆炸,4 集中坦克 3......
     70             this.x = 0;
     71             this.y = 0;
     72             if (dir) {
     73                 switch (dir) {
     74                     case 'up': factor = 0; break;
     75                     case 'right': factor = 1; break;
     76                     case 'down': factor = 2; break;
     77                     case 'left': factor = 3; break;
     78                 }
     79             }
     80             var el = document.createElement('div');
     81             var bp = 'background-position :' + (0 - 8 * factor) + 'px  0 ;';
     82             el.setAttribute('style', bp);
     83             el.setAttribute('class', 'bullet');
     84             this.el = el;
     85         };
     86 
     87         Bullet.prototype.move = function () {
     88 
     89             var bullet = this.el;
     90             var dir = this.direction;
     91             var xpos = getCss(bullet, 'left') ? getCss(bullet, 'left') : 0;
     92             var ypos = getCss(bullet, 'top') ? getCss(bullet, 'top') : 0;
     93             xpos = parseInt(xpos);
     94             ypos = parseInt(ypos);
     95             var mx = MyGlobal.mapWidth - 8;
     96             var my = MyGlobal.mapHeight - 8;
     97             var stop = false;
     98             switch (dir) {
     99                 case 'up':
    100                     if (ypos <= 0) {
    101                         stop = true;
    102                     } else {
    103                         ypos--;
    104                     }
    105                     break;
    106                 case 'right':
    107                     if (xpos >= mx) {
    108                         stop = true;
    109                     } else {
    110                         xpos++;
    111                     }
    112                     break;
    113                 case 'down':
    114                     if (ypos >= my) {
    115                         stop = true;
    116                     } else {
    117                         ypos++;
    118                     }
    119                     break;
    120                 case 'left':
    121                     if (xpos <= 0) {
    122                         stop = true;
    123                     } else {
    124                         xpos--;
    125                     }
    126                     break;
    127             }
    128 
    129             setCss(bullet, 'left', xpos + 'px');
    130             setCss(bullet, 'top', ypos + 'px');
    131             this.x = xpos;
    132             this.y = ypos;
    133 
    134             var scope = this;
    135             var speed = this.speed;
    136             var repeat = function () {
    137                 scope.move();
    138             };
    139             if (this.tid) {
    140                 clearTimeout(this.tid);
    141                 this.tid = null;
    142             }
    143             if (!this.tid) {
    144                 this.tid = setTimeout(repeat, speed);
    145             }
    146             if (stop) {
    147                 this.blast();
    148             }
    149         };
    150 
    151         Bullet.prototype.blast = function (reason) {
    152             var el = this.el;
    153             var x = this.x - 28;
    154             var y = this.y - 28;
    155             setCss(el, 'left', x + 'px');
    156             setCss(el, 'top', y + 'px');
    157             this.x = x;
    158             this.y = y;
    159             var scope = this;
    160             setAttr(el, 'class', 'Boom');
    161             setCss(scope.el, 'backgroundPosition', '0 0');
    162             var action = function () {
    163                 if (scope.blastState < (scope.blastReason + 1)) {
    164                     var b = scope.blastState * 64 * (-1);
    165                     b = b + 'px 0';
    166                     setCss(scope.el, 'backgroundPosition', b);
    167                     scope.blastState++;
    168                     setTimeout(action, 20);
    169                 } else {
    170                     getById('map').removeChild(scope.el);
    171                     delete scope;
    172                 }
    173             };
    174             if (reason) {
    175                 this.blastReason = reason;
    176             }
    177             setTimeout(action, 20);
    178 
    179             clearTimeout(this.tid);
    180             this.tid = null;
    181 
    182             //    this.blastState
    183 
    184         };
    185 
    186         //坦克对象
    187         var Tank = function (id, dir, x, y) {
    188             this.el = getById(id);
    189             this.direction = dir ? dir : 'up';
    190             this.tid = null;
    191             this.speed = 10;
    192             //坦克活动状态 0 未活动 1 正在活动
    193             this.activeState = 0;
    194             this.x = x ? x : 100;
    195             this.y = y ? y : 200;
    196             this.dirState = {
    197                 up: 1,
    198                 right: 1,
    199                 down: 1,
    200                 left: 1
    201             };
    202         };
    203         Tank.prototype.init = function () {
    204             var dir = this.direction;
    205             var tank = this.el;
    206             setCss(tank, 'left', this.x + 'px');
    207             setCss(tank, 'top', this.y + 'px');
    208             this.setDirection(dir);
    209         };
    210         Tank.prototype.setDirection = function (dir) {
    211             var tank = this.el;
    212             if (dir == 'up') {
    213                 setCss(tank, 'backgroundPosition', '0 0');
    214             }
    215             if (dir == 'right') {
    216                 setCss(tank, 'backgroundPosition', '-5px -36px');
    217             }
    218             if (dir == 'down') {
    219                 setCss(tank, 'backgroundPosition', '0 -73px');
    220             }
    221             if (dir == 'left') {
    222                 setCss(tank, 'backgroundPosition', '0 -105px');
    223             }
    224             this.dirState[dir] = 1;
    225         };
    226 
    227         Tank.prototype.move = function (dir) {
    228             if (this.activeState != 0) return false; //正在运动我们便不管他
    229             this.activeState = 1; //将当前状态设置为正在运动
    230             if (this.direction != dir) {
    231                 this.direction = dir;
    232                 this.setDirection(dir);
    233             }
    234             //处理运动中的定时器
    235             if (this.tid) {
    236                 clearTimeout(this.tid);
    237                 this.tid = null;
    238             }
    239             var state = this.dirState[dir];
    240             var tank = this.el;
    241             if (state == 1 || state == -1) {
    242                 var strPos = getCss(tank, 'backgroundPosition');
    243                 var arrPos = strPos.split(' ');
    244                 var l = arrPos ? arrPos[0] : 0;
    245                 var t = arrPos ? arrPos[1] : 0;
    246                 var curPos = parseInt(l);
    247                 var top = parseInt(t);
    248                 var po = curPos - (40) * (state);
    249                 var curPos = po + 'px ' + top + 'px';
    250                 setCss(tank, 'backgroundPosition', curPos);
    251                 this.dirState[dir] = state == 1 ? -1 : 1;
    252 
    253             }
    254             var xpos = getCss(tank, 'left') ? getCss(tank, 'left') : 0;
    255             var ypos = getCss(tank, 'top') ? getCss(tank, 'top') : 0;
    256             xpos = parseInt(xpos);
    257             ypos = parseInt(ypos);
    258             var mx = MyGlobal.mapWidth - 32;
    259             var my = MyGlobal.mapHeight - 32;
    260             switch (dir) {
    261                 case 'up': ypos <= 0 ? 0 : ypos--; break;
    262                 case 'right': xpos >= mx ? mx : xpos++; break;
    263                 case 'down': ypos >= my ? my : ypos++; break;
    264                 case 'left': xpos <= 0 ? 0 : xpos--; break;
    265             }
    266             setCss(tank, 'left', xpos + 'px');
    267             setCss(tank, 'top', ypos + 'px');
    268             this.x = xpos;
    269             this.y = ypos;
    270             var scope = this;
    271             var speed = this.speed;
    272             var repeat = function () {
    273                 scope.move(dir);
    274             };
    275             if (!this.tid) {
    276                 this.tid = setTimeout(repeat, speed);
    277             }
    278             //移动结束
    279             this.activeState = 0;
    280         };
    281 
    282         Tank.prototype.stop = function () {
    283             clearTimeout(this.tid);
    284             this.tid = null;
    285         };
    286 
    287         Tank.prototype.fire = function () {
    288             var bullet = new Bullet(this.direction);
    289             var l = (this.x + 12) + 'px';
    290             var t = (this.y + 12) + 'px'
    291             //    top:12px;left:12px;
    292             var el = bullet.el;
    293             setCss(el, 'top', t);
    294             setCss(el, 'left', l);
    295             bullet.y = this.y + 12;
    296             bullet.x = this.x + 12;
    297             getById('map').appendChild(el);
    298             //    bullet.el = this.el.getElementsByTagName('div')[0];
    299             bullet.move();
    300         };
    301 
    302 
    303         //实际应用
    304         var tank = new Tank('me', 'right', 100, 100);
    305         tank.init();
    306 
    307         function getDir(code) {
    308             if (code == '87' || code == '119') {
    309                 return 'up';
    310             }
    311             if (code == '100' || code == '68') {
    312                 return 'right';
    313             }
    314             if (code == '115' || code == '83') {
    315                 return 'down';
    316             }
    317             if (code == '97' || code == '65') {
    318                 return 'left';
    319             }
    320             return null;
    321         }
    322 
    323         document.onkeydown = function (evt) {
    324             evt = (evt) ? evt : window.event;
    325             var keyCode = evt.keyCode;
    326             var charCode = evt.charCode;
    327             var dir = getDir();
    328             if (keyCode) {
    329                 dir = getDir(keyCode.toString());
    330             }
    331             if (charCode) {
    332                 dir = getDir(charCode.toString());
    333             }
    334             if (dir)
    335                 tank.move(dir);
    336             if (charCode == '106' || keyCode == '74') {
    337                 tank.fire();
    338             }
    339             evt.preventDefault();
    340             return false;
    341         };
    342         document.onkeyup = function (evt) {
    343             tank.stop();
    344         };
    345         document.onkeypress = function (evt) {
    346             evt = (evt) ? evt : window.event;
    347             var keyCode = evt.keyCode;
    348             var charCode = evt.charCode;
    349             var dir = getDir();
    350             if (keyCode) {
    351                 dir = getDir(keyCode.toString());
    352             }
    353             if (charCode) {
    354                 dir = getDir(charCode.toString());
    355             }
    356             if (dir)
    357                 tank.move(dir);
    358             if (charCode == '106' || keyCode == '74') {
    359                 tank.fire();
    360             }
    361             evt.preventDefault();
    362             return false;
    363         };
    364     </script>
    365 </body>
    366 </html>
    完整代码

    效果演示(可运行)J可以发子弹,没有子弹就到高版本浏览器去试试

    http://sandbox.runjs.cn/show/evpyzcku

    结语

    好了,今天到此为止,后面点我们来一步步修改代码,让代码变得“面向对象”,有机会便加上砖块和其它东东。

    今天的代码不用说,千疮百孔,无论是性能方面,或者代码优雅度,还是神马都一团糟糕,但是经过几个小时的奋战,我现在脑子已经不好使了,只好暂时停一下。

    我们后面点优化吧。

  • 相关阅读:
    Kostya Keygen#2分析
    一个简单的windows勒索软件分析
    MSRHook与SSDTHook
    VS2013中调驱动
    VMProtect1.63分析
    Linux内核分析总结
    进程的切换和系统的一般执行过程
    可执行程序的装载
    进程的描述和进程的创建
    扒开系统调用的三层皮(下)
  • 原文地址:https://www.cnblogs.com/yexiaochai/p/3132553.html
Copyright © 2011-2022 走看看