小强的HTML5移动开发之路(8)——坦克大战游戏2

来源:互联网 发布:nba2k17亚洲人捏脸数据 编辑:程序博客网 时间:2024/05/11 14:34

来自:http://blog.csdn.net/cai_xingyun/article/details/48629015

在上一篇文章中我们已经画出了自己的坦克,并且可以控制自己的坦克移动,我们继续接着上一篇来实现我们的坦克大战游戏吧。

一、将JS文件分离出来

使用OO的思想,我们已经对坦克进行了封装,对画坦克也进行了封装,下面我们将这两个对象提取到外部的js文件中,文件内容如下:

  1. //定义一个Hero类(后面还要改进)  
  2. //x表示坦克的横坐标  
  3. //y表示纵坐标  
  4. //direct表示方向  
  5. function Hero(x,y,direct){  
  6.     this.x=x;  
  7.     this.y=y;  
  8.     this.speed=1;  
  9.     this.direct=direct;  
  10.     //上移  
  11.     this.moveUp=function(){  
  12.         this.y-=this.speed;  
  13.         this.direct=0;  
  14.     }  
  15.     //右移  
  16.     this.moveRight=function(){  
  17.         this.x+=this.speed;  
  18.         this.direct=1;  
  19.     }  
  20.     //下移  
  21.     this.moveDown=function(){  
  22.         this.y+=this.speed;  
  23.         this.direct=2;  
  24.     }  
  25.     //左移  
  26.     this.moveLeft=function(){  
  27.         this.x-=this.speed;  
  28.         this.direct=3;  
  29.     }  
  30. }  
  31.   
  32.     //绘制坦克  
  33. function drawTank(tank){  
  34.     //考虑方向  
  35.     switch(tank.direct){  
  36.         case 0:     //向上  
  37.         case 2:     //向下  
  38.             //设置颜色  
  39.             cxt.fillStyle="#BA9658";  
  40.             //左边的矩形  
  41.             cxt.fillRect(tank.x,tank.y,5,30);  
  42.             //右边的矩形  
  43.             cxt.fillRect(tank.x+17,tank.y,5,30);  
  44.             //画中间的矩形  
  45.             cxt.fillRect(tank.x+6,tank.y+5,10,20);  
  46.             //画出坦克的盖子  
  47.             cxt.fillStyle="#FEF26E";  
  48.             cxt.arc(tank.x+11,tank.y+15,5,0,Math.PI*2,true);  
  49.             cxt.fill();  
  50.             //画出炮筒  
  51.             cxt.strokeStyle="#FEF26E";  
  52.             cxt.lineWidth=1.5;  
  53.             cxt.beginPath();  
  54.             cxt.moveTo(tank.x+11,tank.y+15);  
  55.             if(tank.direct==0){         //只是炮筒的方向不同  
  56.                 cxt.lineTo(tank.x+11,tank.y);  
  57.             }else{  
  58.                 cxt.lineTo(tank.x+11,tank.y+30);  
  59.             }  
  60.             cxt.closePath();  
  61.             cxt.stroke();  
  62.             break;  
  63.         case 1:  
  64.         case 3:  
  65.             //设置颜色  
  66.             cxt.fillStyle="#BA9658";  
  67.             //上边的矩形  
  68.             cxt.fillRect(tank.x-4,tank.y+4,30,5);  
  69.             //下边的矩形  
  70.             cxt.fillRect(tank.x-4,tank.y+17+4,30,5);  
  71.             //画中间的矩形  
  72.             cxt.fillRect(tank.x+5-4,tank.y+6+4,20,10);  
  73.             //画出坦克的盖子  
  74.             cxt.fillStyle="#FEF26E";  
  75.             cxt.arc(tank.x+15-4,tank.y+11+4,5,0,Math.PI*2,true);  
  76.             cxt.fill();  
  77.             //画出炮筒  
  78.             cxt.strokeStyle="#FEF26E";  
  79.             cxt.lineWidth=1.5;  
  80.             cxt.beginPath();  
  81.             cxt.moveTo(tank.x+15-4,tank.y+11+4);  
  82.             if(tank.direct==1){         //只是炮筒的方向不同  
  83.                 cxt.lineTo(tank.x+30-4,tank.y+11+4);  
  84.             }else{  
  85.                 cxt.lineTo(tank.x-4,tank.y+11+4);  
  86.             }  
  87.             cxt.closePath();  
  88.             cxt.stroke();  
  89.             break;    
  90.     }  
  91.       
  92. }  

