ActionScript
TypeScript
JavaScript

四、游戏中的属性增加与敌机来袭的实现

发布时间:2017-01-03

 

上节实现了飞机动画切换,鼠标跟随,这节我们来实现敌机的显示,我们增加了角色类型,阵营,血量,速度,被击半径等属性,为将来做准备。

Role.as类更改如下:

package 
{
 import laya.display.Animation;
 import laya.display.Sprite;
 import laya.maths.Rectangle;
 
 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 function init(type:String,hp:Number,speed:Number,hitRadius:Number,camp:Number):void 
  {
   //初始化属性
   this.type = type;
   this.hp = hp;
   this.speed = speed;
   this.hitRadius = hitRadius;
   this.camp = camp;
   
   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");
   
   }
   if (!body){
    //创建动画作为飞机的身体
    body = new Animation();
    //将动画加入到容器中
    this.addChild(body);
    //播放当前状态的动画
   }
   this.playAction("fly");
  }
  
  private function playAction(action:String):void 
  {
   //根据类型播放动画
   body.play(0, true,type + "_" + action);
   //获取动画大小区域
   var bound: Rectangle = this.body.getBounds();
   //设置机身剧中
   body.pos(-bound.width / 2, -bound.height / 2);
  }
 
 }

}


其中更改了init初始化函数,可以初始化血量等信息。

增加更多公用动画模板缓存,使用动画缓存能减少对象动画创建开销,如果有大量相同动画播放,请尽量使用缓存。


Main类:

package 
{
 import laya.events.Event;
 import laya.net.Loader;
 import laya.utils.Handler;

 public class Main 
 {
  //定义主角(主战斗机)
  private var hero:Role;
  
  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);
   //将飞机加入到舞台上
   Laya.stage.addChild(hero);
   //添加鼠标事件
   Laya.stage.on(Event.MOUSE_MOVE, this, onMouseMove);
   //生成敌人
   createEnemy(10);
  }
  
  
  /**
   * 鼠标移动控制飞机函数
   * @param e
   */
  private function onMouseMove(e:Event):void 
  {
   //飞机跟随鼠标移动
   hero.pos(Laya.stage.mouseX, Laya.stage.mouseY);
  }
  
  //敌机血量表
  private var hps: Array = [1, 2, 10];
  //敌机速度表
  private var speeds: Array = [3, 2, 1];
  //敌机被击半径表
  private var radius: Array = [15, 30, 70];
  /**
   * 敌人生成函数
   * @param 生成数量
   */
  private function createEnemy(number:Number):void 
  {
   for (var i: int = 0; i < number; i++) {
    //随机出现敌人
    var r: Number = Math.random();
    //根据随机数,随机敌人   
    var type: Number = r < 0.7 ? 0 : r < 0.95 ? 1 : 2;
    //创建敌人
    var enemy: Role = new Role();
    //初始化角色
    enemy.init("enemy" + (type + 1), this.hps[type], this.speeds[type] ,this.radius[type], 0);
    //随机位置
    enemy.pos(Math.random() * 400 + 40, Math.random() * 200);
    //添加到舞台上
    Laya.stage.addChild(enemy);
   }
  }
  
 }
 
 

}


其中,增加了createEnemy来创建敌人并随机位置显示,我们来看看效果。

图片1.png 

让敌机动起来

现在需要把敌机运动起来。

更改Main.ascreateEnemy,更改角色从对象池创建,这样能减少对象创建开销。

private function createEnemy(number:Number):void 
  {
   for (var i: int = 0; i < number; i++) {
    //随机出现敌人
    var r: Number = Math.random();
    //根据随机数,随机敌人   
    var type: Number = r < 0.7 ? 0 : r < 0.95 ? 1 : 2;
    //创建敌人,从对象池创建
    var enemy: Role = Pool.getItemByClass("role", Role);
    //初始化角色
    enemy.init("enemy" + (type + 1), this.hps[type], this.speeds[type] ,this.radius[type], 0);
    //随机位置
    enemy.pos(Math.random() * 400 + 40, -Math.random() * 200);
    //添加到舞台上
    Laya.stage.addChild(enemy);
   }
  }


onLoaded() 函数最后增加下面代码,增加主循环。

private function onload():void 
  {
   //创建控制的飞机 
   hero = new Role();
   //设置飞机的位置
   hero.pos(240, 700);
    //初始化角色
   hero.init("hero", 1, 0, 0, 30);
   //将飞机加入到舞台上
   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.removeSelf();
      //回收到对象池
      Pool.recover("role", role);
     }
    }
   }
   //每间隔30帧创建新的敌机
   if (Laya.timer.currFrame % 60 === 0) {
    this.createEnemy(2);
   }
  }


全部代码如下:

package 
{
 import laya.events.Event;
 import laya.net.Loader;
 import laya.utils.Handler;
 import laya.utils.Pool;

 public class Main 
 {
  //定义主角(主战斗机)
  private var hero:Role;
  
  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);
   //将飞机加入到舞台上
   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.removeSelf();
      //回收到对象池
      Pool.recover("role", role);
     }
    }
   }
   //每间隔30帧创建新的敌机
   if (Laya.timer.currFrame % 60 === 0) {
    this.createEnemy(2);
   }
  }
  
  
  /**
   * 鼠标移动控制飞机函数
   * @param e
   */
  private function onMouseMove(e:Event):void 
  {
   //飞机跟随鼠标移动
   hero.pos(Laya.stage.mouseX, Laya.stage.mouseY);
  }
  
  //敌机血量表
  private var hps: Array = [1, 2, 10];
  //敌机速度表
  private var speeds: Array = [3, 2, 1];
  //敌机被击半径表
  private var radius: Array = [15, 30, 70];
  /**
   * 敌人生成函数
   * @param 生成数量
   */
  private function createEnemy(number:Number):void 
  {
   for (var i: int = 0; i < number; i++) {
    //随机出现敌人
    var r: Number = Math.random();
    //根据随机数,随机敌人   
    var type: Number = r < 0.7 ? 0 : r < 0.95 ? 1 : 2;
    //创建敌人,从对象池创建
    var enemy: Role = Pool.getItemByClass("role", Role);
    //初始化角色
    enemy.init("enemy" + (type + 1), this.hps[type], this.speeds[type] ,this.radius[type], 0);
    //随机位置
    enemy.pos(Math.random() * 400 + 40, -Math.random() * 200);
    //添加到舞台上
    Laya.stage.addChild(enemy);
   }
  }
  
 }
}


编译后看到敌机缓缓飞来。

图片1.png 

 

本节课程源码下载