HTML5 经典小游戏之坦克(二)

上次写到坦克只能发出子弹

今天让坦克连续发射子弹 并击中敌人的坦克

那么问题来了?如何让子弹飞起来呢?

思路:

1.动起来 --- 必然会用到定时器

2.在那用?按空格发子弹后

3.子弹动起来的思路:按钮的时候,先每隔50毫秒改变子弹的参考点的坐标,再刷新画布,每隔100毫秒再刷新一下画布,显示新位置的子弹

4.当子弹碰到画布边界的时候,让子弹停止

 

tankGame.html

<!DOCTYPE html>
< html>
< head>
< meta charset='utf-8'/>
< script src='tankGame.js'></script>
< /head>
< body onkeydown="changeDirect()">
< canvas id='tankMap' width='500px' height='300px' style='background-color:black'>
你的浏览器不支持canvas标签</canvas>
< span id='aa'></span>
< /body>
< script>
    //开始画出我们的tanke
    var canvas = document.getElementById('tankMap');
    //相当于获得画笔
    var ctx = canvas.getContext('2d');
    var hero = new Hero(140,90,0,heroColor);
    var enemyTanks = new Array();
    for(var i=0;i<3;i++){
        var enemyTank = new EnemyTank((i+1)*50,0,2,enemyColor);
        enemyTanks[i] = enemyTank;
        //drawTank(enemyTanks[i]);
    }
    var bombs = new Array();
    //实例化子弹对象
    var heroBullets = new Array();
    var heroBullet = null;
    
    drawTank(hero);
    flashMap();
    function flashMap(){
        ctx.clearRect(0,0,500,300);
        drawTank(hero);
        isHitEnemyTank(heroBullets,enemyTanks);
        drawHeroBullet(heroBullets);
        for(var i=0;i<3;i++){
            if(enemyTanks[i].isLive==true){
                drawTank(enemyTanks[i]);
            }
        }
        //画出炸弹
        for(var k=0;k<bombs.length;k++){
            //如何画一张图片
            var img = new Image();
            img.src = 'bomb_1.gif';
            var x = bombs[k].x;
            var y = bombs[k].y;
            ctx.drawImage(img,x,y,30,30);
            bombs.splice(k,1);
        }
    }

    function changeDirect(){
        var keycode = event.keyCode;
        switch(keycode){
            case 38:
            hero.moveUp();
            break;
            case 39:
            hero.moveRight();
            break;
            case 40:
            hero.moveBottom();
            break;
            case 37:
            hero.moveLeft();
            break;
            case 32:
            hero.shotEnemy();
            break;
        }
            flashMap();
    }
    window.setInterval("flashMap()",100);
< /script>
< /html>

 

