如何自定义 Cocos2d-html5 Loading 界面

2025-04-22 21:56:59
推荐回答(2个)
回答1:

要自定义实现 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;
};

回答2:

自定义Cocos2d-html 5 Loading界面代码:

// 这里定义了 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;
};