cocos2d js 3.7 runScene问题

时间:2015-08-11 12:51:29

标签: javascript cocos2d-x cocos2d-js

所以我将我的游戏从cocos2d c ++移植到js并且已经对很多js相关的差异进行了排序,但是无法理解也无法在线找到涉及使用cc.director.runScene()切换场景的特定问题的解决方案。

所以我有一个复杂的游戏场景,我加载:

cc.LoaderScene.preload(gameplay_resources, function () {

    cc.director.runScene(new GameScene(level, epoch));
}, this);

获取舞台和等级参数并返回包含所有游戏元素的场景对象。

游戏场景片段如下所示:

var GameNode = cc.Node.extend({
levelID:null,
epoch:null,
platforms:null,
boardSize:null,
numberOfMovesLeft:null,
numberOfMovesAllowed:null,
sessionInfo:null,
ctor:function (levelID, epochID)
{
    this._super();

    this.levelID = levelID;
    this.setEpoch(Epoch.epochForNumber(epochID));
    this.platforms = [];

    var self = this;

    var gameplayUI = ccs.load(gameplayRes.GameplayUI, "res/");
    this.addChild(gameplayUI.node);

    var replayButton = gameplayUI.node.getChildByName("replay");
    cc.assert(cc.sys.isObjectValid(replayButton), "Replay button not valid");
    replayButton.addTouchEventListener(function (sender, type) {

        if(type != ccui.Widget.TOUCH_ENDED) return;

        cc.LoaderScene.preload(gameplay_resources, function () {

            cc.director.runScene(new GameScene(self.levelID, self.epoch.ID));
        }, this);

    }, this);

    return true;
}

    //... Other methods

});

var GameScene = cc.Scene.extend({
    ctor:function (levelID, epochID) {
        this._super();
        var gameNode = new GameNode(levelID, epochID);
        this.addChild(gameNode);
    }
});

一切都在场景本身很好地工作,但是如果我用相同的方法将场景更改为主菜单,然后再次进入游戏,它似乎是新的'游戏场景对象具有之前(应该被释放)对象的值。所以,如果我按下重播'按钮,它也使用旧的游戏场景值。

我的意思是在C ++中替换场景时,旧场景的内存由cocos引擎发布。如果你通过创建新对象来进入那个场景 - 它是新的。

所以我的问题是为什么会发生这种情况?也许我不知道有关cocos2d js内存管理的事情,所以我需要做一些额外的事情来释放旧场景?

我所确保的:

  • 当我扩展引擎类时,所有我添加的变量都是空的,并且使用this.value = ...在ctor中分配对象值。不要以这种方式为所有对象提供静态值。
  • 没有孩子保留游戏场景(或者似乎没有),所以我假设它应该在我替换场景时被释放?
  • 我没有使用retain()/ release(),并且所有的孩子都被添加到了gamescene中以供保留。

任何建议都将不胜感激。

干杯!

1 个答案:

答案 0 :(得分:0)

所以我已经解决了 - 我正在使用事件管理器因此发送事件和游戏场景,其子项已经注册了其中一些。我假设eventManager在'弱'的基础上保留节点,但似乎你必须在其onExit方法中为每个注册节点调用removeListeners()来手动删除侦听器。所以现在似乎工作正常。