首页 web前端 H5教程 小强的HTML5移动开发之路(9)——坦克大战游戏3

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

Jan 22, 2017 am 11:18 AM

上一篇我们创建了敌人的坦克和自己的坦克,接下来就应该让坦克发子弹了,我们下面来看一下如何让我们的坦克发出子弹。

前面我们用面向对象的思想对Tank进行了封装,又利用对象冒充实现了我们的坦克和敌人的坦克,仿照这种方式我们是不是也应该封装一个Bullet,答案是肯定的。好吧,那么我们再想想这个Bullet"类“都应该封装什么东西呢?位置应该有吧、子弹飞行的方向应该有吧、飞行的速度也应该有吧、自己飞出去的动作应该有吧。好啦,大概就这些,封装后的Bulle”t类“如下:

//子弹类  
function Bullet(x,y,direct,speed){  
    this.x=x;  
    this.y=y;  
    this.speed=speed;  
    this.direct=direct;  
    this.timer=null;  
    this.run=function(){  
        switch(this.direct){  
            case 0:  
                this.y-=this.speed;  
                break;  
            case 1:  
                this.x+=this.speed;  
                break;  
            case 2:  
                this.y+=this.speed;  
                break;  
            case 3:  
                this.x-=this.speed;  
                break;    
        }  
          
    }  
}
登录后复制

我们已经创建好子弹的模型了,下面就用我们的坦克创造子弹将子弹发出去,在Hero类中添加shotEnemy方法。

//定义一个Hero类  
function Hero(x,y,direct,color){  
    //下面两句话的作用是通过对象冒充达到继承的效果  
    this.tank=Tank;  
    this.tank(x,y,direct,color);  
    //射击敌人函数  
    this.shotEnemy=function(){  
        switch(this.direct){  
            case 0:  
                heroBullet=new Bullet(this.x+10,this.y,this.direct,1);  
                break;  
            case 1:  
                heroBullet=new Bullet(this.x+30-4,this.y+10+4,this.direct,1);  
                break;  
            case 2:  
                heroBullet=new Bullet(this.x+10,this.y+30,this.direct,1);  
                break;  
            case 3:  
                heroBullet=new Bullet(this.x-4,this.y+10+4,this.direct,1);  
                break;  
        }  
        //把这个子弹放入数组中——》push函数  
        //调用我们子弹的run  
        //var timer=window.setInterval("heroBullet.run()",50);  
        //heroBullet.timer=timer;  
        heroBullets.push(heroBullet);  
        var timer=window.setInterval("heroBullets["+(heroBullets.length-1)+"].run()",50);  
        heroBullets[heroBullets.length-1].timer=timer;  
          
    }  
}
登录后复制

再在按键监听函数中添加一个监听发射子弹的键“J"

case 74: //J  :发子弹  
    hero.shotEnemy();  
    break;
登录后复制

好了我们来试着发射一下子弹吧!子弹怎么只能发一颗,而且越发越快,这是怎么回事呢?再看看我们上面写的代码,原来我们的子弹一旦发出去就不能停止了,虽然跑出了我们的”战场“但是还是在朝一个方向跑,一旦发第二颗子弹第一颗子弹就会由于重新刷新界面没有重绘子弹而消失。好了既然知道原因了下面我们判断一下子弹是否出界,然后给子弹一个状态isLive(这个状态标记子弹是否存在,如果不存在则在重绘子弹的时候不再重绘),修改后的代码如下:

