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


    来自: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>  
    运行效果:

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


  • 相关阅读:
    HTML和CSS
    springcloud中配置多数据源
    洛谷 P3800 Power收集(单调队列优化dp)
    洛谷 P2569 [SCOI2010]股票交易(单调队列优化dp)
    洛谷 P3957 [NOIP2017 普及组] 跳房子(二分,单调队列优化dp)
    洛谷 P1419 寻找段落(01分数规划,实数二分,单调队列)
    Prometheus(普罗米修斯)和grafana监控的安装和使用
    AMC如何管理NPL
    linux 正则表达式与字符处理
    react-router-dom switch & match
  • 原文地址:https://www.cnblogs.com/wanghang/p/6298973.html
Copyright © 2020-2023  润新知