飞机大战

本文详细阐述了使用JavaScript开发飞机大战小游戏的全过程,从游戏状态的定义到具体的游戏元素实现,包括动态背景、飞机与子弹的创建、敌机的多样化设定、游戏暂停与结束处理等关键环节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

飞机大战小游戏的思路

游戏存在就会有准备阶段(控制游戏全局属性):

  1. 定义游戏状态
    第一阶段:游戏欢迎状态 0 START
    第二阶段:游戏加载状态 1 LOADING
    第三阶段:游戏运行状态 2 RUNNING
    第四阶段:游戏暂停阶段 3 PAUSE
    第五阶段:游戏结束阶段 4 GAMEOVER
  2. 定义游戏得分 score = 0
  3. 定义我方飞机的生命值 life = 3
  4. 定义游戏开关:
    State=0

第一阶段

给页面添加一个动态的背景图

//1.游戏刚开始的阶段
            //1.1加载背景图片
            //1.1.1创建加载背景图片的对象
            var bg=new Image();
            bg.src="img/012.jpg";
            //1.1.2初始化背景图片的数据
            var BG={
                imgs:bg,
                width:480,
                height:853
            }
            //1.1.3创建背景图片的构造函数(构造出一个对象)  
            //这里使用了创建对象的第二种方法:先使用函数来定义对象,然后创建新的对象实例
            //构造函数的特点: 
//          ①构造函数的首字母必须要大写,用来区分与普通函数 
//          ②内部使用的this对象,来指向直接要生成的实例对象 
//          ③使用new来生成实例对象
            function Bg(config){//这里的config是个形参,而BG就是后面要传进来的实参;
                this.imgs=config.imgs;
                this.width=config.width;
                this.height=config.height;
                //在这里定义了两张背景图,是为了第一张背景图移动完后第二张背景图接着移动
                this.x1=0;
                this.y1=0;
                this.x2=0;
                //第二张背景图的初始高度放在背景高度(固定)的上面
                this.y2=-this.height;

                //定义背景图片绘制的方法
                this.paint=function(){
                    //分别绘制了两张背景图
                    context.drawImage(this.imgs,this.x1,this.y1);
                    context.drawImage(this.imgs,this.x2,this.y2);
                }
                //定义背景图片运动的方法
                this.step=function(){
                    //背景图片位置向下移动一个,然后利用后面的定时器让背景图动起来
                    this.y1++;
                    this.y2++;
                    //判断图片高度的临界点,只要图片一和图片二的高度等于设置的背景高度时,就让他们的纵向位置变成背景高度的上面
                    if(this.y1 == this.height){
                        this.y1=-this.height;
                    }
                    if(this.y2 == this.height){
                        this.y2=-this.height;
                    }
                }
            }
//          1.1.4创建背景图片的对象
            var sky=new Bg(BG);
//          1.2绘制游戏名
            var logo=new Image();
            logo.src="img/start.png";

点击开始时的进入游戏动画

 2第二阶段游戏加载的过程
//          2.1游戏加载时的四个图片
            var loadings = [];
            loadings[0] = new Image();
            loadings[0].src = "img/game_loading1.png";
            loadings[1] = new Image();
            loadings[1].src = "img/game_loading2.png";
            loadings[2] = new Image();
            loadings[2].src = "img/game_loading3.png";
            loadings[3] = new Image();
            loadings[3].src = "img/game_loading4.png";
//          2.2初始化图片数据
            var LOADING={
                imges:loadings,
                length:loadings.length,
                width:186,
                height:38
            }
//          2.3写构造函数
            function Loading(config){
                this.imges=config.imges;
                this.length=config.length;
                this.width=config.width;
                this.height=config.height;
//              定义索引,判断要显示的图片是哪个
                this.startIndex=0;
//              定义绘制方法
                this.paint=function(){
                    context.drawImage(this.imges[this.startIndex],0,HEIGHT-this.height)
                }
                //定义游戏加载时的图片切换速度初始值
                this.time=0;
                //定义游戏加载时图片动态效果(其实是图片切换)的方法
                this.step=function(){
                    this.time++;
                    //设置4步切换一张图
                    if(this.time % 4 == 0){
                        this.startIndex++;
                    }
                    if(this.startIndex == this.length){
                        state = RUNNING;
                    }
                }
            }
            //创建游戏加载(第二阶段)的对象
            var loading=new Loading(LOADING);
            //获取鼠标点击事件
           canvas.onclick = function(){
				console.log(111);
				if(state == START){
					state = STARTING;
				}
			}

