1. 程式人生 > >HTML5 經典小遊戲之坦克(二)

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>