tankGame.js

    //定义敌人和我们自己的坦克的颜色
    var enemyColor = new Array('#00FEFE','#00A2B5');
    var heroColor = new Array('#FEF26E','#BA9658');
    //封装一个公用的坦克类
    function Tank(x,y,direct){
        this.x = x;
        this.y = y;
        this.speed = 3;
        this.direct = direct;
        this.moveUp = function(){
            this.y -= hero.speed;
            this.direct = 0;
        }
        this.moveRight = function(){
            this.x += hero.speed;
            this.direct = 1;
        }
        this.moveBottom = function(){
            this.y += hero.speed;
            this.direct = 2;
        }
        this.moveLeft = function(){
            this.x -= hero.speed;
            this.direct = 3;
        }
    }
    
    //英雄坦克类
    function Hero(x,y,direct,color){
        //将坦克类的构造方法赋给hero
        this.hero = Tank;
        //调用,拥有坦克类的所有的属性和方法
        this.hero(x,y,direct);
        this.color = color;
        this.direct = direct;
        this.shotEnemy = function(){
            switch(this.direct){
                case 0:
                    heroBullet = new Bullet(this.x+10,this.y,this.direct);
                break;
                case 1:
                    heroBullet = new Bullet(this.x+30,this.y+10,this.direct);
                break;
                case 2:
                    heroBullet = new Bullet(this.x+10,this.y+30,this.direct);
                break;
                case 3:
                    heroBullet = new Bullet(this.x,this.y+10,this.direct);
                break;
            }
                heroBullets.push(heroBullet);
                //定义定时器
                var timer = window.setInterval("heroBullets["+(heroBullets.length-1)+"].run()",50);
                heroBullets[(heroBullets.length-1)].timer = timer;
        }

    }

    //敌人的坦克
    function EnemyTank(x,y,direct,color){
        //将坦克类的构造方法赋给hero
        this.enemyTank = Tank;
        //调用,拥有坦克类的所有的属性和方法
        this.enemyTank(x,y,direct);
        this.color = color;
        this.isLive = true;
    }
    //绘制坦克
        function drawTank(hero){
        switch(hero.direct){
            case 0:
            case 2:
            //alert(ctx);
                ctx.fillStyle = hero.color[0];
                ctx.fillRect(hero.x,hero.y,5,30);
                ctx.fillRect(hero.x+15,hero.y,5,30);
                ctx.fillRect(hero.x+6,hero.y+5,8,20);
                //需要注意,画圆的时候需要重新开启路径
                ctx.fillStyle = hero.color[1];
                ctx.beginPath();
                ctx.arc(hero.x+10,hero.y+15,3,0,Math.PI*2,true);
                ctx.closePath();
                ctx.fill();
                //画出炮筒(直线)
                ctx.strokeStyle = hero.color[1];
                ctx.lineWidth = 2;
                ctx.moveTo(hero.x+10,hero.y+15);
                if(hero.direct==0){
                    ctx.lineTo(hero.x+10,hero.y);
                }else if(hero.direct==2){
                    ctx.lineTo(hero.x+10,hero.y+30);
                }
                ctx.stroke();
            break;
            case 1:
            case 3:
                ctx.fillStyle = hero.color[0];
                ctx.fillRect(hero.x,hero.y,30,5);
                ctx.fillRect(hero.x,hero.y+15,30,5);
                ctx.fillRect(hero.x+5,hero.y+6,20,8);
                //需要注意,画圆的时候需要重新开启路径
                ctx.fillStyle = hero.color[1];
                ctx.beginPath();
                ctx.arc(hero.x+15,hero.y+10,3,0,Math.PI*2,true);
                ctx.closePath();
                ctx.fill();
                //画出炮筒(直线)
                ctx.strokeStyle = hero.color[1];
                ctx.lineWidth = 2;
                ctx.moveTo(hero.x+15,hero.y+10);
                if(hero.direct ==1){
                    ctx.lineTo(hero.x+30,hero.y+10);
                }else if(hero.direct ==3){
                    ctx.lineTo(hero.x,hero.y+10);
                }
                ctx.stroke();
            break;
        }
    }

    //定义一个子弹类
    function Bullet(x,y,direct){
        this.x = x;
        this.y = y;
        this.speed = 3;
        this.timer = null;
        this.isLive = true;
        this.direct = direct;
        //这个函数是用来修改子弹的坐标
        this.run = function(){
            //alert('ok');
            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;
            }
            //在这里判断一下,如果子弹超过边界,我就清除定时器
            if(this.x <= 0 || this.x >=500 || this.y <=0 || this.y>= 300){
                window.clearInterval(this.timer);
            }
            document.getElementById('aa').innerText = "子弹的x:"+this.x+"y:"+this.y;
        }
    }

    function drawHeroBullet(bullets){
        for(var i=0;i<bullets.length;i++){
            var heroBullet = bullets[i];
            if(heroBullet.isLive&&heroBullet!=null){
                ctx.fillStyle = '#FEF26E';
                ctx.fillRect(heroBullet.x,heroBullet.y,2,2);
            }
        }
    }

    //判断子弹是否击中敌人的坦克
    function isHitEnemyTank(heroBullets,enemyTanks){
        //循环出我们所有的子弹
        for(var i=0;i<heroBullets.length;i++){
            //再循环出敌人所有的坦克
            for(var j=0;j<enemyTanks.length;j++){
                if(enemyTanks[j].isLive){
                    switch(enemyTanks[j].direct){
                    case 0:
                    case 2:
                        if(heroBullets[i].x>=enemyTanks[j].x && heroBullets[i].x<= enemyTanks[j].x+20 && heroBullets[i].x>=enemyTanks[j].y&&heroBullets[i].y<=enemyTanks[j].y+30){
                        //标记一下敌人的坦克牺牲了
                        enemyTanks[j].isLive = false;
                        heroBullets[i].isLive = false;
                        //实例化炸弹
                        var bomb = new Bomb(enemyTanks[j].x,enemyTanks[j].y);
                            bombs.push(bomb);

                    }
                    break;
                    case 1:
                    case 3:
                        if(heroBullets[i].x>=enemyTanks[j].x&&heroBullets[i].x<=enemyTanks[j].x+30&&heroBullets[i].y>=enemyTanks[j].y&&heroBullets[i].y<=enemyTanks[j].y+20){
                            //标记敌人的坦克已死
                            //实例化炸弹
                            enemyTanks[j].isLive = false;
                            heroBullets[i].isLive = false;
                            heroBullets.splice(i,1);
                            //实例化炸弹
                            var bomb = new Bomb(enemyTanks[j].x,enemyTanks[j].y);
                            bombs.push(bomb);
                    }
                    break;
                }
            }
            }
        }
    }

    //炸弹类
    function Bomb(x,y,direct){
        this.x = x;
        this.y = y;
        this.direct = direct;
    }

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

图片加载片段:

 

<canvas id="myCanvas" width='700px' height='400px' style="border:1px solid #9C0"></canvas>
< script>
< !--加载图片-->
//得到画布
var canvas=document.getElementById('myCanvas');
//得到画笔,获得二维画布
var ctx=canvas.getContext('2d');

var img=new Image();//实例化对象
img.src='a.jpg';//加载图片路径
ctx.drawImage(img,0,0,300,400);//图片放置到画布上,参数1:实例化对象名,2,3:起点坐标,3,4:图片大小
</script>

 

For more complete information about compiler optimizations, see our Optimization Notice.