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();
                    break;
                case 65: //A
                    myTank.MoveLeft();
                    break;
                case 83: //S
                    myTank.MoveDown();
                    break;
                case 74:
                    myTank.shotEnemy();
                    break;
            }
            //触发这个函数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.x = x;
    this.y = y;
    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;
                        break;
                    case 2:
                        this.y += this.speed;
                        break;
                    case 3:
                        this.x -= this.speed;
                        break;
                }
            }
            document.getElementById("aa").innerText = "子弹x=" + this.x + "子弹y=" + this.y;
        }
    }
}
//坦克类
function Tank(x, y, direct,color) {
    this.x = x;
    this.y = y;
    this.direct = direct;
    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);
                break;
            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.tank = Tank;
    this.count = 0;
    this.bulletIsLive = true;


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


    this.run = function () {
        //判断敌人的坦克的前进方向
        switch (this.direct) {
            case 0:
                if (this.y > 0) {
                    this.y -= this.speed;
                }
                break;
            case 1:
                if (this.x + 30 < 500) {
                    this.x += this.speed;
                }
                break;
            case 2:
                if (this.y + 30 < 600) {
                    this.y += this.speed;
                }
                break;
            case 3:
                if (this.x > 0) {
                    this.x -= this.speed;
                }
                break;
        }
        //改变方向,走三十次,在改变方向
        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);
                    break;
                case 1: //右
                    etBullet = new Bullet(this.x + 28, this.y + 15, this.direct, 1, "hero", this);
                    break;
                case 2: //下
                    etBullet = new Bullet(this.x + 15, this.y + 28, this.direct, 1, "hero", this);
                    break;
                case 3: //左
                    etBullet = new Bullet(this.x + 2, this.y + 15, this.direct, 1, "hero", this);
                    break;
                }
            //把子弹添加到敌人子弹数组中
            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) {
            case 0: //上
            case 2: //下
                //使用自己的坦克,使用绘图技术
                //设置颜色
                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.beginPath();
                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.closePath();
                cxt.stroke();
                break;
            //左和右  
            case 1:
            case 3:
                //画出自己的坦克,使用前面的绘图技术
                //设置颜色
                cxt.fillStyle = tank.color[0];
                //韩老师使用 先死--->后活 (初学者最好用这个方法)
                //先画出右面的矩形
                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.fillStyle = tank.color[1];
                cxt.arc(tank.x + 15, tank.y + 13, 8, 0, 360, true);
                cxt.fill();
                //画出炮筒(直线)
                cxt.strokeStyle = tank.color[1];
                //设置线条的宽度
                cxt.lineWidth = 4;
                cxt.beginPath();
                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);
                }


                cxt.closePath();
                cxt.stroke();
                break;
        }
    }
}
//编写一个函数,专门用于判断我的子弹,是否集中某个敌人的坦克
function isHitEnemyTank() {
    //取出每一颗子弹
    for(var i=0;i<myBullets.length;i++)
    {
        //取出每一颗子弹
        var myBullet=myBullets[i];
        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)
                            {
                                //把坦克isLive设置为false,表示死亡
                                enemyTank.isLive=false;
                                //该子弹也死亡
                                myBullet.isLive=false;
                                //创建一颗炸弹
                                var bomb=new Bomb(enemyTank.x,enemyTank.y);
                                //然后把该炸弹放入到booms数组中
                                bombs.push(bomb);
                            }
                            break;
                    }
                }
            }
        }
    }
}


//画出敌人的炸弹
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";
                var x=bombs.x;
                var y=bombs.y;
                img2. () {
                    cxt.drawImage(img1,x,y,30,30);
                }
            }
            else
            {
                //显示最小炸弹图
                var img3=new Image();
                img3.src="imgs/bomb_3.gif";
                var x=bombs.x;
                var y=bombs.y;
                img3. () {
                    cxt.drawImage(img1,x,y,30,30);
                }
            }
            //减血
            bomb.bloodDown();
            if(bomb.blood<=0)
            {
                //把这个炸弹从数组中去掉
                bombs.splice(i,1);
            }
        }
    }
}


























本文转自蓬莱仙羽51CTO博客,原文链接:http://blog.51cto.com/dingxiaowei/1366603,如需转载请自行联系原作者


相关文章
|
1月前
超好看的照片墙HTML源码
超好看的照片墙HTML源码
44 10
超好看的照片墙HTML源码
|
7天前
漂亮的七彩引导页导航HTML源码
漂亮的七彩引导页导航HTML源码,源码由HTML+CSS+JS组成,记事本打开源码文件可以进行内容文字之类的修改,双击html文件可以本地运行效果,也可以上传到服务器里面,重定向这个界面
3 0
漂亮的七彩引导页导航HTML源码
|
8天前
超漂亮二次元导航HTML源码
超漂亮网站导航HTML源码,页面中调用了很多外站链接需自行更换 修改方法:使用记事本右键打开修改即可~
10 0
超漂亮二次元导航HTML源码
|
19天前
二次元导航HTML源码
二次元导航HTML源码,很好看的一个htmlの引导页
17 0
二次元导航HTML源码
|
1月前
爱情告白主题特效HTML源码
爱情告白主题特效HTML源码
14 2
爱情告白主题特效HTML源码
|
1月前
超好看的下载页HTML源码分享
超好看的下载页HTML源码分享
65 4
超好看的下载页HTML源码分享
|
2月前
|
前端开发 JavaScript
基于HTML实现浪漫情人节表白代码(附源代码)
基于HTML实现浪漫情人节表白代码(附源代码)
132 0
|
8月前
抖音超火的圣诞树代码,html源码分享
抖音超火的圣诞树代码,html源码分享
435 0
|
4月前
|
移动开发 JavaScript 前端开发
个人博客html5雪花飘落代码JS特效下载
如何给自己的网站/页面添加雪花代码、特效呢?有的网站配合自己的主题模板添加雪花飘落效果挺好看的。特别是与冬天季节相关的主题,很多的博客空间都加了雪花的效果。
114 1
|
10月前
|
存储 移动开发 算法
HTML5 游戏开发实战 | 推箱子
经典的推箱子是一个来自日本的古老游戏,目的是在训练玩家的逻辑思考能力。在一个狭小的仓库中,要求把木箱放到指定的位置,稍不小心就会出现箱子无法移动或者通道被堵住的情况,所以需要巧妙地利用有限的空间和通道,合理安排移动的次序和位置,才能顺利地完成任务
114 0
HTML5 游戏开发实战 | 推箱子