天天看点

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,如需转载请自行联系原作者

继续阅读