ActionScript
TypeScript
JavaScript

一、新建TS项目,让背景滚动起来

发布时间:2016-05-14

 

还记得当年微信小游戏《飞机大战》吧,无需下载即可在微信直接玩,并且还能分享自己的排名,无数人为之疯狂,这是html5游戏的传播魅力。本着向经典致敬的理想,本周我将演示如何使用LayaAir快速开发,重现经典游戏。先声明一下:游戏内资源全部为原开发者所有,本例只做研究学习之用,源码和资源请勿商用。

游戏试玩地址: http://layabox.github.io/layaair-examples/

试玩.png

 

新建LayaAir项目

打开LayaAirIDE,新建一个空项目,项目名称为 AirWar,本例以 TypeScript 语言为版本,其他语言同理。

如何用LayaAirIDE创建项目及环境配置,面前章节已经讲过,这里就不再絮讲。不了解的同学建议先看一下。

图片1.png 

 高楼大厦始于足下,凡事总有一个开始,从简到难,我们先从显示游戏背景开始。

显示游戏背景

打开生成的项目,将游戏背景图放到项目的输出目录bin目录下的 res 文件夹内。新建了一个Game类,目录结构如下,下面就把这个背景显示出来。

图片1.png 

 

        修改index.html文件,引入 game.js 文件。

        打开Game.ts,书写游戏逻辑代码,显示游戏背景。

 /**
 * Game
 */
class Game {
    constructor() {
        //初始化引擎,设置游戏设计宽高
        Laya.init(480,852)
        
        //创建一个精灵
        var bg:Laya.Sprite = new Laya.Sprite();
        //加载并显示背景图
        bg.loadImage("res/background.png");
        //把这个精灵添加到舞台
        Laya.stage.addChild(bg);
    }
}
 
//启动游戏
new Game();


 

        点击图片1.png快捷使用快捷键F5编译,显示效果如下:

        图片1.png 

 

重新看看上述代码:

Laya.init(480,852) 引擎初始化,使用引擎之前,必须先初始化,并设置游戏宽高。这里需要注意,引擎默认使用Canvas渲染,如果想用WebGL渲染,可以这样写Laya.init(480,852,Laya.WebGL),这样就会优先用WebGL渲染,如果WebGL不可用,还是会用Canvas渲染。(记得引用laya.webgl.js)

var bg:Laya.Sprite = new Laya.Sprite(); 创建一个精灵(Sprite),精灵是Laya最常见对象,他既可作为一个显示对象显示出来,比如显示一个图片,显示一个矩形,还可以作为容器,添加别的精灵到他内部,只要把精灵各种API了解清楚,LayaAir引擎你已经学会一半了o(^▽^)o。

bg.loadImage("res/background.png"); 调用了精灵类的loadImage方法,让他加载并显示一个图片,这里是加载并显示背景图片。

Laya.stage.addChild(bg); 精灵要想显示出来,必须添加到舞台上,这里就是把他添加到舞台容器里面,让他在舞台上显示。

这些代码是很容易理解和学习吧。LayaAir API设计以精简为准则,简单易学。

让背景滚动

实际游戏中,仅仅显示一个图片是不够的,现在要实现让背景图片循环滚动效果,通过精灵的。实现思路:创建两个精灵,拼接一起,放到一个容器里面,让容器滚动,并在合适的时候上下交替精灵,实现滚动效果。下面对代码进行改进如下:

/**
* Game
*/
class Game {
 
    //定义背景容器
    private box: Laya.Sprite;
    //定义背景1
    private bg1: Laya.Sprite;
    //定义背景2
    private bg2: Laya.Sprite;
 
