如何自定义 Cocos2d-html5 Loading 界面

作者&投稿:文冯 (若有异议请与网页底部的电邮联系)
如何自定义 Cocos2d-html5 Loading 界面~

Cocos2d-html5 Loading 界面自定义的方法是:
自定义一个 Loader.js 文件,实现 Loader 类,完成自定义Loading 界面的具体实现,其中大多参考(实际是copy)了 LoaderScene 的实现,在其上修改扩充,它完成了修改 Logo 图片,并添加了一个简单的进度条。
实现代码如下:

logoData = "data:image/png;base64,...";

Loading = cc.Scene.extend(
_logo: null,
_logoTexture: null,
_texture2d: null,
_bgLayer: null,
_label: null,
_winSize:null,
_processLayer: null, // 相比 LoaderScene 的实现,添加了两个属性,标示进度条层和进度条长度
_processLayerLength: null,

// 构造函数
ctor: function () {
this._super();
this._winSize = cc.Director.getInstance().getWinSize();
},
init:function(){
cc.Scene.prototype.init.call(this);

// logo 图片和 label 的添加 .. 这里省略,于 LoaderScene 同样

// 设置进度条层,它就是一个红色颜色层,通过长度来标示加载的进度
this._processLayerLength = 500;
this._processLayer = cc.LayerColor.create(cc.c4b(255, 100, 100, 128), 1, 30);
this._processLayer.setPosition(cc.pAdd(centerPos, cc.p(- this._processLayerLength / 2, -logoHeight / 2 - 50)));
// 可以启用锚点,并设置以满足自己的需要
// this._processLayer.ignoreAnchorPointForPosition(false);
// this._processLayer.setAnchorPoint(cc.p(0, 0));

this._bgLayer.addChild(this._processLayer);
},
// 以下方法的实现并没有跟 LoaderScene 有什么不同
// _initStage: ...
// onEnter ...
// onExit ...
// initWithResources ...
// _startLoading ...
// _logoFadeIn
// 每帧更新
_updatePercent: function () {
var percent = cc.Loader.getInstance().getPercentage();
var tmpStr = "Loading... " + percent + "%";
this._label.setString(tmpStr);

// 设置当前进度条层的长度
this._processLayer.changeWidth(this._processLayerLength * percent / 100);

if (percent >= 100)
this.unschedule(this._updatePercent);
}
});
// 这里于 LoaderScene 的实现同样
Loading.preload = function (resources, selector, target) {
if (!this._instance) {
// 创建一个 Loading
this._instance = new Loading();
this._instance.init();
}
// ...
return this._instance;
};

