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

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条回答 默认 最新

  • 子幽 2020-06-19 09:40
    关注

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

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 微信公众平台自制会员卡可以通过收款码收款码收款进行自动积分吗
  • ¥15 随身WiFi网络灯亮但是没有网络,如何解决?
  • ¥15 gdf格式的脑电数据如何处理matlab
  • ¥20 重新写的代码替换了之后运行hbuliderx就这样了
  • ¥100 监控抖音用户作品更新可以微信公众号提醒
  • ¥15 UE5 如何可以不渲染HDRIBackdrop背景
  • ¥70 2048小游戏毕设项目
  • ¥20 mysql架构,按照姓名分表
  • ¥15 MATLAB实现区间[a,b]上的Gauss-Legendre积分
  • ¥15 delphi webbrowser组件网页下拉菜单自动选择问题