LHdrogen
液氢
2020-06-18 22:24
采纳率: 100%
浏览 292

H5写的飞机大战代码报错

图片说明

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>飞机大战</title>
        <style>
            div{
                text-align: center;
                margin: 10px auto;
            }

            #canfly{
                background-color: #999999;
                cursor: pointer;
            }

            body{
                margin: 0px;
                padding: 0px;
            }
        </style>
    </head>
    <body>
        <div>
            <h3>飞机大战</h3>
            <canvas id="canfly" width="480" height="650"></canvas>
        </div>
    </body>
    <script>

        (function(){

            var canvas = document.getElementById("canfly");
            var context = canvas.getContext("2d");

            //游戏基础数据
            var gameData = {
                state : 0,//状态

                //游戏状态常量
                START : 0,
                STARTING : 1,
                RUNNING : 2,
                PAUSE : 3,
                GAMEOVER  : 4,
                HEROLIFE : 3,
                score : 0,
                WIDTH : 480,
                HEIGHT : 650,
            }

            //加载背景图片
            var bgImg = new Image();
            bgImg.src = "images/background.png";
            var SKY = {
                imgs : bgImg,
                width : 480,
                height : 650,
            }

            //startLogo
            var startLogo = new Image();
            startLogo.src = "images/start.png";

            //加载飞机入场动画
            var loadings = [];
            loadings[0] = new Image();
            loadings[0].src = "images/game_loading1.png";
            loadings[1] = new Image();
            loadings[1].src = "images/game_loading2.png";
            loadings[2] = new Image();
            loadings[2].src = "images/game_loading3.png";
            loadings[3] = new Image();
            loadings[3].src = "images/game_loading4.png";

            //初始化入场动画图片数据
            var LOADING = {
                imgs : loadings,
                width : 186,
                height : 38,
                sum : loadings.length//图片个数
            }

            //加载英雄机
            var heros = [];
            heros[0] = new Image();
            heros[0].src = "images/hero1.png";
            heros[1] = new Image();
            heros[1].src = "images/hero2.png";
            heros[2] = new Image();
            heros[2].src = "images/hero_blowup_n1.png";
            heros[3] = new Image();
            heros[3].src = "images/hero_blowup_n2.png";
            heros[4] = new Image();
            heros[4].src = "images/hero_blowup_n3.png";
            heros[5] = new Image();
            heros[5].src = "images/hero_blowup_n4.png";

            //初始化英雄机
            var HERO = {
                imgs : heros,
                width : 99,
                height : 124,
                sum : heros.length,
                length : 2 
            }

            //子弹
            var bullet = [];
            bullet[0] = new Image();
            bullet[0].src = "images/bullet1.png";

            //初始化子弹
            var BULLET = {
                imgs : bullet,
                width : 8,
                height : 21,
                sum : bullet.length
            }

            //加载暂停图片
            var paused = new Image();
            paused.src = "images/game_pause_nor.png";

            //加载敌机图片
            var enemies1 = [];//小型飞机
            enemies1[0] = new Image();
            enemies1[0].src = "images/enemy1.png";
            enemies1[1] = new Image();
            enemies1[1].src = "images/enemy1_down1.png";
            enemies1[2] = new Image();
            enemies1[2].src = "images/enemy1_down2.png";
            enemies1[3] = new Image();
            enemies1[3].src = "images/enemy1_down3.png";
            enemies1[4] = new Image();
            enemies1[4].src = "images/enemy1_down4.png";

            var ENEMY1 = {
                imgs : enemies1,
                width : 57,
                height : 51,
                type : 0,//敌机类型
                sum : enemies1.length,//爆炸图片个数
                length : 1,//正常图片个数
                reviseH : 12,//碰撞高度修正
                reviseW : 6,//碰撞宽度修正
                life : 1,//生命
                score : 1//分数
            }

            var enemies2 = [];//中型飞机
            enemies2[0] = new Image();
            enemies2[0].src = "images/enemy2.png";
            enemies2[1] = new Image();
            enemies2[1].src = "images/enemy2_down1.png";
            enemies2[2] = new Image();
            enemies2[2].src = "images/enemy2_down2.png";
            enemies2[3] = new Image();
            enemies2[3].src = "images/enemy2_down3.png";
            enemies2[4] = new Image();
            enemies2[4].src = "images/enemy2_down4.png";

            var ENEMY2 = {
                imgs : enemies2,
                width : 69,
                height : 95,
                type : 1,//敌机类型
                sum : enemies2.length,//爆炸图片个数
                length : 1,//正常图片个数
                reviseH : 8,//碰撞高度修正
                reviseW : 2,//碰撞宽度修正
                life : 3,//生命
                score : 5//分数
            }

            var enemies3 = [];//大型飞机
            enemies3[0] = new Image();
            enemies3[0].src = "images/enemy3_n1.png";
            enemies3[1] = new Image();
            enemies3[1].src = "images/enemy3_n2.png";
            enemies3[2] = new Image();
            enemies3[2].src = "images/enemy3_hit.png";
            enemies3[3] = new Image();
            enemies3[3].src = "images/enemy3_down1.png";
            enemies3[4] = new Image();
            enemies3[4].src = "images/enemy3_down2.png";
            enemies3[5] = new Image();
            enemies3[5].src = "images/enemy3_down3.png";
            enemies3[6] = new Image();
            enemies3[6].src = "images/enemy3_down4.png";
            enemies3[7] = new Image();
            enemies3[7].src = "images/enemy3_down5.png";
            enemies3[8] = new Image();
            enemies3[8].src = "images/enemy3_down6.png";

            var ENEMY3 = {
                imgs : enemies3,
                width : 168,
                height : 258,
                type : 2,//敌机类型
                sum : enemies3.length,//爆炸图片个数
                length : 2,//正常图片个数
                reviseH : 8,//碰撞高度修正
                reviseW : 2,//碰撞宽度修正
                life : 10,//生命
                score : 20//分数
            }

            //------------------------------//

            //创建通用构造器
            function Compant(config){

                this.imgs = config.imgs;//加载图片
                this.width = config.width;
                this.height = config.height;
                this.sum = config.sum;
                this.length = config.length;

                //敌机属性
                this.type = config.type;//类型
                this.life = config.life;//生命值
                this.score = config.score;//分数
                this.time = 0;//相对速度
                this.index = 0;//索引值
                this.down = false;//是否执行爆破动画标识
                this.canDelete = false;//是否删除标识

                //绘制坐标
                this.x = 0;
                this.y = 0;

                //绘制方法
                this.paint = function(){
                    context.drawImage(this.imags[this.index],this.x,this.y);
                }

                this.step = function(){};//移动方法
                this.bang = function(){};//执行撞击后逻辑方法

            }

            //创建背景图片构造器
            function Bgsky(config){

                //通用构造器初始化
                Compant.call(this,config);///

                //绘制高度变量
                this.y1 = -this.height;
                this.y2 = 0;

                //定义绘制方法
                this.paint = function(){
                    context.drawImage(this.imgs,0,this.y1);//第一张图片
                    context.drawImage(this.imgs,0,this.y2);//第二张图片

                }

                //背景的运动方法
                this.step = function(){

                    this.time++;
                    if(this.time % 3 == 0){
                        this.y1++;//运动到下一帧
                        this.y2++;

                        //图片移动至画布后,将y坐标重置为-height,实现图片的连续滚动
                        this.y1 > this.height && (this.y1 = -this.height);
                        this.y2 > this.height && (this.y2 = -this.height);
                        this.time = 1;//垂直移动时间

                    }
                }
            }

            var sky = new Bgsky(SKY);

            //入场动画构造器
            function Loading(config){

                //调用构造器
                Compant.call(this,config);

                //定义绘制方法
                this.paint = function(){
                    context.drawImage(this.imgs[this.index],0,gameData.HEIGHT - this.height);
                }

                //定义入场动画
                this.step = function(){
                    this.time++;
                    if(this.time % 20 == 0){
                        this.index++;
                        if(this.index == this.sum){
                            gameData.state = gameData.RUNNING;
                            this.time = 0;
                        }
                    }
                }
            }

            var loading = new Loading(LOADING);

            //英雄机构造函数
            function Hero(config){

                Compant.call(this,config);
                this.btTime = 0;
                this.x = (gameData.WIDTH - this.width)/2;
                this.y = gameData.HEIGHT - this.height - 10;

                //定义绘制方法
                this.paint = function(){
                    context.drawImage(this.imgs[this.index],this.x,this.y);
                }

                //定义飞机动画
                this.step = function(){
                    this.time++;
                    if(this.down){
                        if(this.time % 15 == 0){
                            this.index++;
                            if(this.index >= this.sum){
                                if(gameData.HEROLIFE > 0){
                                    hero = new Hero(HERO);
                                    this.down = false;
                                }else{
                                    gameData.state = gameData.GAMEOVER;
                                }
                                this.index = this.length;
                            }
                        }
                    }else{
                        if(this.time % 15 == 0){
                            this.index++;
                            this.index %= this.length;
                             this.time = 0;
                        }
                    }
                }

                //射击方法
                this.shoot = function(){
                    this.btTime++;
                    if(this.btTime % 25 == 0){
                        bullets[bullets.length] = new Bullet(BULLET);
                        this.btTime = 0;
                    }
                }

                //撞机方法
                this.bang = function(){
                    if(!this.down){
                        gameData.HEROLIFE--;
                        this.down = true;
                        this.index = this.length;
                    }
                }
            }

            var hero = new Hero(HERO);

            var bullets = [];

            //定义子弹构造器
            function Bullet(config){
                Compant.call(this,config);

                //子弹坐标
                this.x = hero.x + hero.width/2 - this.width/2;
                this.y = hero.y - this.height;

                //绘制子弹
                this.paint = function(){
                    context.drawImage(this.imgs[this.index],this.x,this.y);
                }

                //定义子弹移动
                this.step = function(){
                    this.y -= 1;//子弹移动速度
                }

                //子弹删除
                this.bang = function(){
                    this.canDelete = true;
                }
            }

            //绘制子弹
            function paintBullets(){
                for(var i = 0,length = bullets.length;i < length;i++){
                    bullets[i].paint();//绘制当前子弹
                    if(gameData.state == gameData.RUNNING){
                        bullets[i].step();
                    }
                }
            }

            //清除超出屏幕的子弹
            function clearBullet(){
                for(var i = bullets.length - 1;i >= 0;i--){
                    if(bullets[i].y <= bullets[i].height || (bullets[i].canDelete)){
                            bullets.splice(i,1);//删除
                    }
                }
            }

            //绘制游戏得分
            function paintText(){
                context.font = "bold 24px 微软雅黑";
                context.fillText("得分:" + gameData.score,10,30);
                context.fillText("生命:" + gameData.HEROLIFE,390,30);
            }

            //绘制暂停图标
            function paintPaused(){
                context.drawImage(paused,gameData.WIDTH/2 - 30,gameData.HEIGHT/2 - 22.5);
            }

            //敌机构造器
            function Enemy(config){

                //调用通用构造器初始化
                Compant.call(this,config);

                //设置撞击修正
                this.reviseH = config.reviseH;
                this.reviseW = config.reviseW;

                //敌机坐标
                this.x = Math.floor(Math.random()*(gameData.WIDTH - this.width));
                this.y = -this.height;

                //定义绘制方法
                this.paint = function(){
                    context.drawImage(this.imgs[this.index],this.x,this.y);
                }

                //移动方法
                this.step = function(){
                    if(this.down){//坠机
                        this.time++;//播放爆炸动画

                        if(this.time % 15 == 0){
                            this.index++;
                        }

                        if(this.index >= this.sum){//判断动画是否播放完毕
                            gameData.score += this.score;
                            this.canDelete = true;
                        }

                    }else{//未坠机

                        //敌机移动
                        this.time++;
                        switch(this.type){
                            case 0://小型飞机
                                this.y++;
                                break;
                            case 1://中型飞机
                                this.time % 2 == this.y++;
                                break;
                            case 2://大型飞机
                                this.time % 3 == this.y++;
                                break;
                        }

                        //大型飞机动画
                        this.bigTime++;
                        if(this.type == 2 && (this.bigTime % 10 == 0)){
                            this.index = this.index == 0 ? 1 : 0;
                            this.bigTime = 0;//重置
                        }
                    }   
                }

                //判断敌机是否被撞击
                this.hit = function(bh){
                    return (bh.x + bh.width > this.x - this.reviseW) && (bh.y < this.y + this.height - this.reviseH)
                     && (bh.x < this.x + this.width + this.reviseW) && (bh.y + bh.height > this.y + this.reviseH);
                }

                //敌机被撞
                this.bang = function(){
                    if(!this.down && !this.canDelete){
                        this.life--;
                        if(this.life <= 0){
                            this.down = true;
                            this.index = this.length;//开始执行爆炸动画
                        }
                    }
                }
            }

            //创建敌机方法
            var enemies = [];//存储敌机
            var enemyTime = 0;//敌机出现速度
            function createEnemies(){

                //生成随机数用于判断飞机类型
                var num = Math.floor(Math.random()*100);
                if(num < 70){//小型飞机
                    enemies[enemies.length] = new Enemy(ENEMY1);
                }else if(num < 90){//中型飞机
                    enemies[enemies.length] = new Enemy(ENEMY2);
                }else{//大型飞机
                    if(enemies.length > 0 && enemies[0].type != 2){
                        enemies.unshift(new Enemy(ENEMY3));//将大型飞机添加到数组开头
                    }
                }
            }

            //绘制飞机以及删除超出屏幕的飞机
            function paintEnemiesAndCheckHIt(){
                for(var i = 0;i<enemies.length;i++){
                    var enemy = enemies[i];

                    //判断敌机和英雄机是否被击落或飞出屏幕外
                    if((enemy.y > gameData.HEIGHT) || enemy.canDelete){
                        enemies.splice(i,1);
                        continue;
                    }

                    //绘制飞机
                    enemy.paint();
                    //判断游戏是否正在运行
                    if(gameData.state == gameData.RUNNING){
                        enemy.step();
                    }

                    //判断是否和英雄机碰撞
                    if(enemy.hit(hero)){
                        enemy.bang();
                        hero.bang();
                    }

                    //判断是否被子弹击中
                    for(var j = 0;j < bullets.length;j++){
                        var bullet = bullets[j];
                        if(enemy.hit(bullet)){
                            enemy.bang();
                            bullet.bang();
                        }
                    }
                }
            }

            //------------------------------//

            //画布点击事件
            canvas.onclick = function(){
                if(gameData.state == gameData.START){
                    gameData.state = gameData.STARTING;
                }
            }

            //画布绑定鼠标移动事件 - 控制飞机移动
            canvas.onmousemove = function(event){

                //获取鼠标当前坐标
                var x = event.offsetX;
                var y = event.offsetY;

                //设置飞机坐标
                hero.x = x - hero.width/2;
                hero.y = y - hero.height/2;

                if(gameData.state == gameData.PAUSE){
                    gameData.state = gameData.RUNNING;
                }
            }

            //鼠标移出游戏界面暂停事件
            canvas.onmouseout = function(){
                if(gameData.state == gameData.RUNNING){
                    gameData.state = gameData.PAUSE;
                }
            }

            function gameOver(){
                context.font = "bold 45px 微软雅黑";
                context.fillText("Game Over",gameData.WIDTH/2 - 150,gameData.HEIGHT/2);
            }

            //-----------------------------//

            //初始化飞机大战方法
            function init(){
                //执行游戏
                gameExec();
            }

            //游戏执行函数
            function gameExec(){

                //背景
                sky.paint();
                sky.step();
                enemyTime++;//敌机创建的速度
                switch(gameData.state){

                    case gameData.START:
                        context.drawImage(startLogo,30,0);
                        break;

                    case gameData.STARTING://进场动画加载
                        loading.paint();
                        loading.step();
                        break;

                    case gameData.RUNNING:

                        //加载飞机
                        hero.paint();
                        hero.step();

                        //绘制子弹
                        hero.shoot();
                        paintBullets();

                        //创建飞机
                        if(enemyTime % 100 == 0){
                            createEnemies();
                        }

                        //绘制所有地方飞机和碰撞检测
                        paintEnemiesAndCheckHIt();

                        //清除子弹
                        clearBullet();
                        break;

                    case gameData.PAUSE:

                        //绘制飞机
                        hero.paint();
                        //绘制子弹
                        paintBullets();
                        //绘制暂停图片
                        paintPaused();
                        break;

                    case gameData.GAMEOVER:
                        gameOver();
                        break;

                }

                //绘制得分
                paintText();

                //定时执行
                setTimeout(function(){
                    gameExec();
                },8);
            }
            //执行初始化方法
            init();
        })()
    </script>
</html>

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • qq_37524684
    子幽 2020-06-19 09:40
    已采纳

    把drawImage放到img对象的load事件中试试

    点赞 评论

相关推荐