ActionScript
TypeScript
JavaScript

六、子弹升级与敌军难度升级的逻辑实现

发布时间:2017-01-03


 难度升级

上节实现了飞行射击,碰撞销毁等效果,游戏的样子已经有了,但是还不够有趣,这节增加一些游戏的趣味性。

我们增加了血瓶和子弹升级道具资源,并且重新打包为图集。

图片1.png 

  在Main.as先定义子弹升级的数组,关卡属性,等级属性。

  //子弹偏移的位置
  private var bulletPos: Array = [[0], [-15, 15], [-30, 0, 30], [-45, -15, 15, 45]];
  //关卡等级
  private var level: Number= 0;
  //积分成绩
  private var score: Number= 0;
  //升级等级所需的成绩数量
  private var levelUpScore: Number= 10;
  //子弹级别
  private var bulletLevel: Number= 0;

修改Role.as 将isBullet改为heroType 在角色创建的函数中添加heroType 缓存强化道具和医疗包

  // 0:普通 1:子弹 2:强化道具 3:医疗袋
  public var heroType:Number= 0   ; 
  
  /**
   * 角色创建
   */
  public function init(type:String,hp:Number,speed:Number,hitRadius:Number,camp:Number,heroType:Number= 0):void 
  {
   //初始化属性
   this.type = type;
   this.hp = hp;
   this.speed = speed;
   this.hitRadius = hitRadius;
   this.camp = camp;
   this.heroType = heroType;
   
    //缓存强化道具
    Animation.createFrames(["war/ufo1.png"], "ufo1_fly");
    //缓存医疗包
    Animation.createFrames(["war/ufo2.png"], "ufo2_fly");


子弹升级

设计目标:击毁boss飞机,有机会获得子弹升级道具,积攒后可以提高子弹发射数量,提高发射速度,提高飞行速度。

 Main.as里面,修改了子弹发射相关代码。

//获取子弹数组
     var pos: Array = bulletPos[role.shootType - 1];
     //根据当前的子弹等级生成子弹
                    for (var index: int = 0; index < pos.length; index++) {
                        //从对象池里面创建一个子弹
                        var bullet: Role = Pool.getItemByClass("role", Role);
                        //初始化子弹信息,根据不同子弹类型,设置不同的飞行速度
                        bullet.init("bullet1", 1,-5, 1, 0, 1);
                        //设置子弹发射初始化位置
                        bullet.pos(role.x + pos[index], role.y - role.hitRadius - 10);
                        //添加到舞台上
                        Laya.stage.addChild(bullet);
      }

 

修改lostHp掉血代码,增加打死boss掉血瓶和子弹升级道具的逻辑

//击落boss掉落补给品
      if (role.type == "enemy3") {
                    //随机是子弹升级道具还是血瓶
                    var type: Number = Math.random() < 0.7 ? 2 : 3;
                    //掉落血瓶或者加速器                     
                    var item: Role = Pool.getItemByClass("role", Role);
                    //初始化信息
                    item.init("ufo" + (type - 1),1, 0, 15, 1, type);
                    //初始化位置
                    item.pos(role.x, role.y);
                    //添加到舞台上
                    Laya.stage.addChild(item);

 

自机碰撞吃子弹升级道具和血瓶逻辑。

  /**
   * 强化自机逻辑
   * @param 强化类型
   */
  private function PowerUp(role:Role):void 
  {
   if (role.heroType === 1){
    //如果是子弹隐藏 下一帧回收
    role.visible = false;
    role.hp = 0;
   }
   if (role.heroType === 2){
    //每吃一个子弹升级道具,子弹升级+1
    this.bulletLevel++;
    //子弹每升2级,子弹数量增加1,最大数量限制在4个
    this.hero.shootType = Math.min(Math.floor(this.bulletLevel / 2) + 1,4);
    //子弹级别越高,发射频率越快
    this.hero.shootInterval = 500 - 20 * (this.bulletLevel > 20 ? 20 : this.bulletLevel);
    //隐藏道具并回收
    role.visible = false;
    role.hp = 0;
   }else if (role.heroType === 3){
    //每吃一个血瓶,血量增加1
    this.hero.hp += 1;
    //设置最大血量不超过10
    if (this.hero.hp > 10) this.hero.hp = 10;
    //隐藏道具并回收
    role.visible = false;
    role.hp = 0;
   }
  }


修改碰撞逻辑,自机碰撞强化道具或血瓶不掉血

if (role1.heroType === 2 || role1.heroType === 3 || role2.heroType === 2 || role2.heroType === 3){
          //英雄或子弹碰撞强化道具强化
          this.PowerUp(role1);
          this.PowerUp(role2);
         }else{
         this.LostHp(role1, 1);
         this.LostHp(role2, 1);
         }


敌人升级

设计目标:增加积分属性,增加关卡等级,积累积分,则关卡等级提升,关卡越高,敌人数量越多,速度越快,血量越高。

修改Main.as 添加属性

  //刷新加速
  private var cutTime:Number = 0;
  //速度提升
  private var speedUp:Number = 0;
  //血量提升   
  private var hpUp:Number = 0;
  //数量提升      
  private var numUp:Number = 0;
  
  //敌机血量表
  private var hps: Array = [1, 2, 10];
  //敌机速度表
  private var speeds: Array = [3, 2, 1];
  //敌机被击半径表
  private var radius: Array = [15, 30, 80];
  //敌机生成数量表
  private var nums:Array = [2, 1, 1];

 

修改敌机出现逻辑。

 if (Math.abs(role1.x - role2.x) < Radius && Math.abs(role1.y - role2.y)  levelUpScore) {
       //升级关卡
       level++;
       //关卡越高,创建敌机间隔越短
       cutTime = this.level < 30 ? this.level * 2 : 60;
       //关卡越高,敌机飞行速度越高
       speedUp = Math.floor(this.level / 6);
       //关卡越高,敌机血量越高
       hpUp = Math.floor(this.level / 8);
       //关卡越高,敌机数量越多
       numUp = Math.floor(this.level / 10);
       //提高下一级的升级分数
       levelUpScore += level * 10;
       }
       
          //生成小飞机
   if (Laya.timer.currFrame % (80 - cutTime) === 0) {
    createEnemy(0, nums[0] + numUp, hps[0],speeds[0] + speedUp , radius[0]);
   }
  
   //生成中型飞机
   if (Laya.timer.currFrame % (170 - cutTime * 2) === 0) {
    createEnemy(1, nums[1] + numUp, hps[1] + hpUp * 2,speeds[1] + speedUp , radius[1]);
   }
  
   //生成boss
   if (Laya.timer.currFrame % (1000 - cutTime * 3) === 0) {
    createEnemy(2, nums[2], hps[2] + hpUp * 6,speeds[2]  , radius[2]);
   }


最后我们看看效果:

图片1.png 

Main.as代码

package 
{
	import laya.events.Event;
	import laya.net.Loader;
	import laya.utils.Browser;
	import laya.utils.Handler;
	import laya.utils.Pool;
	import laya.utils.Stat;
	/**
	 * ...
	 * @author ssq
	 */
	public class Main 
	{
		//刷新加速
		private var cutTime:Number = 0;
		//速度提升
		private var speedUp:Number = 0;
		//血量提升			
		private var hpUp:Number = 0;
		//数量提升						
		private var numUp:Number = 0;
		
		//敌机血量表
		private var hps: Array = [1, 2, 10];
		//敌机速度表
		private var speeds: Array = [3, 2, 1];
		//敌机被击半径表
		private var radius: Array = [15, 30, 80];
		//敌机生成数量表
		private var nums:Array = [2, 1, 1];
		
		//定义主角(主战斗机)
		private var hero:Role;
		//子弹偏移的位置
		private var bulletPos: Array = [[0], [-15, 15], [-30, 0, 30], [-45, -15, 15, 45]];
		//关卡等级
		private var level: Number = 0;
		//积分成绩
		private var score: Number = 0;
		//升级等级所需的成绩数量
		private var levelUpScore: Number = 10;
		//子弹级别
		private var bulletLevel: Number = 0;
		
		public function Main() 
		{
			//初始化引擎
			Laya.init(480,852);
			//创建滚动的背景
			var bg:BackGround = new BackGround();
			//将背景添加到舞台上
			Laya.stage.addChild(bg);
			//加载图集资源
			Laya.loader.load("res/atlas/war.json", Handler.create(this, this.onload), null, Loader.ATLAS);
			//显示FPS
			Stat.show();
		}
		
		private function onload():void 
		{
			//创建控制的飞机 
			hero = new Role();
			//设置飞机的位置
			hero.pos(240, 700);
			 //初始化角色
			hero.init("hero", 1, 0, 30, 0);
			//更改为射击状态
			hero.shootType = 1;
			//将飞机加入到舞台上
			Laya.stage.addChild(hero);
			//添加鼠标事件
			Laya.stage.on(Event.MOUSE_MOVE, this, onMouseMove);
			//创建主循环
			Laya.timer.frameLoop(1, this, this.onLoop)
		}
		/**
		 * 程序主循环
		 */
		private function onLoop():void 
		{
			//遍历所有飞机,更改飞机状态
			for (var i: int = Laya.stage.numChildren - 1; i > -1; i--) {
				var role: Role = Laya.stage.getChildAt(i) as Role;
				if (role && role.speed) {
					//根据飞机速度更改位置
					role.y += role.speed;
					//如果敌人移动到显示区域以外||飞机&子弹被隐藏||子弹移动到显示区域外
				if (role.y > 1000 || !role.visible || (role.heroType === 1 && role.y  0){
				//获取当前时间
				var time:Number = Browser.now() ;
				//如果当前时间大于下次射击时间
				if (time > role.shootTime){
					//更新下次子弹射击的时间
					role.shootTime = time + role.shootInterval ;
					//获取子弹数组
					var pos: Array = bulletPos[role.shootType - 1];
					//根据当前的子弹等级生成子弹
                    for (var index: int = 0; index < pos.length; index++) {
                        //从对象池里面创建一个子弹
                        var bullet: Role = Pool.getItemByClass("role", Role);
                        //初始化子弹信息,根据不同子弹类型,设置不同的飞行速度
                        bullet.init("bullet1", 1,-5, 1, 0, 1);
                        //设置子弹发射初始化位置
                        bullet.pos(role.x + pos[index], role.y - role.hitRadius - 10);
                        //添加到舞台上
                        Laya.stage.addChild(bullet);
						}
					}
				}
			}

blob.png 

                                     }
						}
					}
				}
			//如果主角死亡,则停止游戏循环
			if (hero.hp > 20 ? 20 : this.bulletLevel);
				//隐藏道具并回收
				role.visible = false;
				role.hp = 0;
			}else if (role.heroType === 3){
				//每吃一个血瓶,血量增加1
				this.hero.hp += 1;
				//设置最大血量不超过10
				if (this.hero.hp > 10) this.hero.hp = 10;
				//隐藏道具并回收
				role.visible = false;
				role.hp = 0;
			}
		}
		
		/**
		 * 掉血逻辑函数
		 * @param	掉血角色
		 * @param	失去生命
		 */
		private function LostHp(role:Role, lostHp:Number):void 
		{
			//减血
			role.hp -= lostHp;
			if (role.hp > 0) {
				//如果未死亡,则播放受击动画
				role.playAction("hit");
			} else {
				//如果死亡,则播放爆炸动画
				if (role.heroType === 1) {
					//如果是子弹,则直接隐藏,下次回收
					role.visible = false;
				} else {
					role.playAction("down");
					//击落boss掉落补给品
					 if (role.type == "enemy3") {
                    //随机是子弹升级道具还是血瓶
                    var type: Number = Math.random() < 0.7 ? 2 : 3;
                    //掉落血瓶或者加速器                     
                    var item: Role = Pool.getItemByClass("role", Role);
                    //初始化信息
                    item.init("ufo" + (type - 1),1, 0, 15, 1, type);
                    //初始化位置
                    item.pos(role.x, role.y);
                    //添加到舞台上
                    Laya.stage.addChild(item);
					}
				}
			}
		}
		
		
		/**
		 * 鼠标移动控制飞机函数
		 * @param	e
		 */
		private function onMouseMove(e:Event):void 
		{
			//飞机跟随鼠标移动
			hero.pos(Laya.stage.mouseX, Laya.stage.mouseY);
		}
		
		
		/**
		 * 敌人生成函数
		 * @param	生成数量
		 */
		private function createEnemy(type:Number,number:Number,hp:Number,speed:Number,radius:Number):void 
		{
			for (var i: int = 0; i < number; i++) {
				//创建敌人,从对象池创建
				var enemy: Role = Pool.getItemByClass("role", Role);
				//初始化角色
				enemy.init("enemy" + (type + 1), hp, speed ,radius, 1);
				//随机位置
				enemy.pos(Math.random() * 400 + 40, -Math.random() * 200- 100);
				//添加到舞台上
				Laya.stage.addChild(enemy);
			}
		}
		
	}
}

