ActionScript
TypeScript
JavaScript

七、用LayaAirIDE制作游戏UI

发布时间:2017-01-03

 

游戏中,少不了UI功能,展示游戏数据信息,LayaAirIDE集成了可视化UI界面编辑工具,制作UI非常方便快捷。

实现目标:制作游戏暂停,关卡,积分,血量等UI界面。

编辑UI

点击编辑器左侧导航栏第二个,即可进入编辑页面。

blob.png 

 

右键点击项目面板,弹出菜单,选择新建页面(快捷键Ctrl+N)。

blob.png 

 

弹出新建面板,设置页面名称为“GameInfo”,点击确定。

blob.png 

 

右键选择资源面板,弹出菜单,选择“打开所在目录”。

图片1.png 

 

复制按钮等三个资源到war文件夹。

图片1.png 

 

返回到编辑器,F5刷新编辑器,可以看到刚才添加的资源,并被自动识别为button组件(组件是根据资源名称前缀识别)。

图片1.png 

 

打开刚才新建的GameInfo页面,设置宽高属性为480,852。

blob.png 

 

拖动刚添加的btn_pause到页面内,设置stateNum为1,label为空,设置var为pauseBtn,方便代码控制。

blob.png 

 

拖动三个Label组件到编辑器内,分别设置字体,颜色,分别命令var为hpLabel,levelLabel,scoreLabel。

blob.png 

blob.png

 

在拖动一个Label到舞台,设置字体及颜色,设置var为infoLabel,方便控制,最终UI界面编辑器完毕。

blob.png 

 

使用快捷键F12,发布刚才设计的界面,切换到“代码模式”,我们现在就把刚才制作的UI界面放到游戏内。

新建一个GameInfo.as类,继承至刚才生成的GameInfoUI类。

blob.png 

  

  为了方便控制游戏层次,我们把之前的所有Role均放到一个roleBox容器内,同时示例一个UI层到上面。为了更好的性能体验,我这里激活了WebGL渲染模式,WebGL渲染模式打开方法:Laya.init(480, 852, WebGL);(记得导入laya.webgl.WebGL);