在上一篇中有一个小问题,感谢 Mark_Lee的提醒

  1. //画出坦克的盖子  
  2. cxt.fillStyle="#FEF26E";  
  3. cxt.arc(tank.x+15-4,tank.y+11+4,5,0,360,true);  
  4. cxt.fill();  

这里画的坦克盖子不是园的,大家可以参考:http://www.w3school.com.cn/html5/canvas_arc.asp


好了,现在我们的html中的内容就变的清晰多了,html中的内容如下:

  1. <!DOCTYPE html>  
  2. <html>  
  3. <head>  
  4. <meta charset="utf-8"/>  
  5. </head>  
  6. <body onkeydown="getCommand();">  
  7. <h1>html5-坦克大战</h1>  
  8. <!--坦克大战的战场-->  
  9. <canvas id="tankMap" width="400px" height="300px" style="background-color:black"></canvas>  
  10. <!--将tankGame04.js引入-->  
  11. <script type="text/javascript" src="tankGame04.js"></script>  
  12. <script type="text/javascript">  
  13.   
  14.   
  15.     //得到画布  
  16.     var canvas1 = document.getElementById("tankMap");  
  17.     //得到绘图上下文  
  18.     var cxt = canvas1.getContext("2d");  
  19.       
  20.     //我的tank  
  21.     //规定0向上、1向右、2向下、3向左  
  22.     var hero = new Hero(40,40,0);  
  23.     drawTank(hero);  
  24.   
  25.       
  26.     //接收用户按键的函数  
  27.     function getCommand(){  
  28.         var code = event.keyCode;  //键盘上字幕的ASCII码  
  29.         switch(code){  
  30.             case 87:  
  31.                 hero.moveUp();  
  32.                 break;  
  33.             case 68:  
  34.                 hero.moveRight();  
  35.                 break;  
  36.             case 83:  
  37.                 hero.moveDown();  
  38.                 break;  
  39.             case 65:  
  40.                 hero.moveLeft();  
  41.                 break;  
  42.         }  
  43.         //把画布清理  
  44.         cxt.clearRect(0,0,400,300);  
  45.         //重新绘制  
  46.         drawTank(hero);  
  47.     }  
  48. </script>  
  49. </body>  
  50. </html>  

二、绘制敌人的坦克

好多朋友可能现在已经有了思路,这还不简单吗?画敌人坦克的时候再新建立一个function仿照自己的坦克类再写一遍不就好了吗。还有的朋友不同意这个方法,说:既然都是坦克我们就不用写了,直接创建坦克实例不就完了吗。第一个朋友和第二个朋友的做法看似是面向对象其实不是面向对象,在做这种游戏的时候如果我们不用面向对象的思想去实现,也可以实现,但是会很复杂。

我们这样考虑一下,自己坦克肯定和敌人坦克有区别,不能归为一类,比如:发的子弹不同,颜色不同等。但是两者又有相同点(都是坦克),我们是不是应该把这部分给抽象出来呢?是的,我们先抽象出来一个Tank类,再分别继承这个Tank类。你开玩笑吧大笑这个不是Java语言,这个是javascript脚本语言,哪里来的继承?惊讶呵呵,我们可以用javascript中的对象冒充,对象冒充,是JavaScript 和 ECMAScript实现继承的方法,在学习对象冒充实现继承前我们的先了解关键字 this 的使用

  1. function  classA(color){  
  2.   this.color = color;  
  3.   this.show = function(){alert(this.color);}  
  4. }  
  5. /* 
  6.    Note: 
  7.      1> this 代表的是classA函数所构建的对象,而非函数classA对象本身这样说主要是为了避免(function is object)的影响; 
  8.      2> 在构建classA对象时,是通过this来初始化的属性和方法的,如果用classB的this去冒充classA的this,那么就实现了简单的继承了 
  9. */  
对象冒充的原理:函数classA通过this来初始化属性和方法,如果用函数classB的this冒充classA的this去执行,则就会使classB具有classA的属性和方法