要自定义实现 Loading 界面,那就是重新实现 LoaderScene 即可。对于 LoaderScene 的实现比较简单,自定义一个 Loader.js 文件,实现 Loader 类,完成自定义Loading 界面的具体实现,其中大多参考(实际是copy)了 LoaderScene 的实现,在其上修改扩充,它完成了修改 Logo 图片,并添加了一个简单的进度条。
loading.js源码如下:
var logoData = "data:image/png;base64,L4U3iOPBn1XRxsIzA/wIhOlbeQNbh6gAAAABJRU5ErkJggg==";/** * Used to display the loading screen * @class * @extends cc.Scene */Loading = cc.Scene.extend(/** @lends cc.LoaderScene# */{ _logo: null, _logoTexture: null, _texture2d: null, _bgLayer: null, _label: null, _winSize:null,_processLayer: null,_processLayerLength: null, /** * Constructor */ ctor: function () { this._super(); this._winSize = cc.Director.getInstance().getWinSize(); }, init:function(){ cc.Scene.prototype.init.call(this); //logo var logoHeight = 200; var centerPos = cc.p(this._winSize.width / 2, this._winSize.height / 2); this._logoTexture = new Image(); var _this = this; this._logoTexture.addEventListener("load", function () { _this._initStage(centerPos); }); this._logoTexture.src = logoData; this._logoTexture.width = 242; this._logoTexture.height = 114; // bg this._bgLayer = cc.LayerColor.create(cc.c4(200, 200, 200, 255)); this._bgLayer.setPosition(cc.p(0, 0)); this.addChild(this._bgLayer, 0); //loading percent this._label = cc.LabelTTF.create("Loading... 0%", "Arial", 14); this._label.setColor(cc.c3(80, 80, 80)); this._label.setOpacity(0); // this._label.setPosition(cc.pAdd(centerPos, cc.p(0, -logoHeight / 2 - 10))); this._label.setPosition(cc.pAdd(centerPos, cc.p(0, -logoHeight / 2 - 100))); this._bgLayer.addChild(this._label, 10);this._processLayerLength = 500;this._processLayer = cc.LayerColor.create(cc.c4b(255, 100, 100, 128), 1, 30);this._processLayer.setPosition(cc.pAdd(centerPos, cc.p(- this._processLayerLength / 2, -logoHeight / 2 - 50)));// this._processLayer.ignoreAnchorPointForPosition(false);// this._processLayer.setAnchorPoint(cc.p(0, 0));this._bgLayer.addChild(this._processLayer); }, _initStage: function (centerPos) { if (cc.renderContextType === cc.CANVAS) { this._logo = cc.Sprite.createWithTexture(this._logoTexture); } else { this._texture2d = new cc.Texture2D(); this._texture2d.initWithElement(this._logoTexture); this._texture2d.handleLoadedTexture(); this._logo = cc.Sprite.createWithTexture(this._texture2d); } this._logo.setPosition(centerPos); this._bgLayer.addChild(this._logo, 10); //load resources this._logoFadeIn(); }, onEnter: function () { cc.Node.prototype.onEnter.call(this); this.schedule(this._startLoading, 0.3); }, onExit: function () { cc.Node.prototype.onExit.call(this); var tmpStr = "Loading... 0%"; this._label.setString(tmpStr); }, /** * init with resources * @param {Array} resources * @param {Function|String} selector * @param {Object} target */ initWithResources: function (resources, selector, target) { this.resources = resources; this.selector = selector; this.target = target; }, _startLoading: function () { this.unschedule(this._startLoading); cc.Loader.preload(this.resources, this.selector, this.target); this.schedule(this._updatePercent); }, _logoFadeIn: function () { var logoAction = cc.Spawn.create( cc.EaseBounce.create(cc.MoveBy.create(0.25, cc.p(0, 10))), cc.FadeIn.create(0.5)); var labelAction = cc.Sequence.create( cc.DelayTime.create(0.15), logoAction.clone()); this._logo.runAction(logoAction); this._label.runAction(labelAction); }, _updatePercent: function () { var percent = cc.Loader.getInstance().getPercentage(); var tmpStr = "Loading... " + percent + "%"; this._label.setString(tmpStr);this._processLayer.changeWidth(this._processLayerLength * percent / 100); if (percent >= 100) this.unschedule(this._updatePercent); }});Loading.preload = function (resources, selector, target) { if (!this._instance) { this._instance = new Loading(); this._instance.init(); } this._instance.initWithResources(resources, selector, target); var director = cc.Director.getInstance(); if (director.getRunningScene()) { director.replaceScene(this._instance); } else { director.runWithScene(this._instance); } return this._instance;};

  在使用 C++ 编写 Cocos2d-x 游戏的时候,通常在运行游戏之前,需要加载游戏资源,这样是为了让游戏在运行时更为流畅,避免了在运行时加载资源,而出现卡顿现象,影响用户体验,因为加载资源是非常耗时、耗资源的操作。在 Cocos2d-html5 中也是同样,在运行游戏之前,预先加载好所有的资源(加载到浏览器缓存),以保证游戏的流畅运行。

  Cocos2d-html5 的加载流程

  在开始我们的替换工作之前,大致说一下必要的(只注重我们在乎的细节问题)原有的加载流程,以**HelloHTML5World**为例 。从其主页面 index.html开始,我们需要了解三个文件的运作方式,index.html、cocos2d.js 和 main.js:

  浏览器首先加载 index.html 页面,值得注意的有两点,在页面的 DOM 树中,能看到命名为**gamecanvas**的**Canvas**元素,它将会是游戏的画布,另一点,在页面的最后,加载了 cocos2d.js 文件。

  cocos2d.js 内中,定义了程序运行需要的一些参数,如 显示 FPS,是否加载扩展库,物理引擎库等,其中 engineDir 设置了引擎所在的位置,appFiles 设置了,当前项目所用到需要加载的 js 程序代码。并定义了当 DOM 加载完成时运行的代码(你可以在 【这里】 查看所有代码。):

  window.addEventListener('DOMContentLoaded', function () {
  // 添加脚本
  var s = d.createElement('script');
  // 这里判断了是否使用自定义的 单文件作为库加载,对库的优化压缩文件
  if (c.SingleEngineFile && !c.engineDir) {
  s.src = c.SingleEngineFile;
  }
  else if (c.engineDir && !c.SingleEngineFile) {

  s.src = c.engineDir + 'platform/jsloader.js';
  }
  else {
  alert('You must specify either the single engine file OR the engine directory in "cocos2d.js"');
  }
  document.ccConfig = c;
  s.id = 'cocos2d-html5';
  // 将脚本加载到当前文档,地址是 jsloader.js 的实际地址
  d.body.appendChild(s);
  });
  jsloader.js 里面设置了一堆需要加载的可执行脚本,保存在 engine 变量之中,在文件的最后,我们能够看到这样的代码:

  // 将所有的 appFiles 添加到 engine 中,返回到新定义的变量 que 之中
  var que = engine.concat(c.appFiles);
  que.push('main.js');
  ...
  // 后面一个 for 循环,添加所有文件到 document 中去
  由以上代码,便将我们自定义的使用脚本和 main.js 添加进去了,而最后执行的也是 main.js 脚本,游戏的第一个运行场景就由此开始。main.js 里面创建了一个 cocos2dApp 的类型,它 继承(虽然在 js 中没有继承的概念,但有类似于继承的机制) 自 cc.Applicatoin,其中我们看到非常熟悉的函数 applicationDidFinishLaunching ,有这样一段代码:

  // 调用 cc.LoaderScene Loading 界面,用以加载资源
  cc.LoaderScene.preload(g_resources, function () {
  // 当资源加载完毕,回调函数,运行第一个场景,而这个场景是由 cocos2dApp 的构造函数传入
  director.runScene(new this.startScene());
  }, this);

  // main.js 最后一行
  var myApp = new cocos2dApp(GameLayer.scene);
  在 cocos2dApp 的构造函数中,初始化了一些必要信息,并调用了cc.AppController.shareAppController().didFinishLaunchingWithOptions();,这会间接的调用 Application 的 run 方法,从而导致applicationDidFinishLaunching方法被触发。它运行了cc.LoaderScene的 preLoad 方法,这内中就是 Loading 界面的实现了,它传入了一个回调函数,用于确定在资源加载完毕之后启动第一个场景(Loading 其本身也是一个场景)。

  怎样自定义 Loading 界面

  前面我们了解了 Cocos2d-html5 的大致加载流程,而现在我们关注的是 cc.LoaderScene 所在的文件 CCLoader.js 的内部实现。里面定义了 cc.Loader 和 cc.LoaderScene 类型,Loader 内部完成了,对资源加载的所有操作步骤实现,而 LoaderScene 则是对 Loader 的进一步封装,将加载的过程,用一个界面来可视化的实现出,如用一个加载场景,上面一个 Logo 显示,同时显示了当前加载资源的进度百分比。我们要自定义实现 Loading 界面,那就是重新实现 LoaderScene 即可。对于 LoaderScene 的实现比较简单,我们参考其实现,自定义一个 Loader.js 文件,实现 Loader 类,完成自定义Loading 界面的具体实现,其中大多参考(实际是copy)了 LoaderScene 的实现,在其上修改扩充,它完成了修改 Logo 图片,并添加了一个简单的进度条,是加载过程更为一目了然,这里并没有多么炫的效果,但足以让你了解,你该如何自定义一个 Loading 界面(只贴出了相比较 LoaderScene 所修改的部分,但你可以在 【这里】 获取到源码):

  // 这里定义了 Logo 图片的 Base64 编码,至于为什么,后面将会说明,这里的编码内容挺多,故做简写
  logoData = "data:image/png;base64,...";

  Loading = cc.Scene.extend(
  _logo: null,
  _logoTexture: null,
  _texture2d: null,
  _bgLayer: null,
  _label: null,
  _winSize:null,
  _processLayer: null, // 相比 LoaderScene 的实现,添加了两个属性,标示进度条层和进度条长度
  _processLayerLength: null,

  // 构造函数
  ctor: function () {
  this._super();
  this._winSize = cc.Director.getInstance().getWinSize();
  },
  init:function(){
  cc.Scene.prototype.init.call(this);

  // logo 图片和 label 的添加 .. 这里省略,于 LoaderScene 同样

  // 设置进度条层,它就是一个红色颜色层,通过长度来标示加载的进度
  this._processLayerLength = 500;
  this._processLayer = cc.LayerColor.create(cc.c4b(255, 100, 100, 128), 1, 30);
  this._processLayer.setPosition(cc.pAdd(centerPos, cc.p(- this._processLayerLength / 2, -logoHeight / 2 - 50)));
  // 可以启用锚点,并设置以满足自己的需要
  // this._processLayer.ignoreAnchorPointForPosition(false);
  // this._processLayer.setAnchorPoint(cc.p(0, 0));

  this._bgLayer.addChild(this._processLayer);
  },
  // 以下方法的实现并没有跟 LoaderScene 有什么不同
  // _initStage: ...
  // onEnter ...
  // onExit ...
  // initWithResources ...
  // _startLoading ...
  // _logoFadeIn
  // 每帧更新
  _updatePercent: function () {
  var percent = cc.Loader.getInstance().getPercentage();
  var tmpStr = "Loading... " + percent + "%";
  this._label.setString(tmpStr);

  // 设置当前进度条层的长度
  this._processLayer.changeWidth(this._processLayerLength * percent / 100);

  if (percent >= 100)
  this.unschedule(this._updatePercent);
  }
  });
  // 这里于 LoaderScene 的实现同样
  Loading.preload = function (resources, selector, target) {
  if (!this._instance) {
  // 创建一个 Loading
  this._instance = new Loading();
  this._instance.init();
  }
  // ...
  return this._instance;
  };
  这里我们只是 copy 了一份 LoaderScene(copy 修改会让这里的操作步骤简化) ,重新命名 Loading 然后在此基础添加了一个进度条显示,当然这里的 Loading 类完全由你自己定义,它有哪些显示,你可以随意定制,只要在 _updatePercent 方法实时获取当前进度,并且更新到界面显示即可。

  我们注意到在 Loading 文件,定义了一个 logoData 变量,它保存的是一张图片的 Base64 位格式编码,这样做的好处是,在运行显示图片之时,不会出现此图没有加载的情况,但是也由于它是 Base64 编码的图片,所以图片不宜过大,否则编码后的数据量很大,其次解码也需要耗时。

  完成 Loading.js 后,我们需要加载它,并让它运行,以替换 LoaderScene 的运行。首先修改项目 cocos2d.js 文件,在**appFiles**添加 Loading.js 文件。其次修改 main.js 文件内 cc.LoaderScene.preload 为 Loading.preload 即可,刷新 index.html 界面,将能看见 Loading 界面已经替换。它加载速度的快慢取决于游戏资源内容的多少 ~

自定义Cocos2d-html 5 Loading界面代码: // 这里定义了 Logo 图片的 Base64 编码,至于为什么,后面将会说明,这里的编码内容挺多,固做简写 logoData = "data:image/png;base64,..."; Loading = cc.Scene.extend( _logo: null, _logoTexture:


前进区18723517325: 如何自定义 Cocos2d - HTML5 Loading 界面 -
伯牙吾台妍舒肝: 自定义Cocos2d-html 5 Loading界面代码: // 这里定义了 Logo 图片的 Base64 编码,至于为什么,后面将会说明,这里的编码内容挺多,固做简写 logoData = "data:image/png;base64,..."; Loading = cc.Scene.extend( _logo: null, _logoTexture:

前进区18723517325: 如何在自定义文件下创建cocos2d -
伯牙吾台妍舒肝: 在创建Cocos2d-x项目前首先要在电脑中安装配置python2.7.找到安装目录 D:\Program Files\cocos2d-x-3.4\tools\cocos2d-console\bin 打开电脑中的CMD命令窗口,将目录切换到上述安装路径,并输入cocos new -h命令 如果出现以上提示,说明可以开始创建Cocos2d-x项目了.输入如下命令开始创建项目,其中-p表示包名称,-l表示所用语言,-d表示项目保存路径 创建成功后会在设定的项目保存目录下找到项目文件,6 双击上面项目解决方案,即可以打开项目.编译运行可以得到如下界面

前进区18723517325: cocosbuilder怎么自定义类 -
伯牙吾台妍舒肝: 使用自定义类 CocosBuilder的使用方法是通过自定义类.在CocosBuilder中选中一个对象并在属性栏中输入自定义类的类名就可以了.记住你的自定义类必须是你选中对象的一个子类(如CCLayer,CCNode等等) 当加载ccbi文件时,你需要定义...

前进区18723517325: 自定义Cocos2D的菜单问题
伯牙吾台妍舒肝: // Creating menu items MenuItem *start = [MenuItemFont itemFromString:@"Start" target:self selector:@selector(start:)]; MenuItem *settings = [MenuItemFont itemFromString:@"Settings" target:self selector:@selector(settings:)]; MenuItem *...

前进区18723517325: 如何动态设置 Image的Sprite -
伯牙吾台妍舒肝: 步骤如下: 1.新建Cocos2d-win32工程,工程名为"TinySeal",勾选"Box2D"选项(后续文章会使用到),勾选"SimpleAudioEngineinCocosDenshion"选项; 2.打开HelloWorldScene.cpp文件,在添加如下方法: CCSprite*HelloWorld::...

前进区18723517325: 求问如何在cocos2d中使用自定义.ttf格式字体 -
伯牙吾台妍舒肝: 1. 双击打开工程文件的info.plist,如果其中没有UIAppFonts的数据项,则可以直接添加:UIAppFontsInsanibu.ttf 如果其中有UIAppFonts数据项,则可以追加元素UIAppFontsXXX.ttfInsanibu.ttf //这里字体带后缀的全程应该与字体的文件名完全一致...

前进区18723517325: cocos2dx - lua中怎么使用自定义类以及tolua++的使用 -
伯牙吾台妍舒肝: 使用cocos2dx-lua开发,免不了自己定义类,但是如何使用自定义的类的?先了解下lua如何调用c++的:lua脚本代码->通过coocs2dx中间解析层代码->将其转换并调用cocos2dx c++的前端代码coocs2dx中间解析层代码都在libs/lua/cocos2dx_...

前进区18723517325: 如何使用Cocos Code IDE和Cocos2d - x开发《一个都不能落下》游戏 -
伯牙吾台妍舒肝: 摘要: 简介Cocos Code IDE是Cocos2d-x引擎官方团队推出的一款基于Eclipse的跨平台开发环境,专为Cocos2d-x Lua和JavaScript开发人员准备,通过Cocos Code IDE,可方便地创建游戏工程、编写并且调试代码、实时查看代码修改 ... 简介 ...

前进区18723517325: cocos2dx 3.0 怎么在头文件定义 Layout* 的变量 -
伯牙吾台妍舒肝: #include "cocos2d.h"#include "cocos-ext.h"#include "CocosGUI.h" USING_NS_CC; USING_NS_CC_EXT; using namespace ui; 要保证头文件在路径里面 附加包含目录:$(EngineRoot);$(EngineRoot)cocosui;$(EngineRoot)cocos;...

前进区18723517325: cocos2d 自定义调度器怎么传参数 -
伯牙吾台妍舒肝: cocos2d-x 3.0使用了c++11的新特性std::bind,所以我们就可以用这个东西做很多很多的事了.我们可以将要回调的update函数多加上你要的几个参数,但是schedule中得要求函数的参数个数是一个啊,所以就用bind吧.这里用到的CC_CALLBACK

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网