实现加载进度条效果和json数据读取
**
在Main类中
public constructor() {
super();
this.addEventListener(egret.Event.ADDED_TO_STAGE, this.onAddToStage, this);
}
监听事件,页面被添加到屏幕上会执行的程序。如:在网站打开网页后,先显示的是灰色的屏幕,即网页打开,但是egret场景还没有加载完,在网页上加载白鹭底核。当加载完成,执行的第一个方法。
。
依次是更新,暂停(页面被打断,来电话游戏切到后台),恢复(暂停之后回到游戏)
白鹭纠错机制,当这个方法运行报错,会报错弹出。
runGame方法:
await this.loadResource() :整个白鹭加载核心。读取加载资源。
含义:以独占模式执行此方法
多线程;同时开很多程序。同一个也会执行很多(功能)线程。
所有具备监听者模式,回调模式的代码都是异步(多线程)执行。
在异步执行过程中,如果有了await独占模式,就必须要先执行完这句代码,才会执行后面代码。
const loadingView = new LoadingUI(); //资源加载界面LoadingUI,界面或回调
解释:
在进行资源加载时,必须传界面,用回调方法把加载的进度进行返回。
this.stage.addChild(loadingView); //加载最高层
解释:
把加载界面添加到场景当中。 用this.stage.addChild。stage是整个场景。
Main.ts也是一个界面,都添加到Main.ts这个大场景,Main.ts是加载到主的手机页面,就是stage。
所以在stage上添加界面,不论当时手机屏幕显示的什么,只要在stage上添加,一定会在最上层。
永远会遮住游戏中所有图层。
await RES.loadConfig(“resource/default.res.json”, “resource/”); //资源加载配置文件
解释:
资源路径,配置,分组。按照组进行资源加载
await:以独占模式运行,只有这个线程执行完,才会再次执行后面代码。
在代码语句中出现了await…独占模式语句,那么这个方法就必须是独占模式,加关键字async
await RES.loadGroup(“preload”, 0, loadingView); //进行分组加载
解释:进行一个组的加载( 组名,起始加载位置,加载界面)
执行完这句代码资源并没有加载完成,只是开始执行,
this.stage.removeChild(loadingView); //移除加载界面
loadResource()方法中
try…catch 异常处理,这段代码中可以出错, 若出现错误,代码不会终止,会执行catch中的代码。
current: number, 加载资源个数 total: number加载资源总数
this.textField.text = Loading...${current}/${total}
; js写法
this.textField.text = “Loading…”+current+"/"+total; 字符串连接
回到loadResource方法
this.stage.removeChild(loadingView); //加载完资源,移除LoadingUI界面
回到runGame方法执行this.createGameScene();方法
加载时间过长怎么办?
①尽可能减少图片的使用量
②分步加载,用什么加载什么
不同时间段加载的图片进行分组
切换流程:
进入游戏界面时,先进行游戏界面的加载,还要重新调出,当进度条读完,再移除加载界面,切换到游戏界面。
动画播放完,图片加载完成,再去执行界面切换。
添加menu界面点击切换到游戏界面
流程:
在Main类中申请 public menu:MainMenu;
public canvasIndex:number; //界面索引
界面索引用于界面切换
构造:
this.game= null;
this.addChild(this.menu);
this.canvasIndex=10; //10menu 20game 30over
在Main类中
在touchDown,touchMove ,touchUp三方法和update方法添加
switch(this.canvasIndex)
{
case 10:
this.menu.touchDown(e);
break;
case 20:
this.game.touchDown(e);
break;
}
public loadingView;
private async loadResource() {
try {
this.loadingView = new LoadingUI();
this.stage.addChild(this.loadingView);
await RES.loadConfig("resource/default.res.json", "resource/");
//menu为组名,menu背景图在menu组中
await RES.loadGroup("menu", 0, this.loadingView); this.stage.removeChild(this.loadingView);
}
catch (e) {
console.error(e);
}
}
为什么this.game= null;?
在构造时资源没有加载,在点击切换屏幕时才开始加载。因为game虽然有但并不存在,所以为空。
在Mainmenu类中
public async touchDown(e:egret.TouchEvent)
{
//等于空说明没有构造,资源没有加载,所以才加载界面
if(this.main.game == null){ //把loading界面加载到场景中
this.stage.addChild(this.main.loadingView);
//读取资源
await RES.loadGroup("game", 0, this.main.loadingView);
//移除界面
this.stage.removeChild(this.main.loadingView);
//加载完成再去构造game界面
this.main.game = new MainGame(this.main);
}
this.main.removeChild(this);
this.main.game.reset(0); // 0 是关卡
this.main.addChild(this.main.game);
this.main.canvasIndex = 20;
}
加载三过程
//把loading界面加载到场景中
this.stage.addChild(this.main.loadingView);
//读取资源
await RES.loadGroup(“game”, 0, this.main.loadingView);
//移除界面
this.stage.removeChild(this.main.loadingView);
创建LoadingUI2界面
class LoadingUI2 extends egret.Sprite implements RES.PromiseTaskReporter {
public im:egret.Bitmap;
public constructor() {
super();
this.im =Main.createBitmapByName("game_uiboss3_png");
this.addChild(this.im);
this.im.y = 500;
this.im.scaleX = 0 ;
}
public onProgress(current: number, total: number): void {
//进度条伸长效果
this.im.scaleX = current/total;
}
}
在Main类中的loadResource()方法最后添加 this.loadingView = new LoadingUI2();
private async createGameScene()
{
this.stage.addChild(this.loadingView);;
await RES.loadGroup("menu", 0, this.loadingView);
this.stage.removeChild(this.loadingView);
this.menu=new MainMenu(this);
this.game= null;
...}
在MainMenu类中
public async touchDown(e:egret.TouchEvent)
{
if(this.main.game == null){ //等于空说明没有构造,资源没有加载,所以才加载界面
//把loading界面加载到场景中
this.stage.addChild(this.main.loadingView);
//读取资源
await RES.loadGroup("game", 0, this.main.loadingView);
//移除界面
this.stage.removeChild(this.main.loadingView);
//加载完成再去构造game界面
this.main.game = new MainGame(this.main);
}
this.main.removeChild(this);
this.main.game.reset(0); // 0 是关卡
this.main.addChild(this.main.game);
this.main.canvasIndex = 20;
}
**
**
游戏开发设计模式:状态机 根据m执行不同代码
有限状态机:用状态机时代码太长,用父类和子类。父类统一管理,子类实现差异化
工厂设计模式:通过create生成对象,将对象放在仓库、
单例设计模式:
当项目中所有的东西都需要使用它,谁都需要,但是又谁也不属于,可以作为单例模式。例如:数据
59:
json文件不能加注释!但是可以写成键值对类型,最后一个值不用加逗号
{
“playV”: 30, ”说明1”:”玩家速度”,
“zdV”: 10, ”说明2”:”子弹转向速度”
}
创建JSON文件,导入资源。
//读取json文件中的值
let data = RES.getRes("data_json");
this.v = data["playV"];
使用json文件的优点:可以在游戏打包完成后进行数值修改,不需要重新编译文件,不需要修改代码,就可以对数值修改。
数据类的整合:
创建Maindata类: 当中包含游戏中所有的数据 单例类
MainData中的数据对应json文件中的数据 优点:可以加全局注释
单例类在项目中每个文件都需要使用,在项目之外,提供数据支持。
单例对象主要特征:
①在内部有一个静态自身对象:private static my:MainData;
②全局静态方法getInstrins():public static getInstrins():MainData{ } 这个方法返回自身的静态对象
public static getInstrins():MainData{
//判断静态对象是否存在 .MainData.my 存在执行她的构造,返回它的对象
if(!MainData.my){
MainData.my = new MainData();
}
return MainData.my;
}
使用: player类中:this.v = MainData.getInstrins().playerV;