ActionScript
TypeScript
JavaScript

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

发布时间:2016-05-14

 

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

Role.ts类更改如下:

/**
 * 角色类
 */
class Role extends Laya.Sprite {
    //是否缓存了动画
    private static cached: boolean = false;
    //定义飞机的身体
    private body: Laya.Animation;
    //定义飞机类型
    private type: string;
    //阵营,0:我方,1:敌方
    public camp: number;
    //血量
    public hp: number;
    //飞行速度
    public speed: number;
    //攻击半径
    public hitRadius: number;
 
    constructor() {
        super();
    }
 
    public init(type: string, camp: number, hp: number, speed: number, hitRadius: number): void {
        //初始化角色属性
        this.type = type;
        this.camp = camp;
        this.hp = hp;
        this.speed = speed;
        this.hitRadius = hitRadius;
 
        //缓存公用动画模板,减少对象创建开销
        if (!Role.cached) {
            Role.cached = true;
            //缓存hero_fly动画
            Laya.Animation.createFrames(["war/hero_fly1.png", "war/hero_fly2.png"], "hero_fly");
            //缓存hero_down动画
            Laya.Animation.createFrames(["war/hero_down1.png", "war/hero_down2.png", "war/hero_down3.png", "war/hero_down4.png"], "hero_down");
 
            //缓存enemy1_fly动画
            Laya.Animation.createFrames(["war/enemy1_fly1.png"], "enemy1_fly");
            //缓存enemy1_down动画
            Laya.Animation.createFrames(["war/enemy1_down1.png", "war/enemy1_down2.png", "war/enemy1_down3.png", "war/enemy1_down4.png"], "enemy1_down");
 
            //缓存enemy2_fly动画
            Laya.Animation.createFrames(["war/enemy2_fly1.png"], "enemy2_fly");
            //缓存enemy2_down动画
            Laya.Animation.createFrames(["war/enemy2_down1.png", "war/enemy2_down2.png", "war/enemy2_down3.png", "war/enemy2_down4.png"], "enemy2_down");
            //缓存enemy2_hit动画
            Laya.Animation.createFrames(["war/enemy2_hit.png"], "enemy2_hit");
 
            //缓存enemy3_fly动画
            Laya.Animation.createFrames(["war/enemy3_fly1.png", "war/enemy3_fly2.png"], "enemy3_fly");
            //缓存enemy3_down动画
            Laya.Animation.createFrames(["war/enemy3_down1.png", "war/enemy3_down2.png", "war/enemy3_down3.png", "war/enemy3_down4.png", "war/enemy3_down5.png", "war/enemy3_down6.png"], "enemy3_down");
            //缓存enemy3_hit动画
            Laya.Animation.createFrames(["war/enemy3_hit.png"], "enemy3_hit");
        }
 
        if(!this.body){
            //创建一个动画作为飞机的身体
            this.body = new Laya.Animation();
            //把机体添加到容器内
            this.addChild(this.body);
        }
        //播放飞行动画
        this.playAction("fly");
    }
 
    playAction(action: string): void {
        //根据类型播放动画
        this.body.play(0, true, this.type + "_" + action);
        //获取动画大小区域
        var bound: Laya.Rectangle = this.body.getBounds();
        //设置机身剧中
        this.body.pos(-bound.width / 2, -bound.height / 2);
    }
}


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

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


Game类:

/**
* Game
*/
class Game {
    //定义英雄(主战斗机)
    private hero: Role
 
    constructor() {
        //初始化引擎,设置游戏设计宽高
        Laya.init(480, 852);
 
        //创建循环滚动的背景
        var bg: BackGround = new BackGround();
        //把背景添加到舞台上显示出来
        Laya.stage.addChild(bg);
 
        //加载图集资源
        Laya.loader.load("res/atlas/war.json", Laya.Handler.create(this, this.onLoaded), null, Laya.Loader.ATLAS);
    }
 
    onLoaded() {
        //创建一个主角(主战斗机)
        this.hero = new Role();
        //初始化角色
        this.hero.init("hero", 0, 1, 0, 30);
        //设置角色位置
        this.hero.pos(240, 700);
        //把主角添加到舞台上
        Laya.stage.addChild(this.hero);
 
        //监听舞台的鼠标移动事件
        Laya.stage.on("mousemove", this, this.onMouseMove);
 
        //创建敌人
        this.createEnemy(10);
    }
 
