天天看点

html5学习--实现坦克可以连续发射子弹

js代码:

//定义颜色的全局变量

var heroColors = new Array("#BA9658", "#FEF26E");

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

//其他的坦克,这里的拓展性还可以

//子弹类

function Bullet(x, y, direct) {

    this.x = x;

    this.y = y;

    this.speed = 1;

    this.direct = direct;

    this.timer = null;

    this.live = true;

    this.run = function run() {

        //先判断子弹是否已经到边界

        if (this.x <= 0 || this.x >= 400 || this.y <= 0 || this.y >= 300) {

            //子弹停止

            window.clearInterval(this.timer);

            this.live = 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("tankMap").innerText = "子弹x=" + this.x + "子弹=y" + this.y;

    }

}

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

    this.x = x;

    this.y = y;

    this.speed = 8;

    this.direct = direct;

    this.color = color;

    //up

    this.moveUp = function () {

        if (2 != this.direct) {

            if (this.y - this.speed < 0)

                this.y = 0;

            else

                this.y -= this.speed;

        }

        this.direct = 0;

    }

    //right

    this.moveRight = function () {

        if (3 != this.direct) {

            if (this.x + this.speed > 400 - 30)

                this.x = 400 - 30;

            else

                this.x += this.speed;

        }

        this.direct = 1;

    }

    //down

    this.moveDown = function () {

        if (0 != this.direct) {

            if (this.y + this.speed >= 300 - 30)

                this.y = 300 - 30;

            else

                this.y += this.speed;

        }

        this.direct = 2;

    }

    //left

    this.moveLeft = function () {

        if (1 != this.direct) {

            if (this.x - this.speed < 0)

                this.x = 0;

            else

                this.x -= this.speed;

        }

        this.direct = 3;

    }

}

//画出自己的子弹,你也尅一把该函数封装到HeroTank类中

function drawHeroBullet() {

    //要画出所有子弹

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

        var heroBullet = heroBullets[i];

        if (null != heroBullet && true == heroBullet.live) {

            cxt.fillStyle = "#FEF26E";

            cxt.fillRect(heroBullet.x, heroBullet.y, 2, 2);

        }

    }

}

//把绘制坦克封装成一个函数,将来可以作为成员函数

function drawTank(tank) {

    switch (tank.direct) {

        case 0:

        case 2:

            //画出自己的坦克,使用前面的绘图技术

            //设置颜色

            cxt.fillStyle = tank.color[0];

            //使用先死--》后活(初学者最好使用这个方法)

            //先画出矩形

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

            //画出右边的矩形(这时请大家思路-》一定要定义一个参照点)

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

            //画出中间矩形

            cxt.fillRect(tank.x + 6, tank.y + 5, 8, 20);

            //画出中间的盖子

            cxt.beginPath();

            cxt.fillStyle = tank.color[1];

            cxt.arc(tank.x + 10, tank.y + 15, 4, -30, 360, true);

            cxt.closePath();

            cxt.fill();

            //画出炮筒

            cxt.strokeStyle = tank.color[1];

            cxt.lineWidth = 1.5;

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

            if (0 == tank.direct)

                cxt.lineTo(tank.x + 10, tank.y);

            else if (2 == tank.direct)

                cxt.lineTo(tank.x + 10, tank.y + 30);

            cxt.stroke();

            break

        case 1:

        case 3:

            //画出自己的坦克,使用前面的绘图技术

            //设置颜色

            cxt.fillStyle = "#BA9658";

            //使用先死--》后活(初学者最好使用这个方法)

            //先画出矩形

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

            //画出右边的矩形(这时请大家思路-》一定要定义一个参照点)

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

            //画出中间矩形

            cxt.fillRect(tank.x + 5, tank.y + 6, 20, 8);

            //画出中间的盖子

            cxt.beginPath();

            cxt.fillStyle = "#FEF26E";

            cxt.arc(tank.x + 15, tank.y + 10, 4, -30, 360, true);

            cxt.closePath();

            cxt.fill();

            //画出炮筒

            cxt.strokeStyle = "#FEF26E";

            cxt.lineWidth = 1.5;

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

            if (1 == tank.direct)

                cxt.lineTo(tank.x + 30, tank.y + 10);

            else if (3 == tank.direct)

                cxt.lineTo(tank.x, tank.y + 10);

            cxt.stroke();

            break

    }

}