我方飞机与子弹

  var heros=[];
            heros[0]=new Image();
            heros[0].src="img/hero1.png";
            heros[1]=new Image();
            heros[1].src="img/hero1.png";
            heros[2]=new Image();
            heros[2].src="img/hero_blowup_n4.png";
        初始化图片数据
            var HEROS={
                imgs:heros,
                length:heros.length,
                width:99,
                height:124,
                frame:2             
            }
//          3.1.3构造我方飞机的函数
            function Hero(config){
                this.imgs=config.imgs;
                this.length=config.length;
                this.width=config.width;
                this.height=config.height;
                this.frame=config.frame;
                this.startIndex=0;
                this.x=WIDTH / 2 - this.width / 2;
                this.y=HEIGHT - this.height;
                this.down=false;
                this.candel=false;
                this.paint=function(){
                    context.drawImage(this.imgs[this.startIndex],this.x,this.y)
                }
//              定义我方飞机运动的方法
                this.step=function(){
                    if(!this.down){//表示飞机正常状态,此时只有两张图进行切换
                        if(this.startIndex == 0){
                            this.startIndex=1;
                        }
                        else{
                            this.startIndex=0;
                        }
                    }
                    else{//爆炸状态
                        this.startIndex++;//爆炸状态的图片持续增加
                        if(this.startIndex == this.length){//判断图片是最后一张的时候
                            life--;//我方飞机爆炸完后,生命值减一
                            //判断生命值为0时,游戏结束
                            if(life == 0){
                                state=GAMEOVER;
                                //虽然游戏结束了但是还停留在最后一张图的状态
                                this.startIndex=this.length-1;
                            }
//                          想要开始新的生命时,直接给出创建的新的对象
                            else{
                                hero=new Hero(HEROS);
                            }
                        }
                    }
                }
//              定义我方飞机碰撞的方法
                this.bang=function(){
                    this.down=true;
                }
//              增加我方飞机射击的方法
                //定义射击速度初始值为0
                this.time=0;
                //我方飞机射击的时候,就会出现子弹,所以要调用子弹的数组中产生的子弹对象
                this.shoot=function(){
                    this.time++;
                    //每3步射击一次
                    if(this.time % 3 == 0){
                        //这里把子弹每次创建好的新的实例增加到数组的末尾
                        bullets.push(new Bullet(BULLETS))
                    }
                }
            }
            //创建我方飞机的对象实例
            var hero=new Hero(HEROS);
//绑定移动我方飞机的事件
			canvas.onmousemove = function(event){
				 var event=event || window.event;
				if(state == RUNNING){
					var x = event.offsetX;
					var y = event.offsetY;
					//修改我方飞机的坐标值
					hero.x = x - hero.width/2; 
					hero.y = y - hero.height/2;
				}
			}
//          创建子弹
            var bullet=new Image();
            bullet.src="img/bullet111.png";
            var BULLETS={
                imgs:bullet,
                width:9,
                height:21
            }
//子弹的构造函数
            function Bullet(config){
                this.imgs=config.imgs;
                this.width=config.width;
                this.height=config.height;
//              定义子弹的坐标
                this.x=hero.x + hero.width / 2-this.width / 2 ;
                this.y=hero.y - this.height;
                this.paint=function(){
                   // context.drawImage(this.imgs,this.x-15,this.y)
                    context.drawImage(this.imgs,this.x+3,this.y)    
                };
                this.step=function (){
                    this.y-=10;
                };
//              定义子弹碰撞属性    ,false表示没有碰撞            
                this.candel=false;
//              定义子弹碰撞方法,碰撞之后他的碰撞属性为true
                this.bang=function(){
                    this.candel=true;
                }
            }
//          让所有new的子弹对象放到一个数组中
            var bullets=[];
//          通过遍历绘制子弹;最后在定时器中调用
            function bulletdPaint(){
                for(var i=0;i<bullets.length;i++){
                    //调用数组对象中的方法paint()
                    bullets[i].paint();
                }
            }
//      通过遍历调用子弹的运动;
            function bulletdStep(){
                for(var i=0;i<bullets.length;i++){
                    bullets[i].step();
                }
            }
