有时候,当我们场景上挂载的资源过多时,我们使用cc.director.loadScene切换场景时会等一段时间才会切换过去,这对游戏的体验是相当不好的。所以我们可以使用cc.director.preloadScene来进行预加载,如:

cc.director.preloadScene("sceneName", function () {
cc.director.loadScene("sceneName");
});

同时搭载一个加载进度条来实现显示加载进度,优化游戏体验:

那么如何获取加载时的进度呢?

在Cocos creator 2.0版本之前,我们可以使用下面这样的方法:

cc.loader.onProgress = function (completedCount, totalCount, item){
//先开监听
this.loading.progress = completedCount/totalCount;
this.loadLabel.string = Math.floor(completedCount/totalCount * 100) + "%";
}.bind(this); cc.director.preloadScene("sceneName", function () {
cc.log("加载成功");
});

loading就是你在脚本中绑定的进度条组件。

Cocos creator升级到2.0版本后,onProgress貌似就无法使用了,所以上述那个方法无法获取到加载进度,但是在cc.director.preloadScene这个函数中新增了一个参数:

所以我们可以通过这个参数来获取加载的进度:

cc.director.preloadScene("sceneName", this.onProgress.bind(this), function(){
cc.log("加载成功");
}) onProgress :function(completedCount, totalCount, item){
this.loading.progress = completedCount/totalCount;
this.loadLabel.string = Math.floor(completedCount/totalCount * 100) + "%";
}

其实无论是预加载场景还是加载资源,本质调用的还是cc.loader.load这个api,看底层代码可以知道:

预加载场景:

preloadScene: function (sceneName, onProgress, onLoaded) {
if (onLoaded === undefined) {
onLoaded = onProgress;
onProgress = null;
} var info = this._getSceneUuid(sceneName);
if (info) {
this.emit(cc.Director.EVENT_BEFORE_SCENE_LOADING, sceneName);
cc.loader.load({ uuid: info.uuid, type: 'uuid' },
onProgress,
function (error, asset) {
if (error) {
cc.errorID(1210, sceneName, error.message);
}
if (onLoaded) {
onLoaded(error, asset);
}
});
}
else {
var error = 'Can not preload the scene "' + sceneName + '" because it is not in the build settings.';
onLoaded(new Error(error));
cc.error('preloadScene: ' + error);
}
},

加载资源:

proto.loadResDir = function (url, type, progressCallback, completeCallback) {
var args = this._parseLoadResArgs(type, progressCallback, completeCallback);
type = args.type;
progressCallback = args.onProgress;
completeCallback = args.onComplete; var urls = [];
var uuids = resources.getUuidArray(url, type, urls);
this._loadResUuids(uuids, progressCallback, function (errors, assetRes, urlRes) {
// The spriteFrame url in spriteAtlas will be removed after build project
// To show users the exact structure in asset panel, we need to return the spriteFrame assets in spriteAtlas
let assetResLength = assetRes.length;
for (let i = 0; i < assetResLength; ++i) {
if (assetRes[i] instanceof cc.SpriteAtlas) {
let spriteFrames = assetRes[i].getSpriteFrames();
for (let k in spriteFrames) {
let sf = spriteFrames[k];
assetRes.push(sf);
if (urlRes) {
urlRes.push(`${urlRes[i]}/${sf.name}`);
}
}
}
}
completeCallback && completeCallback(errors, assetRes, urlRes);
}, urls);
};
proto._loadResUuids = function (uuids, progressCallback, completeCallback, urls) {
if (uuids.length > 0) {
var self = this;
var res = uuids.map(function (uuid) {
return {
type: 'uuid',
uuid: uuid
}
});
this.load(res, progressCallback, function (errors, items) {
if (completeCallback) {
var assetRes = [];
var urlRes = urls && [];
for (var i = 0; i < res.length; ++i) {
var uuid = res[i].uuid;
var id = this._getReferenceKey(uuid);
var item = items.getContent(id);
if (item) {
// should not release these assets, even if they are static referenced in the scene.
self.setAutoReleaseRecursively(uuid, false);
assetRes.push(item);
if (urlRes) {
urlRes.push(urls[i]);
}
}
}
if (urls) {
completeCallback(errors, assetRes, urlRes);
}
else {
completeCallback(errors, assetRes);
}
}
});
}
else {
if (completeCallback) {
callInNextTick(function () {
if (urls) {
completeCallback(null, [], []);
}
else {
completeCallback(null, []);
}
});
}
}
};

cc.loader.load的内部实现的参数中就是带有这个回调函数的

所以我们还可以这样写来获取加载场景的进度:

var info = cc.director._getSceneUuid(this.sceneName);
var self = this;
if (info) {
cc.loader.load({ uuid: info.uuid, type: 'uuid' }, function(completedCount, totalCount, item){
  cc.log("已完成Items:" + completedCount);
  cc.log("全部Items:" + totalCount);
  cc.log("当前Item:" + item.url);
  self._loadingNextStep = parseInt(completedCount / totalCount * 100);
  cc.log("加载进度:" + self._loadingNextStep);
}, function(error, asset){
if (error) {
cc.errorID(1210, this.sceneName, error.message);
} else {
cc.log("加载完成");
         }
}
});
}