好了,现在我们用自己的坦克和敌人的坦克对象去冒充一下坦克,呵呵。

  1. //定义一个Tank类(基类)  
  2. function Tank(x,y,direct,color){  
  3.     this.x=x;  
  4.     this.y=y;  
  5.     this.speed=1;  
  6.     this.direct=direct;  
  7.     this.color=color;  
  8.     //上移  
  9.     this.moveUp=function(){  
  10.         this.y-=this.speed;  
  11.         this.direct=0;  
  12.     }  
  13.     //右移  
  14.     this.moveRight=function(){  
  15.         this.x+=this.speed;  
  16.         this.direct=1;  
  17.     }  
  18.     //下移  
  19.     this.moveDown=function(){  
  20.         this.y+=this.speed;  
  21.         this.direct=2;  
  22.     }  
  23.     //左移  
  24.     this.moveLeft=function(){  
  25.         this.x-=this.speed;  
  26.         this.direct=3;  
  27.     }  
  28. }  
  29.   
  30. //定义一个Hero类  
  31. function Hero(x,y,direct,color){  
  32.     //下面两句话的作用是通过对象冒充达到继承的效果  
  33.     this.tank=Tank;  
  34.     this.tank(x,y,direct,color);  
  35. }  
  36.   
  37. //定义一个EnemyTank类  
  38. function EnemyTank(x,y,direct,color){  
  39.     this.tank=Tank;  
  40.     this.tank(x,y,direct,color);  
  41. }  
这样我们就将自己的坦克和敌人的坦克定义好了,那么绘制坦克的drawTank(tank)要不要变呢?因为绘制的是Tank所以不需要改动,呵呵,这就是面向对象的多态喽。

创建坦克对象吧!

  1. //我的tank  
  2. //规定0向上、1向右、2向下、3向左  
  3. var hero=new Hero(40,40,0,heroColor);  
  4. //敌人的tank  
  5. var enemyTanks=new Array();  
  6. for(var i=0;i<3;i++){  
  7.     var enemyTank = new EnemyTank((i+1)*50,0,2,enemyColor);  
  8.     enemyTanks[i]=enemyTank;      
  9. }  

完整代码如下:

tankGame05.js

  1. //为了编程方便,我们定义两个颜色数组  
  2. var heroColor=new Array("#BA9658","#FEF26E");  
  3. var enemyColor=new Array("#00A2B5","#00FEFE");  
  4.   
  5. //定义一个Tank类(基类)  
  6. function Tank(x,y,direct,color){  
  7.     this.x=x;  
  8.     this.y=y;  
  9.     this.speed=1;  
  10.     this.direct=direct;  
  11.     this.color=color;  
  12.     //上移  
  13.     this.moveUp=function(){  
  14.         this.y-=this.speed;  
  15.         this.direct=0;  
  16.     }  
  17.     //右移  
  18.     this.moveRight=function(){  
  19.         this.x+=this.speed;  
  20.         this.direct=1;  
  21.     }  
  22.     //下移  
  23.     this.moveDown=function(){  
  24.         this.y+=this.speed;  
  25.         this.direct=2;  
  26.     }  
  27.     //左移  
  28.     this.moveLeft=function(){  
  29.         this.x-=this.speed;  
  30.         this.direct=3;  
  31.     }  
  32. }  
  33.   
  34. //定义一个Hero类  
  35. function Hero(x,y,direct,color){  
  36.     //下面两句话的作用是通过对象冒充达到继承的效果  
  37.     this.tank=Tank;  
  38.     this.tank(x,y,direct,color);  
  39. }  
  40.   
  41. //定义一个EnemyTank类  
  42. function EnemyTank(x,y,direct,color){  
  43.     this.tank=Tank;  
  44.     this.tank(x,y,direct,color);  
  45. }  
  46.   
  47.     //绘制坦克  
  48. function drawTank(tank){  
  49.     //考虑方向  
  50.     switch(tank.direct){  
  51.         case 0:     //向上  
  52.         case 2:     //向下  
  53.             //设置颜色  
  54.             cxt.fillStyle=tank.color[0];  
  55.             //左边的矩形  
  56.             cxt.fillRect(tank.x,tank.y,5,30);  
  57.             //右边的矩形  
  58.             cxt.fillRect(tank.x+17,tank.y,5,30);  
  59.             //画中间的矩形  
  60.             cxt.fillRect(tank.x+6,tank.y+5,10,20);  
  61.             //画出坦克的盖子  
  62.             cxt.fillStyle=tank.color[1];  
  63.             cxt.arc(tank.x+11,tank.y+15,5,0,Math*PI*2,true);  
  64.             cxt.fill();  
  65.             //画出炮筒  
  66.             cxt.strokeStyle=tank.color[1];  
  67.             cxt.lineWidth=1.5;  
  68.             cxt.beginPath();  
  69.             cxt.moveTo(tank.x+11,tank.y+15);  
  70.             if(tank.direct==0){         //只是炮筒的方向不同  
  71.                 cxt.lineTo(tank.x+11,tank.y);  
  72.             }else{  
  73.                 cxt.lineTo(tank.x+11,tank.y+30);  
  74.             }  
  75.             cxt.closePath();  
  76.             cxt.stroke();  
  77.             break;  
  78.         case 1:  
  79.         case 3:  
  80.             //设置颜色  
  81.             cxt.fillStyle="#BA9658";  
  82.             //上边的矩形  
  83.             cxt.fillRect(tank.x-4,tank.y+4,30,5);  
  84.             //下边的矩形  
  85.             cxt.fillRect(tank.x-4,tank.y+17+4,30,5);  
  86.             //画中间的矩形  
  87.             cxt.fillRect(tank.x+5-4,tank.y+6+4,20,10);  
  88.             //画出坦克的盖子  
  89.             cxt.fillStyle="#FEF26E";  
  90.             cxt.arc(tank.x+15-4,tank.y+11+4,5,0,Math*PI*2,true);  
  91.             cxt.fill();  
  92.             //画出炮筒  
  93.             cxt.strokeStyle="#FEF26E";  
  94.             cxt.lineWidth=1.5;  
  95.             cxt.beginPath();  
  96.             cxt.moveTo(tank.x+15-4,tank.y+11+4);  
  97.             if(tank.direct==1){         //只是炮筒的方向不同  
  98.                 cxt.lineTo(tank.x+30-4,tank.y+11+4);  
  99.             }else{  
  100.                 cxt.lineTo(tank.x-4,tank.y+11+4);  
  101.             }  
  102.             cxt.closePath();  
  103.             cxt.stroke();  
  104.             break;    
  105.     }  
  106.       
  107. }  