//         增加子弹的删除函数
            function bulletDel(){
                for(var i=0;i<bullets.length;i++){
                    if(bullets[i].candel  || bullets[i].y < -bullets[i].height){
                        //调用数组中的方法
                        bullets.splice(i,1)
                    }
                }
            }

敌方飞机

 var enemy1=[];//小飞机
            enemy1[0]=new Image();
            enemy1[0].src="img/enemy1.png";
            enemy1[1]=new Image();
            enemy1[1].src='img/enemy1_down1.png';
            enemy1[2]=new Image();
            enemy1[2].src='img/enemy1_down2.png';
            enemy1[3]=new Image();
            enemy1[3].src='img/enemy1_down3.png';
            enemy1[4]=new Image();
            enemy1[4].src='img/enemy1_down4.png';
            var enemy2=[];//中飞机
            enemy2[0]=new Image();
            enemy2[0].src="img/enemy2.png";
            enemy2[1]=new Image();
            enemy2[1].src="img/enemy2_down1.png";
            enemy2[2]=new Image();
            enemy2[2].src="img/enemy2_down2.png";
            enemy2[3]=new Image();
            enemy2[3].src="img/enemy2_down3.png";
            enemy2[4]=new Image();
            enemy2[4].src="img/enemy2_down4.png";
            var enemy3 = [];    //大飞机
            enemy3[0] = new Image();
            enemy3[0].src = "img/enemy3_n1.png"
            enemy3[1] = new Image();
            enemy3[1].src = "img/enemy3_n2.png"
            enemy3[2] = new Image();
            enemy3[2].src = "img/enemy3_down1.png"
            enemy3[3] = new Image();
            enemy3[3].src = "img/enemy3_down2.png"
            enemy3[4] = new Image();
            enemy3[4].src = "img/enemy3_down3.png"
            enemy3[5] = new Image();
            enemy3[5].src = "img/enemy3_down4.png"
            enemy3[6] = new Image();
            enemy3[6].src = "img/enemy3_down5.png"
            enemy3[7] = new Image();
            enemy3[7].src = "img/enemy3_down6.png"
//         敌方飞机的初始化数据
            var ENEMY1={
                imgs:enemy1,
                length:enemy1.length,
                width:57,
                height:51,
                type:1,
                frame:1,
                life:1,
                score:1
            }
            var ENEMY2={
                imgs:enemy2,
                length:enemy2.length,
                width:69,
                height:95,
                type:2,
                frame:1,
                life:5,
                score:5
            }
            var ENEMY3={
                imgs:enemy3,
                length:enemy3.length,
                width:165,
                height:261,
                type:3,
                frame:2,
                life:15,
                score:20
            }
//         敌方飞机的构造函数
            function Enemy(config){
                this.imgs=config.imgs;
                this.length=config.length;
                this.width=config.width;
                this.height=config.height;
                this.type=config.type;
                this.frame=config.frame;
                this.life=config.life;
                this.score=config.score;
//              定义敌方飞机的坐标
                this.x=Math.random()*(WIDTH-this.width);
                this.y=-this.height;
                //定义下标
                this.startIndex=0;
                //定义碰撞属性,没有碰撞为false
                this.down=false;
                //定义是否爆炸完成的属性
                this.candel=false;
                //定义绘制方法
                this.paint=function(){
                    context.drawImage(this.imgs[this.startIndex],this.x,this.y);
                };
                //定义运动方法
                this.step = function(){
                    if(!this.down){  
//                      大飞机的下标是在0和1之间进行切换
                        this.startIndex ++;
                        this.startIndex = this.startIndex % this.frame;
                        this.y += 2;
                    }
                    else{          //飞机发生碰撞以后
                        this.startIndex ++;
                        if(this.startIndex == this.length){
                            this.candel = true;
                            this.startIndex = this.length - 1;
                        }
                    }
                }
                //是否被碰撞的方法
                this.checkHit=function(wo){//判断四个边
                    return wo.y + wo.height > this.y 
                           && wo.x + wo.width > this.x
                           && wo.y < this.y + this.height
                           && wo.x < this.x + this.width;       
                }
                //敌方飞机碰撞以后的方法
                this.bang=function(){
                    this.life--;
                    if(this.life == 0){
                        this.down=true;
                        score +=this.score;
                        document.getElementById("score02").innerHTML=score;
                    }
                }
            }
