新建一个recourse文件夹,把需要加载的资源放入。
创建Loading脚本,使用 cc.resources.loadDir( ) 加载资源
cc.resources 是一个 bundle,用于管理所有在 assets/resources 下的资源
const {ccclass, property} = cc._decorator;
@ccclass
export default class NewClass extends cc.Component {
start () {
//进度回调函数
let onProgress =(finish:number,total:number,item)=>{
console.log(finish,total);
}
//完成回调函数
let onComplete =(err:Error,assets: cc.Asset[])=>{
if(err){
console.log('err');
return;
}
console.log(assets);
}
//读取所有资源
//参数一:以resources为根目录的文件夹路径
//参数二:要加载的资源的类型
//参数三:进度回调函数
//参数三:完成回调函数,加载完的资源,存储到回调的参数里面。
cc.resources.loadDir('',null,onProgress,onComplete);
}
}
在菜单场景创建一个进度条节点,挂载Loading脚本
当进度条走完(资源加载完)后,才显示菜单。
把过后才要显示的内容放入NormalLayer中,先设置为隐藏,然后在Loading代码中显示出来。
const {ccclass, property} = cc._decorator;
@ccclass
export default class NewClass extends cc.Component {
start () {
//进度回调函数
let onProgress =(finish:number,total:number,item)=>{
//计算加载进度
let progress = finish/total;
//修改进度条进度
let progressBar = this.node.getChildByName('progressBar').getComponent(cc.ProgressBar);
progressBar.progress = progress;
}
//完成回调函数 cc.Asset[]是一个资源数组
let onComplete =(err:Error,assets: cc.Asset[])=>{
if(err){
console.log('err');
return;
}
//显示菜单
cc.find('Canvas/NormalLayer').active = true;
}
//读取所有资源
//参数一:以resources为根目录的文件夹路径
//参数二:要加载的资源的类型
//参数三:进度回调函数
//参数三:完成回调函数,加载完的资源,存储到回调的参数里面。
cc.resources.loadDir('',null,onProgress,onComplete);
}
}
创建一个资源基类ResBase脚本
基类用于创建不同类型的资源对象,并调用addData函数从Asset中加载出不同类型的资源。
interface ResDt{
resName:string, //资源名字
resType:cc.Asset //资源
}
export default class ResBase{
private arrData:ResDt[] = []; //存储资源的数组
constructor() {
}
//用于根据不同的类型加载Asset资源
addData(name:string,resData:cc.Asset):void{
//创建一个Data类型的对象,把它压入到数组
//根据接口类型创建出对象的属性。
let configData:ResDt ={
resName:name,
resType:resData
};
this.arrData.push(configData);
}
//通过名字获取资源(共有的方法)
getDataByName(name:string):cc.Asset{
//遍历数组,拿到每个元素(对象)里面的configName属性是否跟传递进来的name一样,如果一样返回 脚本
for(let value of this.arrData){
if(name === value.resName){
return value.resType;
}
}
return null;
}
//通过id获取json数据
getJsonByID(jsonName:string,id:number,isJson:boolean = false){
//如果不是json返回空
if(!isJson||jsonName.length === 0){
return null;
}
//首先根据名字拿到json
let jsonAsset =this.getDataByName(jsonName) as cc.JsonAsset;
//获取json数据数组
let arrJson = jsonAsset.json;
//循环根据ID查找具体数据
for(let value of arrJson){
if(id === value.id){
return value;
}
}
return null;
}
}
创建一个统一管理不同资源的ResMgr,把它设为单例。
import ResBase from './ResBase'
interface MgrData{
resMgrName:string,
resMgrType:ResBase
}
export default class ResMgr{
private static instance = null;
private arrMgr:MgrData[] = [];
//结构体
constructor() {
}
//单例
public static getInstance(){
if(!ResMgr.instance){
ResMgr.instance = new ResMgr();
}
return ResMgr.instance;
}
//把不同的Asset存进来
addData(name:string,resMgr:ResBase):void{
//创建一个Data类型的对象,把它压入到数组
//根据接口类型创建出对象的属性。
let configData:MgrData ={
resMgrName:name,
resMgrType:resMgr
};
this.arrMgr.push(configData);
}
//获取不同的Asset
getData(name:string):ResBase{
//遍历数组,拿到每个元素(对象)里面的configName属性是否跟传递进来的name一样,如果一样返回 脚本
for(let value of this.arrMgr){
if(name === value.resMgrName){
return value.resMgrType;
}
}
//循环结束如果没有找到返回null
return null;
}
}
在Loading中,资源加载进来以后,有各种类型的资源。
地图资源相应地要存到地图里,所以要判断资源的类型进行存储。
先new一个基类类型的地图资源tiledMapAsset,然后调用基类类型的资源加载接口addData把资源加载到tiledMapAsset中,最后调用资源管理者ResMgr的接口addData把地图资源tiledMapAsset添加到ResMgr中进行统一管理。
import ResMgr from './ResMgr'
import MgrBase from './ResBase'
const {ccclass, property} = cc._decorator;
@ccclass
export default class NewClass extends cc.Component {
start () {
//进度回调函数
let onProgress =(finish:number,total:number,item)=>{
//计算加载进度
let progress = finish/total;
let progressBar = this.node.getChildByName('progressBar').getComponent(cc.ProgressBar);
progressBar.progress = progress;
}
//完成回调函数 cc.Asset[]是一个资源数组
let onComplete =(err:Error,assets: cc.Asset[])=>{
if(err){
console.log('err');
return;
}
console.log(assets);
//显示菜单
cc.find('Canvas/NormalLayer').active = true;
//处理资源加载进来后的存储逻辑
//遍历资源数组
for(let value of assets){
//获取名字
let name:string = value.name;
//判断value的类型,进行存储。
if(value instanceof cc.TiledMapAsset){
//new一个基类类型的地图
let tiledMapAsset = new MgrBase();
//调用基类类型的资源加载接口
tiledMapAsset.addData(name,value);
//把地图资源添加到ResMgr统一管理
ResMgr.getInstance().addData('TiledMapAsset',tiledMapAsset);
}
else if(value instanceof cc.Prefab){
//预制体
let prefabAsset = new MgrBase();
prefabAsset.addData(name,value);
ResMgr.getInstance().addData('PrefabAsset',prefabAsset);
}
else if(value instanceof cc.SpriteAtlas){
let arrSpriteFrams = value.getSpriteFrames();
for(let spriteFrame of arrSpriteFrams){
//精灵
let spriteAsset = new MgrBase();
spriteAsset.addData(spriteFrame.name,spriteFrame);
ResMgr.getInstance().addData('SpriteAsset',spriteAsset);
}
}
else if(value instanceof cc.JsonAsset){
//json数据
let jsonAsset = new MgrBase();
jsonAsset.addData(value.name,value);
ResMgr.getInstance().addData('JsonAsset',jsonAsset);
}
}
}
//读取所有资源
//参数一:以resources为根目录的文件夹路径
//参数二:要加载的资源的类型
//参数三:进度回调函数
//参数三:完成回调函数,加载完的资源,存储到回调的参数里面。
cc.resources.loadDir('',null,onProgress,onComplete);
}
}
资源的使用:
至此,地图资源已经被加载进来了,不再使用原先的公布数组方式获取地图,直接拿存入的资源即可。
//获取格子地图资源(拿到具体对象下的具体资源)
let tmxAsset = ResMgr.getInstance().getData('TiledMapAsset').getDataByName('map'+(window.myGlobal.mapIndex+1));
//修改地图
this.tiledMap.tmxAsset = tmxAsset;