坦克大战.html

  1. <!DOCTYPE html>  
  2. <html>  
  3. <head>  
  4. <meta charset="utf-8"/>  
  5. </head>  
  6. <body onkeydown="getCommand();">  
  7. <h1>html5-坦克大战</h1>  
  8. <!--坦克大战的战场-->  
  9. <canvas id="tankMap" width="400px" height="300px" style="background-color:black"></canvas>  
  10. <!--将tankGame04.js引入-->  
  11. <script type="text/javascript" src="tankGame05.js"></script>  
  12. <script type="text/javascript">  
  13.     //得到画布  
  14.     var canvas1=document.getElementById("tankMap");  
  15.     //得到绘图上下文  
  16.     var cxt=canvas1.getContext("2d");  
  17.       
  18.     //我的tank  
  19.     //规定0向上、1向右、2向下、3向左  
  20.     var hero=new Hero(40,40,0,heroColor);  
  21.     //敌人的tank  
  22.     var enemyTanks=new Array();  
  23.     for(var i=0;i<3;i++){  
  24.         var enemyTank = new EnemyTank((i+1)*50,0,2,enemyColor);  
  25.         enemyTanks[i]=enemyTank;      
  26.     }  
  27.       
  28.     //定时刷新我们的作战区(定时重绘)  
  29.     //自己的坦克,敌人坦克,子弹,炸弹,障碍物  
  30.     function flashTankMap(){  
  31.         //把画布清理  
  32.         cxt.clearRect(0,0,400,300);  
  33.         //我的坦克  
  34.         drawTank(hero);  
  35.         //敌人的坦克  
  36.         for(var i=0;i<3;i++){  
  37.             drawTank(enemyTanks[i]);  
  38.         }  
  39.     }  
  40.     flashTankMap();  
  41.     //接收用户按键的函数  
  42.     function getCommand(){  
  43.         var code = event.keyCode;  //键盘上字幕的ASCII码  
  44.         switch(code){  
  45.             case 87:  
  46.                 hero.moveUp();  
  47.                 break;  
  48.             case 68:  
  49.                 hero.moveRight();  
  50.                 break;  
  51.             case 83:  
  52.                 hero.moveDown();  
  53.                 break;  
  54.             case 65:  
  55.                 hero.moveLeft();  
  56.                 break;  
  57.         }  
  58.         flashTankMap();  
  59.     }  
  60. </script>  
  61. </body>  
  62. </html>  
运行效果:

 既然我们的坦克和敌人的坦克都有了,我们要让他们战斗起来,下一篇我们将让坦克发子弹。


0 0