public class Main 
	{
		//添加一个主函数的静态变量方法
		public static var gameInstance:Main;
		//定义游戏的UI信息
		private var gameUI:GameInfo;
		//定义一个放角色的容器
		private var roleBox:Sprite;
		
		
		public function Main() 
		{
			//记录这个静态方法
			gameInstance = this;
			//初始化引擎
			Laya.init(480,852,WebGL);
			//创建滚动的背景
			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(0,50);
		}
		
		
            private function onload():void 
		{
			//实例化角色容器
			roleBox = new Sprite();
			//角色容器添加到舞台
			Laya.stage.addChild(roleBox);
			//实例化UI界面
			gameUI = new GameInfo();
			//UI界面添加到舞台
			Laya.stage.addChild(gameUI);
			//实例化自机
			hero = new Role();
			//在角色容器中添加自机
			roleBox.addChild(hero);
			//开始游戏
			this.restart();
		}

  继续修改,添加重新开始游戏的方法restart()

		private function restart():void 
		{
			//暂停按钮接收鼠标消息
			gameUI.pauseBtn.mouseEnabled = true;
			//初始化游戏数据
			score = 0;
			level = 0;
			levelUpScore = 0;
			bulletLevel = 0;
			gameUI.reset();
			//初始化角色
			hero.init("hero", 5, 0, 30, 0);
			//设置角色位置。
			hero.pos(240, 700);
			//设置射击类型
			hero.shootType = 1;
			//重置射击间隔
			hero.shootInterval = 500;
			//显示角色
			hero.visible = true;
			//遍历角色容器中的角色,回收除了自机以外的所有内容
			for (var i:Number = this.roleBox.numChildren - 1; i > -1; i--) {
				var role:Role = this.roleBox.getChildAt(i) as Role;
				if (role != this.hero) {
					//从舞台移除
					role.removeSelf();
					//重置角色的属性
					role.visible = true;
					//回收到对象池
					Pool.recover("role", role);
				}
			}	
			//游戏进行
			this.resume();
		}

  添加游戏暂停方法pause();

/**
		 * 暂停游戏
		 */
		public function pause():void {
			//清除游戏主循环函数的执行。
			Laya.timer.clear(this, this.onLoop);
			//移除舞台的鼠标事件侦听。
			Laya.stage.off(Event.MOUSE_MOVE, this, this.onMouseMove);
		}

   添加游戏开始方法resume();

		/**
		 * 开始游戏,继续游戏。
		 */
		public function resume():void {
			//创建游戏主循环。
			Laya.timer.frameLoop(1, this, this.onLoop);
			//给舞台添加鼠标移动事件侦听。
			Laya.stage.on(Event.MOUSE_MOVE, this, this.onMouseMove);
		}

    修改onloop()游戏主循环,将飞机、子弹、强化道具、医疗保都加入到roleBox

        roleBox.addChild(bullet);
        
        roleBox.addChild(item);
        
        roleBox.addChild(enemy);

   修改清除飞机、子弹的循环,从roleBox中遍历

for (var i: int = roleBox.numChildren - 1; i > -1; i--) {
        var role: Role = roleBox.getChildAt(i) as Role;

修改碰撞检测,从roleBox中比较

blob.png

修改游戏结束的方法

//如果主角死亡,则停止游戏循环
			if (hero.hp < 1) {
		//停止主函数的循环和鼠标监听
		this.pause();
		//更改射击状态
		hero.shootType = 0;
		//禁用暂停按钮
		gameUI.pauseBtn.mouseEnabled = false;
		//设置中心区域的文字
		gameUI.infoLabel.text = "GameOver 分数:" + this.score + "\n点击重新开始。";
		//点击中心区域的文字重新开始游戏
		gameUI.infoLabel.once(Event.CLICK, this, this.restart);
			}

写UI控制类,可以直接使用在编辑器设置的var,直接引用书写代码,并且有很好的代码提示,非常方便。

package 
{
	import laya.events.Event;
	import ui.GameInfoUI;
	

	public class GameInfo extends GameInfoUI 
	{
		
		public function GameInfo() 
		{
			//注册按钮点击事件,点击后暂停游戏
			this.pauseBtn.on("click", this, this.onPauseBtnClick);
			//初始化UI显示
			this.reset();
		}
				/**
		 * 初始化UI界面
		 */
		public function reset():void 
		{
			//设置中心内容
			infoLabel.text = "";
			//初始化血量
			hp(5);
			//初始化等级
			level(0);
			//初始化得分
			score(0);
		}
		/**
		 * 游戏暂停
		 *  @param	e
		 */
		private function onPauseBtnClick(e:Event):void 
		{
			//阻止后续节点的监听器
			e.stopPropagation();
			//设置文本
			infoLabel.text = " 游戏已经暂停,任意地方恢复";
			//执行主函数的暂停函数
			Main.gameInstance.pause();
			//每调用只执行一次的恢复函数
			Laya.stage.once(Event.CLICK, this, this.onStageClick);
		}
		/**
		 * 游戏恢复
		 */
		private function onStageClick():void 
		{
			//设置文本
			infoLabel.text = "";
			//执行主函数里面的恢复函数
			Main.gameInstance.resume();
		}
		/**
		 * 显示得分
		 * @param	分数
		 */
		public function score(number:Number):void 
		{
			scoreLabel.text = "得分:" + number;
		}
		/**
		 * 显示等级
		 * @param	等级
		 */
		public function level(number:Number):void 
		{
			levelLabel.text = "等级:" + number;
		}
		/**
		 * 显示生命
		 * @param	血量
		 */
		public function hp(number:Number):void 
		{
			hpLabel.text = "生命:" + number;
		}
		

		
	}

}


在积分变换后,调用UI的api更改显示。

			//更新自机的生命值
			gameUI.hp(this.hero.hp);
			//更新得分
			gameUI.score(score);
			//积分大于升级积分,则升级
			if (score > 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;
			//更新等级
			gameUI.level(level);
			}


编译后效果如下:

图片1.png 

 

死亡后:

图片1.png 

  

UI编辑器及使用都是可视化的,策划,美术和程序能够通过IDE轻松配合,是不是很方便呢。

 

本节课程源码下载