HTML5+CSS3从入门到精通之移动开发之路(9)坦克大战游戏3
沉沙 2018-11-23 来源 : 阅读 1017 评论 0

摘要:本篇教程探讨了HTML5+CSS3从入门到精通之移动开发之路(9)坦克大战游戏3,希望阅读本篇文章以后大家有所收获,帮助大家HTML5+CSS3从入门到精通 。

本篇教程探讨了HTML5+CSS3从入门到精通之移动开发之路(9)坦克大战游戏3,希望阅读本篇文章以后大家有所收获,帮助大家HTML5+CSS3从入门到精通 。

<

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

前面我们用面向对象的思想对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属性。

看看运行结果吧

全部源代码如下:

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>      

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标WEB前端HTML5/CSS3频道!

本文由 @沉沙 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程