creator 2.0版本对于preloadScene函数获取加载进度的更多相关文章

  1. 使用 .NET Core 3.0 的 AssemblyLoadContext 实现插件热加载

    一般情况下,一个 .NET 程序集加载到程序中以后,它的类型信息以及原生代码等数据会一直保留在内存中,.NET 运行时无法回收它们,如果我们要实现插件热加载 (例如 Razor 或 Aspx 模版的热 ...

  2. js - 多个函数动态加载

    //动态添加物流锁的IEMI列表. function createLi() { var r = '<s:property value="#session.locks"/> ...

  3. setUserVisibleHint的使用.执行顺序和viewPager.setOffscreenPageLimit(0)不管用还是默认会加载第二个fragment

    处理问题一:viewPager.setOffscreenPageLimit(0)不管用还是默认会加载第二个fragment的原因(源码解读); 处理问题二:setUserVisibleHint的使用场 ...

  4. pytorch1.0神经网络保存、提取、加载

    pytorch1.0网络保存.提取.加载 import torch import torch.nn.functional as F # 包含激励函数 import matplotlib.pyplot ...

  5. 【逆向工具】IDA使用1-VS2015版本debug查找Main函数,加载符号文件

    IDA 常见操作 空格,切换反汇编视图 选择CALL或是跳转 进入函数内部或是跳转处 返回键 ESC daq.exe 分析32位程序 ,生成的IDA数据库文件是 .idb Idap64.exe 分析6 ...

  6. javascript . 03 函数定义、函数参数(形参、实参)、函数的返回值、冒泡函数、函数的加载、局部变量与全局变量、隐式全局变量、JS预解析、是否是质数、斐波那契数列

    1.1 知识点 函数:就是可以重复执行的代码块 2.  组成:参数,功能,返回值 为什么要用函数,因为一部分代码使用次数会很多,所以封装起来, 需要的时候调用 函数不调用,自己不会执行 同名函数会覆盖 ...

  7. Android如何在初始化的时候获取加载的布局的宽高

    在自定义ListView中,需要将下拉刷新的View在初始化的时候设置padding隐藏起来,这时就要在初始化的时候获得要加载的布局View的高度. private View headView; he ...

  8. 『心善渊』Selenium3.0基础 — 22、使用浏览器加载项配置实现用户免登陆

    目录 1.浏览器的加载项配置 2.加载Firefox配置 3.加载Chrome配置 1.浏览器的加载项配置 在很多情况下,我们在登录网站的时候,浏览器都会弹出一个是否保存登录账号的信息.如果我们选择保 ...

  9. PHP笔记4__函数/全局、静态变量/函数参数/加载函数库/,,

    <?php header("Content-type: text/html; charset=utf-8"); echo table(5,5); function table ...

随机推荐

  1. Python--day62--编辑出版社功能

    1,Django项目主要用到的文件

  2. SVN中如何执行clean up

    在要清理的文件夹上点右键,菜单:TortoiseSVN--选择cleanup,会出现一个菜单栏,在你菜单栏有一个属性breaklock意思是打破锁定,你勾选打破锁定,然后cleanup就会成功,之后再 ...

  3. 在spring security3中使用自定义的MD5和salt进行加密

    首先看代码: <authentication-manager alias="authenticationManager"> <authentication-pro ...

  4. css3 移动端旋转动画暂停

    音乐播放图片旋转动画 ios不支持暂停: animation-play-state: paused; @-webkit-keyframes rotate{ 100% { transform: rota ...

  5. springBoot从入门到源码分析

    先分享一个springBoot搭建学习项目,和springboot多数据源项目的传送门:https://github.com/1057234721/springBoot 1. SpringBoot快速 ...

  6. Codeforces 293E 点分治+cdq

    Codeforces 293E 传送门:https://codeforces.com/contest/293/problem/E 题意: 给你一颗边权一开始为0的树,然后给你n-1次操作,每次给边加上 ...

  7. Java并发机制的底层实现原理之volatile应用,初学者误看!

    volatile的介绍: Java代码在编译后会变成Java字节码,字节码被类加载器加载到JVM里,JVM执行字节码,最终需要转化为汇编指令在CPU上执行,Java中所使用的并发机制依赖于JVM的实现 ...

  8. etcd配置文件详解

    一 示例yml配置文件 # This is the configuration file for the etcd server. # Human-readable name for this mem ...

  9. Java面试思路

    一.javaSE基础 1.java IO流 2.java NIO 3.java集合 4.java注解 5.java泛型 6.java反射 7.java多线程 8.常用String.数组.日期操作 二. ...

  10. [译文] 为什么你在 C# 里总是应该使用 "var" 关键字

    [译文] Why You Should Always Use the 'var' Keyword in C# (为什么你总是应该在 C# 里使用 "var" 关键字) Using ...