HTML5之坦克大战游戏

主要关注问题:

         学好html5canvas标签画出各种图型  包括图片 文字  图形    

 画坦克  敌人坦克   子弹

         画布  坦克战场  定时刷新

        子弹何时死亡  如何实现子弹飞效果

         如何移动坦克 包括方向

         如何让坦克发射子弹  如何让子弹自己沿着坦克发射的方向飞  打中敌人或者飞到边界让其死亡

         敌机如何自动发射子弹 如何随机移动

        定时器定时画子弹  什么时候才不画(死亡) 如何取消该定时器

        在js里面如何实现继承     :对象冒充

  

     原文参照韩顺平html5自写    看完视频后参照思想自己写代码 后续待完善

   


-------------------html--------------------------

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body onkeydown="ManaPlay();">

<script type="text/javascript" src="tankGame.js"></script>

<canvas id="gameMap" width="400px" height="300px" style="background-color: black" >


</canvas>
<span id="aa">数据</span>


<script>
    var canvas = document.getElementById("gameMap");

    //得到画布
    var cxt = canvas.getContext("2d");

    //英雄坦克颜色   敌人坦克颜色
    var heroColor=new Array("#BA9658","#FEF26E");
    var enmeyColor=new Array("#00A2B5","#00FEFE");

    var hero = new Hero(30,230,0,heroColor);
  //  var heroBullet = null;  //定义一颗空子弹

    var heroBullets = new Array();//定义子弹数组

    var enemyBullets = new Array();//定义敌人的子弹

    //敌人坦克 ,
    var enemys = new Array();
    for(var i=0;i<3;i++){
        var Enemy = new EnemyTank((i+1)*50,0,1,enmeyColor);
        enemys[i]=Enemy;
        //启动这个敌人的坦克
        window.setInterval("enemys["+i+"].run()",50);

        //当创建敌人坦克时就分配子弹
        var eb=new Bullet(enemys[i].x+9,enemys[i].y+30,1,2.2,"enemy",enemys[i]);

        enemyBullets[i]=eb;
        //启动该子弹
        var ettimer=window.setInterval("enemyBullets["+i+"].run()",50);
        enemyBullets[i].timer=ettimer;
    }

    //初始化坦克
    flashTankMap();
    /**
     * 接收用户按键函数
     * @constructor
     */
   function  ManaPlay(){

        //拿到玩家当前按下的键  查对应字母的ascii码
       var code=event.keyCode;

       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();


   }

    /**
     * 坦克地图的刷新操作
     */
    function  flashTankMap(){
        //画布清理
        cxt.clearRect(0,0,400,300,heroColor);

        //画自己的坦克
        drawTank(hero);

        //画敌人的坦克
        for(var i=0;i<enemys.length;i++){
            var Enemy =enemys[i];
            drawTank(Enemy);
        }

        drawHeroBullet();
        drawEnemyBullet();

    }

    window.setInterval("flashTankMap()",100);

</script>
</body>
</html>


--------------js部分——------------------------------
/**
 * 坦克类 专门生产坦克   包括英雄的坦克和敌人的坦克
 * @param x
 * @param y
 * @param direct
 * @param color
 * @constructor
 */
function Tank(x,y,direct,color){

    this.x=x;
    this.y=y;
    this.color=color;
    this.direct=direct;
    this.speed=1; //速度
    //上 0
    this.MoveUp = function(){
        this.y-=this.speed;
        this.direct=0;
    }
    //下 1
    this.MoveDown =function(){
        this.y+=this.speed;
        this.direct=1;
    }
    //左 2
    this.MoveLeft = function(){
        this.x-=this.speed;
        this.direct=2;
    }
    // 右 3
    this.MoveRight = function(){
        this.x+=this.speed;
        this.direct=3;
    }

}


/**
 * 定义一个hero类  表示自己的坦克
 *  定义坦克的属性和其上下移动的方法
 * @param x 横坐标
 * @param y 纵坐标
 * @param direct 坦克的方向
 * @constructor  Liu
 */
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+9,this.y,this.direct,1,"hero",this);
                break;
            case 2:
                heroBullet=new Bullet(this.x,this.y+9,this.direct,1,"hero",this);
                break;
            case 3:
                heroBullet=new Bullet(this.x+30,this.y+9,this.direct,1,"hero",this);
                break;
            case 1:
                heroBullet=new Bullet(this.x+9,this.y+30,this.direct,1,"hero",this);
                break;

        }
        heroBullets.push(heroBullet);

        //调用我们的子弹run,让它自己跑
        var timer=window.setInterval("heroBullets["+(heroBullets.length-1)+"].run()",50);
        //把这个timer赋给这个子弹  如果不要子弹了 就停止跑    (js对象是引用传递!)
        heroBullets[heroBullets.length-1].timer=timer;

    }

}
/**
 * 敌人坦克类
 * @param x
 * @param y
 * @param direct
 * @param color
 * @constructor
 */
