天天看點

Htm5 坦克大戰

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

    <title>經典的坦克大戰</title>

</head>

<body onkeydown="getCommand();" style="text-align:center" >

    <h1>Html5經典的坦克大戰</h1>

    <!-- 坦克大戰的戰場 -->

    <canvas id="tankMap" width="600px" height="500px" style="background-color:Black"></canvas>

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

    <script type="text/javascript">

        //得到畫布

        var canvas = document.getElementById("tankMap");

        //得到畫筆

        var cxt = canvas.getContext("2d");

        //我的坦克(坦克的基準點)

        //方向 0表示向上,1表示向右,2表示像下,3表示向左

        var myTank = new MyTank(300, 400, 0,myTankColor);

        //定義子彈數組

        var myBullets = new Array();

        //定義敵人的坦克

        var enemyTanks = new Array();

        //定義敵人子彈的數組

        var enemyBullets = new Array();

        //定義一個炸彈數組(可以存放很多炸彈)

        var bombs = new Array();

        //先定義三個,後面把敵人坦克的數量,作出變量

        //0->上,1->右,2->下,3->左

        for (var i = 0; i < 3; i++) {

            //建立一個坦克

            var enemyTank = new EnemyTank((i + 1) * 50, 3, 2, enemyColor);

            //把這個坦克放入數組

            enemyTanks[i] = enemyTank;

            //啟動這個敵人的坦克

            window.setInterval("enemyTanks[" + i + "].run()", 50);

            //當建立敵人坦克時就會配置設定子彈,子彈速度為3

            var eb = new Bullet(enemyTanks[i].x + 9, enemyTanks[i].y + 30, 2, 3, "enemy", enemyTanks[i]);

            enemyBullets[i] = eb;

            //啟動該子彈

            var ettimer = window.setInterval("enemyBullets[" + i + "].run()", 50);

            enemyBullets[i].timer = ettimer;

        }

        //先調用一次

        flashTankMap();

        //專門寫一個函數,用于定時重新整理我們的作戰區,把要在作戰區出現的元素(子彈,坦克,障礙物等繪制出來)

        function flashTankMap() {

            //把畫布清理

            cxt.clearRect(0, 0, 600, 500);

            //我的坦克

            drawTank(MyTank);

            //畫出自己的子彈

            //子彈飛的效果原理是,每隔一段時間setInterval就去重新整理工作區

            drawMyBullet();

            //敵人的坦克

            //判斷一下敵人的坦克是否被擊中

            isHitEnemyTank();

            drawEnemyBomb();

            drawEnemyBullet();

            //畫出所有敵人的坦克

            for(var i=0;i<3;i++) {

                drawTank(enemyTanks[i]);

            }

        //繪制坦克

        drawTank(myTank);

        //判斷鍵盤按鍵

        function getCommand() {

            //說明當時按下的是什麼鍵,-->event對象-->事件處理函數

            var code = event.keyCode; //對應字母的ascii碼

            switch (code) {

                case 87: //W

                    myTank.MoveUp();

                    break;

                case 68: //D

                    myTank.MoveRight();

                case 65: //A

                    myTank.MoveLeft();

                case 83: //S

                    myTank.MoveDown();

                case 74:

                    myTank.shotEnemy();

            //觸發這個函數flashTankMap();

            flashTankMap();

            //清理畫布

//            cxt.clearRect(0, 0, 600, 500); //重繪畫布

//            //清理過後重新繪制

//            drawTank(myTank);

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

    </script>

</body>

</html>

js:

//定義兩個顔色數組

var myTankColor = new Array("#F0C970", "#FCD152");

var enmeyColor = new Array("#00A2B5", "#00FEFE");

//定義一個炸彈類

function Bomb(x, y) {

    this.x = x;

    this.y = y;

    this.isLive = true; //炸彈是否是活的,預設為true;

    this.blood = 9; //炸彈生命值

    this.bloodDown = function () {

        if (this.bood > 0) {

            this.blood--;

        else {

            this.isLive = false; //說明炸彈死亡

    }

}

//子彈類

//type表示區分是别人的子彈,還是自己的子彈

//tank表示對象,說明這可子彈是屬于哪個坦克

function Bullet(x, y, direct, speed, type, tank) {

    this.direct = direct;

    this.speed = speed;

    this.timer = null;

    this.isLive = null;

    this.type = type;

    this.tank = tank;

    this.run = function () {

        //先判斷字段是否已經碰到邊界

        //子彈不前進,有兩個邏輯,1.碰到邊界,2.碰到敵人的坦克

        if (this.x <= 0 || this.x >= 600 || this.y <= 0 || this.y >= 500 || this.isLive == false) {

            //子彈要停止

            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.x += this.speed;

                    case 2:

                        this.y += this.speed;

                    case 3:

                        this.x -= this.speed;

                }

            document.getElementById("aa").innerText = "子彈x=" + this.x + "子彈y=" + this.y;

//坦克類

function Tank(x, y, direct,color) {

    this.isLive = true;

    this.color = color;//一個坦克需要兩種顔色

    this.speed = 3; //預設速度為1

    //上移

    this.MoveUp = function () {

        this.y -= this.speed;

        this.direct = 0;

    //下移

    this.MoveDown = function () {

        this.y += this.speed;

        this.direct = 2;

    //左移

    this.MoveLeft = function () {

        this.x -= this.speed;

        this.direct = 3;

    //右移

    this.MoveRight = function () {

        this.x += this.speed;

        this.direct = 1;

//定義我的坦克

function MyTank(x, y, direct, color) {

    //下面兩句話是通過對象冒充,達到繼承的效果

    this.tank = Tank;

    this.tank(x, y, direct, color);

    //增加一個函數,射擊敵人的坦克

    this.shotEnemy = function () {

        //建立子彈,子彈的位置和自己坦克的位置有關系,并且和方向有關

        //this.x就是目前坦克的橫坐标

        switch (this.direct) {

            case 0: //上

                myBullet = new Bullet(this.x + 15, this.y + 2, this.direct, 1, "hero", this);

                break;

            case 1: //右

                myBullet = new Bullet(this.x + 28, this.y + 15, this.direct, 1, "hero", this);

            case 2: //下

                myBullet = new Bullet(this.x + 15, this.y + 28, this.direct, 1, "hero", this);

            case 3: //左

                myBullet = new Bullet(this.x + 2, this.y + 15, this.direct, 1, "hero", this);

        //把這個子彈對象放入到數組中->push函數

        myBullets.push(myBullet);

        //調用我們的子彈run

        //每個子彈的定時器是獨立,如果按原來的方法

        //則所有的子彈共享一個定時器

        var timer = window.setInterval("myBullets[" + (myBullets.length - 1) + "].run()", 50);

        //把這個timer賦給每一個子彈(js對象是引用傳遞)

        myBullets[myBullets.length - 1].timer = timer;

//定義一個EnemyTank類

function EnemyTank(x,y,direct,color) {

    //也通過對象來冒充,來繼承Tank

    this.count = 0;

    this.bulletIsLive = true;

        //判斷敵人的坦克的前進方向

            case 0:

                if (this.y > 0) {

                    this.y -= this.speed;

            case 1:

                if (this.x + 30 < 500) {

                    this.x += this.speed;

            case 2:

                if (this.y + 30 < 600) {

                    this.y += this.speed;

            case 3:

                if (this.x > 0) {

                    this.x -= this.speed;

        //改變方向,走三十次,在改變方向

        if (this.count > 30) {

            //math.round傳回的是最接近的整數,math.random産生0.1-1.0之間的數

            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 + 15, this.y + 2, this.direct, 1, "hero", this);

                case 1: //右

                    etBullet = new Bullet(this.x + 28, this.y + 15, this.direct, 1, "hero", this);

                case 2: //下

                    etBullet = new Bullet(this.x + 15, this.y + 28, this.direct, 1, "hero", this);

                case 3: //左

                    etBullet = new Bullet(this.x + 2, this.y + 15, this.direct, 1, "hero", this);

            //把子彈添加到敵人子彈數組中

            enemyBullets.push(etBullet);

            //啟動新子彈run

            var mytimer=window.setInterval("enemyBullets["+(enemyBullets.lendth-1)+"].run()",50);

            enemyBullets[enemyBullets.length-1].timer=mytimer;

            this.bulletIsLive=true;

//畫自己的子彈,要把這個函數封裝到myTank類中

function drawMyBullet() {

    //現在要畫出所有的子彈

    for(var i=0;i<myBullets.length;i++)

    {

        var myBullet=myBullets[i];

        if(myBullet!=null&&myBullet.isLive)

        {

            cx.fillStyle="#FEF26E";

            cxt.fillRect(myBullet.x,myBullet.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);

//繪制坦克(敵人和自己的坦克)

//把繪制坦克封裝成一個函數,将來可以作為成員函數

function drawTank(tank) {

    //說明所有的坦克都要isLive這個屬性

    if(tank.isLive)

        //考慮方向

        switch (tank.direct) {

                //使用自己的坦克,使用繪圖技術

                //設定顔色

                cxt.fillStyle = tank.color[0];

                //坦克

                cxt.fillRect(tank.x, tank.y, 5, 30); //左輪

                cxt.fillRect(tank.x + 5, tank.y + 7, 16, 16); //坦克身

                cxt.fillRect(tank.x + 5 + 16, tank.y, 5, 30); //右輪

                //畫一個蓋子(内圓)

                cxt.beginPath();

                cxt.fillStyle = tank.color[1];

                cxt.arc(tank.x + 5 + 8, tank.y + 7 + 8, 8, 0, 360, true); //(x,y,r,開始角度,結束角度,是否順時針)

                cxt.closePath();

                //填充實心的圓形

                cxt.fill();

                //設定線條的寬度

                cxt.lineWidth = 4;

                cxt.moveTo(tank.x + 13, tank.y + 15);

                //炮筒

                //cxt.fillRect(tank.x + 5 + 6, tank.y + 2, 4, 5);

                cxt.strokeStyle = tank.color[1];

                if (tank.direct == 0) {

                    cxt.lineTo(tank.x + 13, tank.y + 2);

                } else if (tank.direct == 2) {

                    cxt.lineTo(tank.x + 13, tank.y + 28);

                cxt.stroke();

            //左和右  

                //畫出自己的坦克,使用前面的繪圖技術

                //韓老師使用 先死--->後活 (初學者最好用這個方法)

                //先畫出右面的矩形

                cxt.fillRect(tank.x, tank.y, 30, 5);

                //畫出左邊的矩形

                cxt.fillRect(tank.x, tank.y + 21, 30, 5);

                //畫出中間矩形

                cxt.fillRect(tank.x + 7, tank.y + 5, 16, 16);

                //畫出坦克的蓋子

                cxt.arc(tank.x + 15, tank.y + 13, 8, 0, 360, true);

                //畫出炮筒(直線)

                cxt.moveTo(tank.x + 15, tank.y + 13);

                //向右

                if (tank.direct == 1) {

                    cxt.lineTo(tank.x + 28, tank.y + 13);

                } else if (tank.direct == 3) { //向左

                    cxt.lineTo(tank.x + 2, tank.y + 13);

//編寫一個函數,專門用于判斷我的子彈,是否集中某個敵人的坦克

function isHitEnemyTank() {

    //取出每一顆子彈

        //取出每一顆子彈

        if(heroBullet.isLive) //子彈是活的,才去判斷

            //讓這顆子彈去和周遊每個敵人坦克判斷

            for(var j=0;j<enemyTanks.length;j++)

            {

                var enemyTank=enemyTanks[j];

                //子彈集中敵人坦克的條件是什麼?

                //看這顆子彈是否進入敵人坦克所在的矩形

                //根據當時敵人坦克的方向來決定

                if(enemyTank.isLive)

                {

                    switch(enemytank.direct)

                    {

                        case 0:

                        case 2:

                            if(myBullet.x>=enemyTank.x&&myBullet.x<=enemyTank.x+26&&myBullet.y>=enemyTank.y&&myBullet.y<=enemyTank.y+30)

                            {

                                //把坦克isLive設定為false,表示死亡

                                enemyTank.isLive=false;

                                //該子彈也死亡

                                myBullet.isLive=false;

                                //建立一顆炸彈

                                var bomb=new Bomb(enemyTank.x,enemyTank.y);

                                //然後把該炸彈放入到booms數組中

                                bombs.push(bomb);

                            }

                            break;

                        case 1:

                        case 3://左右方向

                             if(myBullet.x>=enemyTank.x&&myBullet.x<=enemyTank.x+30&&myBullet.y>=enemyTank.y&&myBullet.y<=enemyTank.y+26)

                    }

//畫出敵人的炸彈

function drawEnemyBomb() {

    for(var i=0;i<bombs.length;i++)

        //取出一顆炸彈

        var bomb=bombs[i];

        if(bomb.isLive)

            //根據目前這個炸彈的生命值,來畫出不同的炸彈圖檔

            if(bomb.blood>6)

                //顯示最大炸彈圖

                var img1=new Image();

                img1.src="imgs/bomb_1.gif";

                var x=bombs.x;

                var y=bombs.y;

                img1. () {

                    cxt.drawImage(img1,x,y,30,30);

            else if(bomb.blood>3)

                //顯示中等炸彈圖

                var img3=new Image();

                img3.src="imgs/bomb_2.gif";

                img2. () {

            else

                //顯示最小炸彈圖

                img3.src="imgs/bomb_3.gif";

                img3. () {

            //減血

            bomb.bloodDown();

            if(bomb.blood<=0)

                //把這個炸彈從數組中去掉

                bombs.splice(i,1);

本文轉自蓬萊仙羽51CTO部落格,原文連結:http://blog.51cto.com/dingxiaowei/1366603,如需轉載請自行聯系原作者

繼續閱讀