//定义一个hero类

//x:横坐标 y:纵坐标

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

    //下面两句话的作用是:通过对象冒充达到继承的效果

    this.tank = Tank;

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

    //增加一个函数射击敌人坦克

    this.shotEnemy = function () {

        //创建子弹,子弹的位置应该和坦克的方向有关,并且与坦克的方向是一致的

        //this.x就是当前hero的横坐标

        switch (this.direct) {

            case 0:

                //alert("0");

                heroBullet = new Bullet(this.x + 9, this.y, this.direct);

                break;

            case 1:

                //alert("1");

                heroBullet = new Bullet(this.x + 30, this.y + 9, this.direct);

                break;

            case 2:

                //alert("2");

                heroBullet = new Bullet(this.x + 9, this.y + 30, this.direct);

                break;

            case 3:

                //alert("3");

                heroBullet = new Bullet(this.x, this.y + 9, this.direct);

                break

        }

        //把这个子弹放入到数组中-->push函数

        heroBullets.push(heroBullet);

        //调用我们的子弹run

        //这里有一个技术难度比较大:如果按下面的方法,则所有的子弹共享一个定时器

        //var timer = window.setInterval("heroBullet.run()", 50);

        //heroBullet.timer = timer;

        //按这个方法,所有的子弹都有独立的定时器

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

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

    }

}

//定义一个敌人的坦克

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

    this.tank = Tank;

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

}

html代码:

<!DOCTYPE html>

<html>

<head>

<meta content="text/html;charset=utf-8"/>

<title></title>

</head>

<body οnkeydοwn="getCommand()">

    <h1>html5-经典的坦克大战</h1>

    <canvas id ="tankMap" width="400px" height="300px"

        style="background-color:black">

    </canvas>

    <!--把tankGams.js引入到本页面-->

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

    <script type="text/javascript">

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

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

        //我的坦克hero

        var hero = new HeroTank(40, 40, 0, heroColors);

        //定义个子弹数组

        var heroBullets = new Array();

        //定义敌人的坦克(敌人的坦克有多少?思路:是单个单个的定义,还是放在数组中)

        var enemyTanks = new Array();

        //先死后活,定义3个,后面我们打敌人坦克的数量,做出变量

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

        {

            //创建一个坦克

            var enemyTank = new EnemyTank((i + 1) * 50, 0, 2, enemyColors);

            //把坦克放进数组中

            enemyTanks[i] = enemyTank;

        }

        //打开页面先刷新一次

        flashTankMap();

        //专门写一个函数,用于定时刷新我们的作战区,把要在作战区出现的元素(自己的坦克、

        //敌人的坦克、子弹、炸弹,障碍物)

        function flashTankMap() {

            cxt.clearRect(0, 0, 400, 300);

            //我的坦克

            drawTank(hero);

            //画出自己的子弹

            //子弹飞效果是怎么出现的:首先我们应该每隔一定时间就去刷新作战区,如果在书信的时候,子弹坐标

            //变换了,给人的感觉就是子弹在飞

            drawHeroBullet();

            //敌人所有的坦克

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

                drawTank(enemyTanks[i]);

            }

        }

        //这是一个接收用户按键的函数

        function getCommand() {

            var code = event.keyCode;

            switch (code) {

                case 87://up

                    hero.moveUp();

                    break;

                case 68://right

                    hero.moveRight();

                    break;

                case 83://down

                    hero.moveDown();

                    break;

                case 65://left

                    hero.moveLeft();

                    break;

                case 74://Bullet

                    hero.shotEnemy();

                    break;

            }

            //出发这个函数flashTankMap();

            flashTankMap();

            //重新绘制所有的敌人的坦克,你可以在这里写代码()

        }

        //每隔100毫秒去刷新一次作战区

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

    </script>

</body>

</html>

继续阅读