function EnemyTank (x,y,direct,color){
    this.tank=Tank;
    this.tank(x,y,direct,color);
    this.bulletIsLive =true; //定义坦克子弹的状态   是否死亡
    this.count = 0;// 坦克走了多少步
    this.run = function run() {
        //判断敌人的坦克当前方向
        switch (this.direct) {

            case 0:
                if (this.y > 0) {
                    this.y -= this.speed;
                }
                break;
            case 3:
                if (this.x + 30 < 400) {
                    this.x += this.speed;
                }
                break;
            case 1:
                if (this.y + 30 < 300) {
                    this.y += this.speed;
                }
                break;
            case 2:
                if (this.x > 0) {
                    this.x -= this.speed;
                }
                break;
        }
        //改变方向,走30次,再改变方向
        if (this.count > 30) {
            this.direct = Math.round(Math.random() * 3);//随机生成 0,1,2,3
            this.count = 0;
        }
        this.count++;

        //判断子弹是否已经死亡,如果死亡,则增加新的一颗子弹
        if(this.bulletIsLive==false) {
            //增子弹,这是需要考虑当前这个敌人坦克的方向,在增加子弹
            switch (this.direct) {

                case 0:
                    etBullet=new Bullet(this.x+9,this.y,this.direct,2,"enemy",this);
                    break;
                case 2:
                    etBullet=new Bullet(this.x,this.y+9,this.direct,2,"enemy",this);
                    break;
                case 3:
                    etBullet=new Bullet(this.x+30,this.y+9,this.direct,2,"enemy",this);
                    break;
                case 1:
                    etBullet=new Bullet(this.x+9,this.y+30,this.direct,2,"enemy",this);
                    break;

            }

            //把子弹添加到敌人子弹数组中
            enemyBullets.push(etBullet);
            //启动新子弹run
            var mytimer = window.setInterval("enemyBullets[" + (enemyBullets.length - 1) + "].run()", 50);
            enemyBullets[enemyBullets.length - 1].timer = mytimer;

            this.bulletIsLive = true;


        }
    }

}




/**
 *  画坦克类
 * @param tank
 */
function drawTank(tank){

    //根据方向画坦克
    switch (tank.direct){
        case 0:
        case 1:
            cxt.fillStyle=tank.color[0];
            //矩形
            cxt.fillRect(tank.x,tank.y,5,30);
            cxt.fillRect(tank.x+15,tank.y,5,30);
            cxt.fillRect(tank.x+6,tank.y+5,8,20);
            //设置画笔的样式 画坦克的圆盖
            cxt.fillStyle=tank.color[1];
            cxt.beginPath();
            cxt.arc(tank.x+10,tank.y+15,4,0,360,true);
            cxt.fill();
            cxt.closePath();
            //设置线条的颜色   画炮筒
            cxt.strokeStyle=tank.color[1];
            cxt.beginPath();
            if(tank.direct==0){
                cxt.moveTo(tank.x+10,tank.y+15);
                cxt.lineTo(tank.x+10,tank.y);
            }else if(tank.direct==1){
                cxt.moveTo(tank.x+10,tank.y+15);
                cxt.lineTo(tank.x+10,tank.y+30);
            }
            cxt.closePath();
            cxt.stroke();
            break;
        case 2:
        case 3:
            cxt.fillStyle=tank.color[0];
            //矩形
            cxt.fillRect(tank.x,tank.y,30,5);
            cxt.fillRect(tank.x,tank.y+15,30,5);
            cxt.fillRect(tank.x+5,tank.y+6,20,8);
            //设置画笔的样式 画坦克的圆盖
            cxt.fillStyle=tank.color[1];
            cxt.beginPath();
            cxt.arc(tank.x+15,tank.y+10,4,0,360,true);
            cxt.fill();
            cxt.closePath();
            cxt.strokeStyle=tank.color[1];
            cxt.beginPath();
            if(tank.direct==3){
                cxt.moveTo(tank.x+15,tank.y+10);
                cxt.lineTo(tank.x+30,tank.y+10);
            }else if(tank.direct==2){
                cxt.moveTo(tank.x+15,tank.y+10);
                cxt.lineTo(tank.x,tank.y+10);
            }
            cxt.closePath();
            cxt.stroke();
            break;

    }


}
/**
 * 子弹类  坐标  方向 类型 坦克
 * @param x
 * @param y
 * @param direct
 * @param speed
 * @param type
 * @param tank
 * @constructor
 */
function Bullet(x,y,direct,speed,type,tank){
    this.x=x;
    this.y=y;
    this.direct=direct;
    this.speed=speed;
    this.isLive = true;
    this.timer=null;//这个用来判断 子弹越界或者死亡就终止前进
    this.type = type;
    this.tank = tank;

    this.run = function run(){

        //在该表这个子弹的坐标时,我们先判断子弹是否已经到边界
        if(this.x<=0||this.x>=400||this.y<=0||this.y>=300){
            //子弹要停止.
            window.clearInterval(this.timer);
            //子弹死亡
            this.isLive=false;
            if(this.type=="enemy"){
                this.tank.bulletIsLive=false;
            }
        }else{
                switch (this.direct){

                    case 0:
                        this.y-=this.speed;
                        break;
                    case 1:
                        this.y+=this.speed;
                        break;
                    case 2:
                        this.x-=this.speed;
                        break;
                    case 3:
                        this.x+=this.speed;
                        break;
                }
        }
        document.getElementById("aa").innerText="子弹x="+this.x+" 子弹y="+this.y;
    }
}
/**
 * 画玩家自己坦克的子弹  如果有的话
 */
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 drawEnemyBullet(){

    //现在要画出所有子弹
    for( var i=0;i<enemyBullets.length;i++){
        var etBullet=enemyBullets[i];
        //这里,我们加入了一句话,但是要知道这里加,是需要对整个程序有把握
        if(etBullet.isLive){
            cxt.fillStyle="#00FEFE";
            cxt.fillRect(etBullet.x,etBullet.y,2,2);
        }
    }
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值