JS飞机大战

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        canvas{
            border: 1px solid pink;
            /* margin: 0 auto; */
            position: absolute;
            left: 0;
            right: 0;
            margin: auto;
        }
    </style>
</head>
<body>
    <canvas width="480" height="852"></canvas>


    <script>

        // 0. 数据初始化
        var canvas = document.getElementsByTagName('canvas')[0];
        var ctx = canvas.getContext('2d');
        var ready = 0;
        var loading = 1;
        var running = 2;
        var pause = 3;
        var over = 4;
        // 当前游戏阶段的判定
        var state = ready;
        // 游戏生命值
        var life = 3;
        // 游戏分数
        var score = 0;

        // 画布宽高
        var width = 480;
        var height = 852;


        // 1. 准备阶段 ready
        // 1. 绘制运动的背景图片
        // 1.1 创建背景图片对象
        var bg = new Image();
        bg.src = 'img/background.png';
        // 1.2 确定当前背景图片的绘制位置、绘制大小的信息
        var bgParam = {
            bg:bg,
            x:0,
            y:0,
            width:480,
            height:852
        }

        // 1.3创建一个构造函数  用来实例化背景图片对象
        function Bg(param){
            this.bg = param.bg;
            this.x = param.x;
            this.y = param.y;
            this.width = param.width;
            this.height = param.height;

            // 交替图片的坐标位置
            this.y1 = -this.height;

            // 1. 绘制
            this.paint = function(){
                ctx.drawImage(this.bg,this.x,this.y,this.width,this.height);
                ctx.drawImage(this.bg,this.x,this.y1,this.width,this.height);

            }
            // 2. 运动
            this.sport = function(){
                this.y += 5;
                this.y1 += 5;

                // 交换图片
                if(this.y >= this.height){
                    this.y = - this.height;
                }
                if(this.y1 >= this.height){
                    this.y1 = -this.height;
                }
            }
        }
        var bgObj = new Bg(bgParam);


        // 2. 绘制logo
        // 2.1 创建logo图片
        var logo = new Image();
        logo.src = 'img/start.png';
        // 2.2 定义logo初始化信息
        var logoParam = {
            logo:logo,
            x:0,
            y:0,
            width:400,
            height:654
        }
        // 2.3 创建构造函数
        function Logo(param){
            this.logo = param.logo;
            this.x = param.x;
            this.y = param.y;
            this.width = param.width;
            this.height = param.height;

            // 绘制
            this.paint = function(){
                ctx.drawImage(this.logo,this.x,this.y,this.width,this.height);
            }
        }
        var logoObj = new Logo(logoParam);


        //  点击画布进入到下一个阶段 loading
        canvas.onclick = function(){
            if(state === ready){
                state = loading;
            }
            
        }
        // 暂停
        canvas.onmouseleave=function(){
           if(state==running){
               state=pause;
               pauseObj.paint()
           }
        }
        var pauseImg='img/game_pause_nor.png'
        pause=new Image()
        pause.src=pauseImg
        var pauseParam={
            pause:pause,
            x:230,
            y:426,
            width:60,
            height:45
        }
        function Pause(param){
            this.pause=param.pause;
            this.width=param.width;
            this.height=param.height;
            this.x=param.x;
            this.y=param.y

            this.paint=function(){
                ctx.drawImage(this.pause,this.x,this.y,this.width,this.height);
            }
        }
        var pauseObj = new Pause(pauseParam);

        // 开始
        canvas.onmouseenter=function(){
           if(state==pause){
               state=running;
           }
        }


        // 2. 游戏加载阶段 loading
        // 2.1. 进场图片
        var imgArr = ['img/game_loading1.png','img/game_loading2.png','img/game_loading3.png','img/game_loading4.png'];
        var imgLoading = [];
        for(var i = 0;i<imgArr.length;i++){
            imgLoading[i] = new Image();
            imgLoading[i].src = imgArr[i];
        }
        console.log(imgLoading);//
        // 绘制完进场图片马上进入下一阶段 running

        // 2.3 定义图片信息
        var loadingParam = {
            imgLoading:imgLoading,
            width:186,
            height:38
        }
        function Loading(param){
            this.imgLoading = param.imgLoading;
            this.width = param.width;
            this.height = param.height;
            this.x = 0;
            this.y = height - param.height;

            // 定义绘制图片的下标
            this.index = 0;

            // 定义一个属性 用来判断定时器的执行次数
            this.time = 0;

            this.paint = function(){
                ctx.drawImage(this.imgLoading[this.index],this.x,this.y,this.width,this.height);
            }
            this.sport = function(){
                this.time++;
                if(this.time % 5 == 0){
                    this.index ++;
                    if(this.index === this.imgLoading.length){
                        // 绘制图片超过整体数量时 进入到下一个阶段
                        state = running;
                    }
                }
            }
        }
        var loadingObj = new Loading(loadingParam);

        // 3. 游戏进行中  running
        // 3.1 绘制我方飞机
        var heroArr = ['img/hero1.png','img/hero2.png','img/hero_blowup_n1.png','img/hero_blowup_n2.png','img/hero_blowup_n3.png','img/hero_blowup_n4.png']
        var heroPlane = [];
        for(var i = 0;i<heroArr.length;i++){
            heroPlane[i] = new Image();
            heroPlane[i].src = heroArr[i];
        }

        var heroParam = {
            heroPlane:heroPlane,
            width:99,
            height:124
        }

        function Hero(param){
            this.heroPlane = param.heroPlane;
            this.width = param.width;
            this.height = param.height;

            this.x = width/2 - this.width/2;
            this.y = height - this.height;
            // 切换图片的下标
            this.index = 0;
            // 判断飞机是否被撞击
            this.down = false;
            this.time = 0;




            // 绘制
            this.paint = function(){
                ctx.drawImage(this.heroPlane[this.index],this.x,this.y,this.width,this.height);
            }

            this.sport = function(){
                // 我方飞机是否被撞击了
                // 1. 我方飞机没有被撞击
                if(!this.down){
                    if(this.index === 0){
                        this.index = 1;
                    }else {
                        this.index = 0;
                    }
                }else{
                    // 2. 我方飞机被撞击了
                    this.index ++;
                    if(this.index === this.heroPlane.length){
                        life --;
                        if(life == 0){
                            state = over;
                            // 游戏结束之后 让飞机停留在冒烟状态
                            this.index = this.heroPlane.length -1;
                        }else{
                            heroObj = new Hero(heroParam);
                        }
                    }
                }
            }

            this.shoot = function(){
                this.time ++;
                if(this.time % 2 === 0){
                    bullets.push(new Bullet(bulletParam));
                }
            }
        }
        var heroObj = new Hero(heroParam);


        // 3.1.1 给画布绑定移动事件 飞机跟着鼠标移动
        canvas.onmousemove = function(e){
            if(state === running){
                // 获取鼠标移动后的位置
                heroObj.x = e.offsetX - heroObj.width/2;
                heroObj.y = e.offsetY - heroObj.height/2;
            }
        }


        // 3.2 子弹
        // 3.2.1 创建子弹图片
        var bullet = new Image();
        bullet.src = 'img/bullet1.png';

        var bulletParam = {
            bullet:bullet,
            width:9,
            height:21
        }
        function Bullet(param){
            this.bullet = param.bullet;
            this.width = param.width;
            this.height = param.height;

            this.x = heroObj.x + heroObj.width/2 - this.width/2;
            this.y = heroObj.y - this.height - 10;

            // 判断子弹是否碰撞到了敌机
            this.down = false;

            // 绘制
            this.paint = function(){
                ctx.drawImage(this.bullet,this.x,this.y,this.width,this.height);
            }

            // 运动
            this.sport = function(){
                // this.x = heroObj.x + heroObj.width/2 - this.width/2;
                this.y -= 25;
            }
        }
        // 只创建一个子弹对象 发射出去就没有了
        // var bulletObj = new Bullet(bulletParam);
        // 存储子弹对象
        var bullets = [];


        // 绘制子弹
        function bulletsPaint(){
            for(var i = 0;i<bullets.length;i++){
                bullets[i].paint();
            }
        }
        function bulletsSport(){
            for(var i = 0;i<bullets.length;i++){
                bullets[i].sport();
            }
        }

        // 删除子弹

        // 1. 子弹飞出屏幕外面
        // 2. 子弹敌机碰撞了
        function bulletsDelete(){
            for(var i = 0;i<bullets.length;i++){
                if(bullets[i].y < - this.height||bullets[i].down){
                    bullets.splice(i,1);
                }
                // if(bullets[i].down){
                //     bullets.splice(i,1);
                // }
            }
        }
        
        // 3.3 敌方飞机 
        // 3.3.1 小号飞机
        var enemy1Arr = ['img/enemy1.png','img/enemy1_down1.png','img/enemy1_down2.png','img/enemy1_down3.png','img/enemy1_down4.png'] ;
        // 3.3.2 中号飞机
        var enemy2Arr=['img/enemy2.png','img/enemy2_down1.png','img/enemy2_down2.png','img/enemy2_down3.png','img/enemy2_down4.png'];
        // 3.3.3 大号飞机
        var enemy3Arr=['img/enemy3_n1.png','img/enemy3_n2.png','img/enemy3_hit.png','img/enemy3_down1.png','img/enemy3_down2.png','img/enemy3_down3.png','img/enemy3_down4.png','img/enemy3_down5.png','img/enemy3_down6.png']
        
        var enemyPlane1 = [];
        //小号飞机
        for(var i=0;i<enemy1Arr.length;i++){
            enemyPlane1[i] = new Image();
            enemyPlane1[i].src = enemy1Arr[i];
        }

        // 小号飞机信息
        var enemy1 = {
            enemyPlane1:enemyPlane1,
            width:57,
            height:51,
            life:3
        }

        var enemyPlane2 = [];
        // 中号飞机
        for(var j=0;j<enemy2Arr.length;j++){
            enemyPlane2[j]=new Image();
            enemyPlane2[j].src=enemy2Arr[j]
        }
        var enemy2={
            enemyPlane2:enemyPlane2,
            width:69,
            height:95,
            life:5
        }

        var enemyPlane3 = [];
        // 大号飞机
        for(var n=0;n<enemy3Arr.length;n++){
            enemyPlane3[n]=new Image();
            enemyPlane3[n].src=enemy3Arr[n]
        }
        var enemy3={
            enemyPlane3:enemyPlane3,
            width:169,
            height:258,
            life:10
        }
        // 小号敌机的构造函数
        function Enemy1(param){
            this.enemyPlane1 = param.enemyPlane1;
            this.width = param.width;
            this.height = param.height;
            this.life = param.life;

            this.x = Math.random()*(width - this.width);
            this.y = - this.height;

            this.index = 0;
            // 判断敌机是否发生碰撞
            this.down = false;
            // 是否爆照完成
            this.bang = false;

            this.paint = function(){
                ctx.drawImage(this.enemyPlane1[this.index],this.x,this.y,this.width,this.height);
            }

            this.sport = function(){
                if(!this.down){
                    // 当前敌机未被碰撞时
                    this.y +=8;
                }else{
                    this.y+=5;
                    if(this.life<=0){
                        this.index ++;
                        if(this.index === this.enemyPlane1.length){
                            this.index = this.enemyPlane1.length -1;
                            this.bang = true;
                            score+=3
                        }
                    }
                }
            }

            // 判断是否被碰撞
            this.hit = function(obj){
                return obj.x + obj.width >= this.x && obj.x <= this.x + this.width && 
                        obj.y <= this.y + this.height && obj.y + obj.height >= this.y;
            }
        }
        // 中号
        function Enemy2(param){
            this.enemyPlane2 = param.enemyPlane2;
            this.width = param.width;
            this.height = param.height;
            this.life = param.life;

            this.x = Math.random()*(width - this.width);
            this.y = - this.height;

            this.index = 0;
            // 判断敌机是否发生碰撞
            this.down = false;
            // 是否爆照完成
            this.bang = false;

            this.paint = function(){
                ctx.drawImage(this.enemyPlane2[this.index],this.x,this.y,this.width,this.height);
            }

            this.sport = function(){
                if(!this.down){
                    // 当前敌机未被碰撞时
                    this.y +=8;
                }else{
                    this.y+=5;
                    if(this.life<=0){
                        this.index ++;
                        if(this.index === this.enemyPlane2.length){
                            this.index = this.enemyPlane2.length -1;
                            this.bang = true;
                            score+=5
                        }
                    }
                }
            }

            // 判断是否被碰撞
            this.hit = function(obj){
                return obj.x + obj.width >= this.x && obj.x <= this.x + this.width && 
                        obj.y <= this.y + this.height && obj.y + obj.height >= this.y;
            }
        }
        // 大号
        function Enemy3(param){
            this.enemyPlane3 = param.enemyPlane3;
            this.width = param.width;
            this.height = param.height;
            this.life = param.life;

            this.x = Math.random()*(width - this.width);
            this.y = - this.height;

            this.index = 0;
            // 判断敌机是否发生碰撞
            this.down = false;
            // 是否爆照完成
            this.bang = false;

            this.paint = function(){
                ctx.drawImage(this.enemyPlane3[this.index],this.x,this.y,this.width,this.height);
            }

            this.sport = function(){
                if(!this.down){
                    // 当前敌机未被碰撞时
                    this.y +=8;
                }else{
                    this.y+=5;
                    if(this.life<=0){
                        this.index ++;
                        if(this.index === this.enemyPlane3.length){
                            this.index = this.enemyPlane3.length -1;
                            this.bang = true;
                            score+=10
                        }
                    }
                }
            }

            // 判断是否被碰撞
            this.hit = function(obj){
                return obj.x + obj.width >= this.x && obj.x <= this.x + this.width && 
                        obj.y <= this.y + this.height && obj.y + obj.height >= this.y;
            }
        }


        // 
        var enemies = [];
        var time=0
        function pushEnemy (){
            time++;
            var random = Math.random();
            if(random < 0.5){
               if(time%8==0){
                enemies.push(new Enemy1(enemy1));
               }
            }else if(random < 0.8&&random>=0.5){
                // 中号飞机
               if(time%9==0){
                enemies.push(new Enemy2(enemy2))
               }
            }else{
                // 大号飞机
                if(time%10==0){
                    enemies.push(new Enemy3(enemy3))
                }
            }
        }
        // 绘制、运动飞机对象
        function enemyPaint(){
            for(var i=0;i<enemies.length;i++){
                enemies[i].paint();
            }
        }
        function enemySport(){
            for(var i=0;i<enemies.length;i++){
                enemies[i].sport();
            }
        }

        function enemyDelete(){
            for(var i = 0;i<enemies.length;i++){
                if(enemies[i].y >= height||enemies[i].bang){
                    enemies.splice(i,1);
                }
            }
        }

        // 如何检测每一个敌机是否被(每一个子弹 hero)碰撞
        function checkHit() {
            this.down=false
            for(var i = 0;i<enemies.length;i++){
                // 子弹和敌机撞击
               for(var j = 0;j<bullets.length;j++){
                   if(enemies[i].hit(bullets[j])){
                        bullets[j].down = true;
                        enemies[i].life--;
                    }
                    if(enemies[i].life==0){
                        enemies[i].down = true; 
                    }
               }
                // 敌机和hero
                if(enemies[i].hit(heroObj)){
                    enemies[i].down= true;
                    heroObj.down = true;
                }
            }
        }


        // 分数,生命值
        function scoreText() {
            ctx.font = "30px bold"
            ctx.fillText("score:" + score, 10, 30);
            ctx.fillText("life:" + life, 300, 30);
        };
        
        // 结束
        function gameoverfn() {
                ctx.font = "50px bold"
                ctx.fillText("GAME OVER !!!", 80, 300);
            };


        var timer=null
        // 在定时器中绘制图像
        
                timer = setInterval(function(){
                bgObj.paint();
                bgObj.sport();
                // logoObj.paint();
                
                if(state == ready){
                    ctx.drawImage(logo,0,0,480,852);
                }else if(state === loading){
                    // 绘制进场图片
                    loadingObj.paint();
                    loadingObj.sport();
                }else if(state===pause){
                    bulletsPaint();
                    heroObj.paint();
                    enemyPaint();
                    pauseObj.paint()
                } else if(state === running){
                    heroObj.paint();
                    heroObj.sport();
                    heroObj.shoot();

                    // 绘制子弹
                    // bulletObj.paint();
                    // bulletObj.sport();
                    bulletsPaint();
                    bulletsSport();

                    // 绘制敌机
                    pushEnemy();
                    enemyPaint();
                    enemySport();
                    bulletsDelete();
                    enemyDelete();
                    checkHit();
                    scoreText();
                }else if(state  === over){
                    heroObj.paint();
                    gameoverfn()
                }  
            },60)

        
       
    </script>
</body>
</html>

上一篇:网络安全批处理


下一篇:如何解决GB/T28181视频平台设备在线无法播放视频流?