//子弹类  
unction Bullet(x,y,direct,speed){  
this.x=x;  
this.y=y;  
this.speed=speed;  
this.direct=direct;  
this.timer=null;  
this.isLive=true;  
this.run=function(){  
    //判断子弹是否已经到边界了  
    if(this.x<=0||this.x>=400||this.y<=0||this.y>=300){  
        //子弹要停止  
        window.clearInterval(this.timer);  
        //子弹死亡  
        this.isLive=false;  
    }else{  
        //可以去修改坐标  
        switch(this.direct){  
            case 0:  
                this.y-=this.speed;  
                break;  
            case 1:  
                this.x+=this.speed;  
                break;  
            case 2:  
                    break;    
        }  
    }  
}
登录后复制

如果子弹超出了canvas的范围则将isLive属性该为false


然后我们在前面的刷新界面函数中添加一个刷新子弹函数

//定时刷新我们的作战区(定时重绘)  
//自己的坦克,敌人坦克,子弹,炸弹,障碍物  
function flashTankMap(){  
    //把画布清理  
    cxt.clearRect(0,0,400,300);  
    //我的坦克  
    drawTank(hero);  
    //我的子弹  
    drawHeroBullet();  
    //敌人的坦克  
    for(var i=0;i<3;i++){  
        drawTank(enemyTanks[i]);  
    }  
}
登录后复制
//画出自己的子弹  
function drawHeroBullet(){  
    for(var i=0;i<heroBullets.length;i++){  
        var heroBullet=heroBullets[i];  
        if(heroBullet!=null&&heroBullet.isLive){  
            cxt.fillStyle="#FEF26E";  
            cxt.fillRect(heroBullet.x,heroBullet.y,2,2);  
        }  
    }  
}
登录后复制

可以看到上面的drawHeroBullet中判断了子弹的isLive属性。


看看运行结果吧

710.gif

全部源代码如下:

tankGame06.js

//为了编程方便,我们定义两个颜色数组  
var heroColor=new Array("#BA9658","#FEF26E");  
var enemyColor=new Array("#00A2B5","#00FEFE");  
  
    //子弹类  
function Bullet(x,y,direct,speed){  
    this.x=x;  
    this.y=y;  
    this.speed=speed;  
    this.direct=direct;  
    this.timer=null;  
    this.isLive=true;  
    this.run=function(){  
        //判断子弹是否已经到边界了  
        if(this.x<=0||this.x>=400||this.y<=0||this.y>=300){  
            //子弹要停止  
            window.clearInterval(this.timer);  
            //子弹死亡  
            this.isLive=false;  
        }else{  
            //可以去修改坐标  
            switch(this.direct){  
                case 0:  
                    this.y-=this.speed;  
                    break;  
                case 1:  
                    this.x+=this.speed;  
                    break;  
                case 2:  
                    this.y+=this.speed;  
                    break;  
                case 3:  
                    this.x-=this.speed;  
                    break;    
            }  
        }  
    }  
}  
  
//定义一个Tank类(基类)  
function Tank(x,y,direct,color){  
    this.x=x;  
    this.y=y;  
    this.speed=1;  
    this.direct=direct;  
    this.color=color;  
    //上移  
    this.moveUp=function(){  
        this.y-=this.speed;  
        this.direct=0;  
    }  
    //右移  
    this.moveRight=function(){  
        this.x+=this.speed;  
        this.direct=1;  
    }  
    //下移  
    this.moveDown=function(){  
        this.y+=this.speed;  
        this.direct=2;  
    }  
    //左移  
    this.moveLeft=function(){  
        this.x-=this.speed;  
        this.direct=3;  
    }  
}  
  
//定义一个Hero类  
function Hero(x,y,direct,color){  
    //下面两句话的作用是通过对象冒充达到继承的效果  
    this.tank=Tank;  
    this.tank(x,y,direct,color);  
    //设计敌人函数  
    this.shotEnemy=function(){  
        switch(this.direct){  
            case 0:  
                heroBullet=new Bullet(this.x+10,this.y,this.direct,1);  
                break;  
            case 1:  
                heroBullet=new Bullet(this.x+30-4,this.y+10+4,this.direct,1);  
                break;  
            case 2:  
                heroBullet=new Bullet(this.x+10,this.y+30,this.direct,1);  
                break;  
            case 3:  
                heroBullet=new Bullet(this.x-4,this.y+10+4,this.direct,1);  
                break;  
        }  
        //把这个子弹放入数组中——》push函数  
        //调用我们子弹的run  
        //var timer=window.setInterval("heroBullet.run()",50);  
        //heroBullet.timer=timer;  
        heroBullets.push(heroBullet);  
        var timer=window.setInterval("heroBullets["+(heroBullets.length-1)+"].run()",50);  
        heroBullets[heroBullets.length-1].timer=timer;  
          
    }  
}  
  
//定义一个EnemyTank类  
function EnemyTank(x,y,direct,color){  
    this.tank=Tank;  
    this.tank(x,y,direct,color);  
}  
  
    //绘制坦克  
function drawTank(tank){  
    //考虑方向  
    switch(tank.direct){  
        case 0:     //向上  
        case 2:     //向下  
            //设置颜色  
            cxt.fillStyle=tank.color[0];  
            //左边的矩形  
            cxt.fillRect(tank.x,tank.y,5,30);  
            //右边的矩形  
            cxt.fillRect(tank.x+17,tank.y,5,30);  
            //画中间的矩形  
            cxt.fillRect(tank.x+6,tank.y+5,10,20);  
            //画出坦克的盖子  
            cxt.fillStyle=tank.color[1];  
            cxt.arc(tank.x+11,tank.y+15,5,0,Math.PI*2,true);  
            cxt.fill();  
            //画出炮筒  
            cxt.strokeStyle=tank.color[1];  
            cxt.lineWidth=1.5;  
            cxt.beginPath();  
            cxt.moveTo(tank.x+11,tank.y+15);  
            if(tank.direct==0){         //只是炮筒的方向不同  
                cxt.lineTo(tank.x+11,tank.y);  
            }else{  
                cxt.lineTo(tank.x+11,tank.y+30);  
            }  
            cxt.closePath();  
            cxt.stroke();  
            break;  
        case 1:  
        case 3:  
            //设置颜色  
            cxt.fillStyle="#BA9658";  
            //上边的矩形  
            cxt.fillRect(tank.x-4,tank.y+4,30,5);  
            //下边的矩形  
            cxt.fillRect(tank.x-4,tank.y+17+4,30,5);  
            //画中间的矩形  
            cxt.fillRect(tank.x+5-4,tank.y+6+4,20,10);  
            //画出坦克的盖子  
            cxt.fillStyle="#FEF26E";  
            cxt.arc(tank.x+15-4,tank.y+11+4,5,0,Math.PI*2,true);  
            cxt.fill();  
            //画出炮筒  
            cxt.strokeStyle="#FEF26E";  
            cxt.lineWidth=1.5;  
            cxt.beginPath();  
            cxt.moveTo(tank.x+15-4,tank.y+11+4);  
            if(tank.direct==1){         //只是炮筒的方向不同  
                cxt.lineTo(tank.x+30-4,tank.y+11+4);  
            }else{  
                cxt.lineTo(tank.x-4,tank.y+11+4);  
            }  
            cxt.closePath();  
            cxt.stroke();  
            break;    
    }  
      
}
登录后复制

坦克大战.html

<!DOCTYPE html>  
<html>  
<head>  
<meta charset="utf-8"/>  
</head>  
<body onkeydown="getCommand();">  
<h1>html5-坦克大战</h1>  
<!--坦克大战的战场-->  
<canvas id="tankMap" width="400px" height="300px" style="background-color:black"></canvas>  
<!--将tankGame04.js引入-->  
<script type="text/javascript" src="tankGame06.js"></script>  
<script type="text/javascript">  
    //得到画布  
    var canvas1=document.getElementById("tankMap");  
    //得到绘图上下文  
    var cxt=canvas1.getContext("2d");  
      
    //我的tank  
    //规定0向上、1向右、2向下、3向左  
    var hero=new Hero(40,40,0,heroColor);  
    //定义子弹数组  
    var heroBullets=new Array();  
    //敌人的tank  
    var enemyTanks=new Array();  
    for(var i=0;i<3;i++){  
        var enemyTank = new EnemyTank((i+1)*50,0,2,enemyColor);  
        enemyTanks[i]=enemyTank;      
    }  
      
    //画出自己的子弹  
    function drawHeroBullet(){  
        for(var i=0;i<heroBullets.length;i++){  
            var heroBullet=heroBullets[i];  
            if(heroBullet!=null&&heroBullet.isLive){  
                cxt.fillStyle="#FEF26E";  
                cxt.fillRect(heroBullet.x,heroBullet.y,2,2);  
            }  
        }  
    }  
      
    //定时刷新我们的作战区(定时重绘)  
    //自己的坦克,敌人坦克,子弹,炸弹,障碍物  
    function flashTankMap(){  
        //把画布清理  
        cxt.clearRect(0,0,400,300);  
        //我的坦克  
        drawTank(hero);  
        //我的子弹  
        drawHeroBullet();  
        //敌人的坦克  
        for(var i=0;i<3;i++){  
            drawTank(enemyTanks[i]);  
        }  
    }  
    flashTankMap();  
    //接收用户按键的函数  
    function getCommand(){  
        var code = event.keyCode;  //键盘上字幕的ASCII码  
        switch(code){  
            case 87:  //W   :上  
                hero.moveUp();  
                break;  
            case 68: //D    :右  
                hero.moveRight();  
                break;  
            case 83:  //S   :下  
                hero.moveDown();  
                break;  
            case 65: //A    :左  
                hero.moveLeft();  
                break;  
            case 74: //J  :发子弹  
                hero.shotEnemy();  
                break;  
        }  
        flashTankMap();  
    }  
    //每隔100毫秒去刷新一次作战区  
    window.setInterval("flashTankMap()",100);  
</script>  
</body>  
</html>
登录后复制

以上就是 小强的HTML5移动开发之路(9)——坦克大战游戏3的内容,更多相关内容请关注PHP中文网(www.php.cn)!



本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

HTML 中的表格边框 HTML 中的表格边框 Sep 04, 2024 pm 04:49 PM

HTML 表格边框指南。在这里,我们以 HTML 中的表格边框为例,讨论定义表格边框的多种方法。

HTML 左边距 HTML 左边距 Sep 04, 2024 pm 04:48 PM

HTML 左边距指南。在这里,我们讨论 HTML margin-left 的简要概述及其示例及其代码实现。

HTML 中的嵌套表 HTML 中的嵌套表 Sep 04, 2024 pm 04:49 PM

这是 HTML 中嵌套表的指南。这里我们讨论如何在表中创建表以及相应的示例。

HTML 表格布局 HTML 表格布局 Sep 04, 2024 pm 04:54 PM

HTML 表格布局指南。在这里,我们详细讨论 HTML 表格布局的值以及示例和输出。

HTML 输入占位符 HTML 输入占位符 Sep 04, 2024 pm 04:54 PM

HTML 输入占位符指南。在这里,我们讨论 HTML 输入占位符的示例以及代码和输出。

HTML 有序列表 HTML 有序列表 Sep 04, 2024 pm 04:43 PM

HTML 有序列表指南。在这里我们还分别讨论了 HTML 有序列表和类型的介绍以及它们的示例

在 HTML 中移动文本 在 HTML 中移动文本 Sep 04, 2024 pm 04:45 PM

HTML 中的文本移动指南。在这里我们讨论一下marquee标签如何使用语法和实现示例。

HTML onclick 按钮 HTML onclick 按钮 Sep 04, 2024 pm 04:49 PM

HTML onclick 按钮指南。这里我们分别讨论它们的介绍、工作原理、示例以及各个事件中的onclick事件。

See all articles