Role.as代码如下

package 
{
 import laya.display.Animation;
 import laya.display.Sprite;
 import laya.maths.Rectangle;
 import laya.utils.Browser;
 

 public class Role extends Sprite 
 {
  private static var cacheAs:Boolean = false;
  //定义飞机的身体
  private var body:Animation;  
  //飞机的类型
  public var type:String;
  //飞机的血量
  public var hp:Number ; 
  //飞机的速度
  public var speed:Number;
  //飞机的攻击半径
  public var hitRadius:Number;
  //飞机的阵容
  public var camp:Number;
  
  //射击类型 
  public var shootType: Number = 0;
  //射击间隔
  public var shootInterval: Number = 500;
  //下次射击时间
  public var shootTime: Number = Browser.now() + 2000;
  //当前动作
  public var action:String;
  // 0:普通 1:子弹 2:强化道具 3:医疗袋
  public var heroType:Number = 0   ; 
  
  /**
   * 角色创建
   */
  public function init(type:String,hp:Number,speed:Number,hitRadius:Number,camp:Number,heroType:Number = 0):void 
  {
   //初始化属性
   this.type = type;
   this.hp = hp;
   this.speed = speed;
   this.hitRadius = hitRadius;
   this.camp = camp;
   this.heroType = heroType;
   
   if(!Role.cacheAs)
   {
    Role.cacheAs = true;
    //缓存飞机飞行动画
    Animation.createFrames(["war/hero_fly1.png", "war/hero_fly2.png"], "hero_fly");
    //缓存飞机死亡动画
    Animation.createFrames(["war/hero_down1.png", "war/hero_down2.png", "war/hero_down3.png", "war/hero_down4.png"], "hero_down");
    //缓存敌机1飞行动画
    Animation.createFrames(["war/enemy1_fly1.png"], "enemy1_fly");
    //缓存飞机1死亡动画
    Animation.createFrames(["war/enemy1_down1.png", "war/enemy1_down2.png", "war/enemy1_down3.png", "war/enemy1_down4.png"], "enemy1_down");
    //缓存敌机2飞行动画
    Animation.createFrames(["war/enemy2_fly1.png"], "enemy2_fly");
    //缓存飞机2死亡动画
    Animation.createFrames(["war/enemy2_down1.png", "war/enemy2_down2.png", "war/enemy2_down3.png", "war/enemy2_down4.png"], "enemy2_down");
    //缓存飞机2击中动画
    Animation.createFrames(["war/enemy2_hit.png"], "enemy2_hit");
    //缓存敌机3飞行动画
    Animation.createFrames(["war/enemy3_fly1.png"], "enemy3_fly");
    //缓存飞机3死亡动画
    Animation.createFrames(["war/enemy3_down1.png", "war/enemy3_down2.png", "war/enemy3_down3.png", "war/enemy3_down4.png"], "enemy3_down");
    //缓存飞机3击中动画
    Animation.createFrames(["war/enemy3_hit.png"], "enemy3_hit");
    //缓存子弹动画
    Animation.createFrames(["war/bullet1.png"], "bullet1_fly");
    //缓存强化道具
    Animation.createFrames(["war/ufo1.png"], "ufo1_fly");
    //缓存医疗包
    Animation.createFrames(["war/ufo2.png"], "ufo2_fly");
   
   }
   if (!body){
    //创建动画作为飞机的身体
    body = new Animation();
    //动画播放时间间隔
    body.interval = 50;
    //将动画加入到容器中
    this.addChild(body);
     //增加动画播放完成监听
    body.on("complete", this, this.onPlayComplete);
   }
   //播放当前状态的动画
   this.playAction("fly");
  }
  /**
   * 动画监听函数
   */
  private function onPlayComplete():void 
  {
   if (this.action === "down"){
    //停止播放动画
    body.stop();
    //隐藏死亡的飞机,下一帧回收
    this.visible = false;
   }else if (this.action === "hit"){
    this.playAction("fly");
   }
  }
  /**
   * 动画播放函数
   * @param 当前状态
   */
  public function playAction(action:String):void 
  {
   //记录当前的状态
   this.action = action;
   //根据类型播放动画
   body.play(0, true,type + "_" + action);
   //获取动画大小区域
   var bound: Rectangle = this.body.getBounds();
   //设置机身剧中
   body.pos(-bound.width / 2, -bound.height / 2);
  }
 
 }

}

游戏到目前为止,已经有趣味性了,但是还有很多其他功能可以添加,比如增加不同轨迹的子弹,增加跟踪弹,增加敌机反击等,我在此不再过多的深入,更多有趣功能留给开发者自己去尝试。

 

本节课程源码下载