    onMouseMove(e: Laya.Event): void {
        //始终保持影响和鼠标位置一致
        this.hero.pos(Laya.stage.mouseX, Laya.stage.mouseY);
    }
 
    //敌机血量表
    private hps: Array = [1, 2, 10];
    //敌机速度表
    private speeds: Array = [3, 2, 1];
    //敌机被击半径表
    private radius: Array = [15, 30, 70];
 
    createEnemy(num: number): void {
        for (var i: number = 0; i < num; 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), 0, this.hps[type], this.speeds[type], this.radius[type]);
            //随机位置
            enemy.pos(Math.random() * 400 + 40, Math.random() * 200);
            //添加到舞台上
            Laya.stage.addChild(enemy);
        }
    }
}
 
//启动游戏
new Game();


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

图片1.png 

让敌机动起来

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

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

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


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

//创建主循环
Laya.timer.frameLoop(1, this, this.onLoop)


循环内遍历飞机,实现移动会对象回收代码如下:

onLoop(): void {
        //遍历所有飞机,更改飞机状态
        for (var i: number = Laya.stage.numChildren; i>-1;i--) {
                    //从舞台移除
                    role.removeSelf();
                    //回收到对象池
                    Laya.Pool.recover("role", role);
                }
            }
        }
        //每间隔30帧创建新的敌机
        if (Laya.timer.currFrame % 60 === 0) {
            this.createEnemy(2);
        }
    }


全部代码如下:

/**
* Game
*/
class Game {
    //定义英雄(主战斗机)
    private hero: Role
 
    constructor() {
        //初始化引擎,设置游戏设计宽高
        Laya.init(480, 852);
 
        //创建循环滚动的背景
        var bg: BackGround = new BackGround();
        //把背景添加到舞台上显示出来
        Laya.stage.addChild(bg);
 
        //加载图集资源
        Laya.loader.load("res/atlas/war.json", Laya.Handler.create(this, this.onLoaded), null, Laya.Loader.ATLAS);
        
        //显示FPS
        Laya.Stat.show();
    }
 
    onLoaded() {
        //创建一个主角(主战斗机)
        this.hero = new Role();
        //初始化角色
        this.hero.init("hero", 0, 1, 0, 30);
        //设置角色位置
        this.hero.pos(240, 700);
        //把主角添加到舞台上
        Laya.stage.addChild(this.hero);
 
        //监听舞台的鼠标移动事件
        Laya.stage.on("mousemove", this, this.onMouseMove);
 
        //创建主循环
        Laya.timer.frameLoop(1, this, this.onLoop);
    }
 
    onLoop(): void {
        //遍历所有飞机,更改飞机状态
        for (var i: number = Laya.stage.numChildren - 1; i > -1; i--) {
            var role: Role = Laya.stage.getChildAt(i) as Role;
            if (role && role.speed) {
                //根据飞机速度更改位置
                role.y += role.speed;
                console.log(role.type, role.speed);
 
                //如果敌人移动到显示区域以外,则移除
                if (role.y > 1000) {
                    //从舞台移除
                    role.removeSelf();
                    //回收到对象池
                    Laya.Pool.recover("role", role);
                }
            }
        }
        //每间隔30帧创建新的敌机
        if (Laya.timer.currFrame % 60 === 0) {
            this.createEnemy(2);
        }
    }
 
    onMouseMove(e: Laya.Event): void {
        //始终保持影响和鼠标位置一致
        this.hero.pos(Laya.stage.mouseX, Laya.stage.mouseY);
    }
 
    //敌机血量表
    private hps: Array = [1, 2, 10];
    //敌机速度表
    private speeds: Array = [3, 2, 1];
    //敌机被击半径表
    private radius: Array = [15, 30, 70];
 
    createEnemy(num: number): void {
        for (var i: number = 0; i < num; i++) {
            //随机出现敌人
            var r: number = Math.random();
 
            //根据随机数,随机敌人   
            var type: number = r < 0.7 ? 0 : r < 0.95 ? 1 : 2;
 
            //创建敌人,从对象池创建
            var enemy: Role = Laya.Pool.getItemByClass("role", Role);
            //初始化角色
            enemy.init("enemy" + (type + 1), 0, this.hps[type], this.speeds[type], this.radius[type]);
            //随机位置
            enemy.pos(Math.random() * 400 + 40, -Math.random() * 200 - 100);
            //添加到舞台上
            Laya.stage.addChild(enemy);
        }
    }
}
 
//启动游戏
new Game();


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

图片1.png 

 

本节课程源码下载