//  创建数组存放敌方飞机
            var enemise=[];
//   创建函数,往数组中添加数据
            function enterEnemise(){
                //定义一个变量存放随机数
                var rand=Math.floor(Math.random()*100)
                if(rand < 10){
                    //添加小飞机
                    enemise.push(new Enemy(ENEMY1));
                }else if(rand < 55 && rand > 50){
                    //添加中飞机
                    enemise.push(new Enemy(ENEMY2));
                }else if(rand == 88){
                    //添加大飞机
                    //大飞机尤其只有一个
                    //并且把大飞机放在数组的第一位
                    if(enemise[0].type != 3  && enemise.length > 0){
                        enemise.splice(0,0,new Enemy(ENEMY3));
                    }
                }
            }
创建函数绘制敌方飞机(因为敌方飞机在数组中,所以要循环遍历画出)
            function enemyPaint(){
                for(var i=0;i<enemise.length;i++){
                    enemise[i].paint();
                }
            }
//         创建函数敌方飞机的运动
            function enemyStep(){
                for(var i=0;i<enemise.length;i++){
                    enemise[i].step();
                }
            }
//          创建函数删除敌方飞机
            function delenemy(){
                for(var i=0;i<enemise.length;i++){
                    if(enemise[i].y > HEIGHT || enemise[i].candel){
                        enemise.splice(i,1)
                    }
                }
            }
// 绘制碰撞以后的函数
            function hitEnemise(){
                for(var i = 0;i< enemise.length;i++){
//                  如果我方飞机撞到了敌方飞机以后
                    if(enemise[i].checkHit(hero)){
                        enemise[i].bang();
                        hero.bang()
                    }
//                  子弹如果碰到敌方飞机以后
                    for(var j = 0;j<bullets.length;j++){
                        if(enemise[i].checkHit(bullets[j])){
                            enemise[i].bang();
                            bullets[j].bang();
                        }
                    }
                }
            }
//       分数和生命值
            function scoreText(){
                context.font="30px bold"
                context.fillText("score:"+score,10,30)
                context.fillText("life:"+life,300,30)
            }

游戏暂停与结束

            //调用画布的鼠标移出事件,改变状态
            canvas.οnmοuseοut=function(){
                if(state == RUNNING){
                    state = PAUSE;
                }
            }
            canvas.οnmοuseοver=function(){
                if(state == PAUSE){
                    state = RUNNING;
                }
            }
        暂停图片
            var pause=new Image()
            pause.src="img/game_pause_nor.png"
//        游戏结束
            function gameover(){
                context.font="50px bold"
                context.fillText("GAME OVER !!!",80,300)
            }

定时器调用方法

 setInterval(function(){
                //背景图片无论在哪个状态都有背景图片以及它的动态效果
                sky.paint();
                sky.step();
                if(state==START){//第一阶段
                    context.drawImage(logo,35,0);
                    document.getElementById("game_over").style.display="none";
                }else if(state == STARTING){//第二阶段
                    loading.paint();
                    loading.step();
                }else if(state == RUNNING){//第三状态
                    //绘制我放飞机
                    hero.paint();
                    //我方飞机的运动
                    hero.step();
//                  我方飞机的射击方法
                    hero.shoot();
                    //子弹的绘制
                    bulletdPaint();
                    //子弹的运动
                    bulletdStep();
                    //子弹的删除
                    bulletDel();
                    //创建敌方飞机
                    enterEnemise()
                    //绘制敌方飞机
                    enemyPaint();
                    //绘制敌方飞机的运动
                    enemyStep();
                    //删除敌方飞机
                    delenemy();
                    //判断是否撞击
                    hitEnemise();
                    //绘制分数和生命值
                    scoreText()
                }else if(state == PAUSE){
                    sky.paint();
                    sky.step();
                    hero.paint();
                    bulletdPaint();
                    enemyPaint();
                    scoreText()
                    context.drawImage(pause,220,300)
                }else if(state == GAMEOVER){
                    sky.paint();
                    sky.step();
                    hero.paint();
                    bulletdPaint();
                    enemyPaint();
                    scoreText();
                    gameover();
			document.getElementById("game_over").style.display="block";	}   
            },50)

开始界面

在这里插入图片描述
游戏中与敌方飞机大战的界面
在这里插入图片描述
游戏结束时嘲讽重开界面~~

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值