    constructor() {
        //初始化引擎,设置游戏设计宽高
        Laya.init(480, 852);
 
        //创建一个容器
        this.box = new Laya.Sprite();
        //把容器添加到舞台
        Laya.stage.addChild(this.box);
 
        //创建背景1
        this.bg1 = new Laya.Sprite();
        //加载并显示背景图
        this.bg1.loadImage("res/background.png");
        //把背景1放到容器内
        this.box.addChild(this.bg1);
 
        //创建背景2
        this.bg2 = new Laya.Sprite();
        //加载并显示背景图
        this.bg2.loadImage("res/background.png");
        //更改背景2,放到背景1上面
        this.bg2.pos(0, -852)
        //把背景2放到容器内
        this.box.addChild(this.bg2);
 
        //创建一个帧循环,更新容器位置
        Laya.timer.frameLoop(1, this, this.onLoop)
    }
 
    onLoop(): void {
        //背景容器每帧向下移动1像素
        this.box.y += 1;
 
        //如果背景图到了下面不可见,立即调整位置到上面循环显示
        if (this.bg1.y + this.box.y >= 852) {
            this.bg1.y -= 852 * 2;
        }
        if (this.bg2.y + this.box.y >= 852) {
            this.bg2.y -= 852 * 2;
        }
    }
}
 
//启动游戏
new Game();


其中private box: Laya.Sprite;是定义了一个容器,容器是全局的,方便下面函数访问,容器内部添加两个背景图片精灵,交替显示。

Laya.timer.frameLoop(1, this, this.onLoop)创建了一个循环,基于帧率,间隔是1帧,就是每间隔一帧就会待用一次onLoop函数,在onLoop函数内,更新box容器的位置,并且在背景无法看到的时候,移动到上面。


点击图片1.png快捷使用快捷键F5编译,就会发现背景动了起来,并且是循环滚动效果。

图片1.png 

 

到此,我们要的结果就实现了,是不是很简单。但是目前所有代码都在Game类的构造函数内,如果代码越来越多,维护越来越困难,这时就需要把一部分逻辑封装到一个新类里面,每个类做一部分事情。下面增加一个新的BackGround类,封装上面的逻辑。

BackGround

/**
 * 循环滚动的游戏背景
 */
class BackGround extends Laya.Sprite {
    //定义背景1
    private bg1: Laya.Sprite;
    //定义背景2
    private bg2: Laya.Sprite;
 
    constructor() {
        super();
        this.init();
    }
 
    init(): void {
        //创建背景1
        this.bg1 = new Laya.Sprite();
        //加载并显示背景图
        this.bg1.loadImage("res/background.png");
        //把背景1放到容器内
        this.addChild(this.bg1);
 
        //创建背景2
        this.bg2 = new Laya.Sprite();
        //加载并显示背景图
        this.bg2.loadImage("res/background.png");
        //更改背景2,放到背景1上面
        this.bg2.pos(0, -852)
        //把背景2放到容器内
        this.addChild(this.bg2);
 
        //创建一个帧循环,更新容器位置
        Laya.timer.frameLoop(1, this, this.onLoop)
    }
 
    onLoop(): void {
        //背景容器每帧向下移动1像素
        this.y += 1;
 
        //如果背景图到了下面不可见,立即调整位置到上面循环显示
        if (this.bg1.y + this.y >= 852) {
            this.bg1.y -= 852 * 2;
        }
        if (this.bg2.y + this.y >= 852) {
            this.bg2.y -= 852 * 2;
        }
    }
}

 

Game

/**
* Game
*/
class Game {
 
    constructor() {
        //初始化引擎,设置游戏设计宽高
        Laya.init(480, 852);
 
        //创建循环滚动的背景
        var bg: BackGround = new BackGround();
        //把背景添加到舞台上显示出来
        Laya.stage.addChild(bg);
    }
}
 
//启动游戏
new Game();


修改index.html页面,引入BackGround.js。

编译后,效果和上面相同。可以看出,上面Game类里面的代码就简化多了,适当的代码封装,把相同逻辑隔离,保持类的功能单一清晰,怎么封装,如何封装每个人都有自己的方式,这就是面向对象编程的魔力。

 

点击这里下载此例子的代码