在cocos2d中访问当前场景(安全)的最佳方法是什么?

时间:2013-01-23 00:24:36

标签: iphone objective-c cocos2d-iphone

我正在读学习Cocos2d 2;并且偶然发现了这个问题:在游戏场景中,可能在场景层次结构下面有数千个实体,并且所有这些实体可能想要与最顶层的场景对象进行对话。 Learn Cocos2d 2的作者建议使用像这样的全局变量

static GameLayer* sharedGameLayer;
+(GameLayer*) sharedGameLayer
{
    NSAssert(sharedGameLayer != nil, @"GameScene instance not yet initialized!");
    return sharedGameLayer;
}

+(id) scene
{
    CCScene *scene = [CCScene node];
    GameLayer *layer = [GameLayer node];
    [scene addChild: layer];
    InputLayer* inputLayer = [InputLayer node];
    [scene addChild:inputLayer z:1 tag:GameSceneLayerTagInput];
    return scene;
}

我个人认为这种方法不可靠:想象一个玩家实体想要知道场景中另一层的触摸输入,所以它调用sharedGameLayer并假设它实际上是它所在的父级,只是从那里开始工作。但它怎么能这么肯定呢?如果这个sharedGameLayer是其他人分配的另一个实例怎么办?当然在cocos2d中一次只能有一个场景,所以这种方法大部分时间都可以正常工作而没有任何问题。但从设计的角度来看,我仍然觉得这种做法缺乏。

我考虑过两种选择:

  1. 使用适当的(旧)委托方法。在每个级别分配正确的委托/委托者关系。但是,这意味着数千行可能重复的代码,并且从我的角度看并不整洁

  2. 使用NSNotification(或KVO?)从子级别广播消息,并让父母做出相应的响应。但这是否意味着系统不必要的开销

  3. 此时我很遗憾,有人可以告诉我有经验的程序员可能会使用的一般习语吗?

2 个答案:

答案 0 :(得分:1)

您可能需要阅读我的“Strategies for accessing other nodes in the hierarchy”指南。有很多选择,有利有弊。

答案 1 :(得分:0)

在大多数情况下,CCNode s树的叶子,就像您提到的“玩家实体”一样,只有在{{1}上包含CCScene时才会持续存在。场景堆栈。一旦弹出此场景,它将收到CCDirector消息,从而dealloc(其)removeAll。这反过来将Children这些孩子,包括你的“玩家权利”。您的“玩家实体”将收到的最后一条消息是dealloc,在此期间所有父节点仍处于活动状态(尽管在被破坏的过程中),因此永远不会出现儿童请求无效dealloc的情况。 1}}。但是,如果你想把任何孩子带到另一个场景,你必须在很多方面都非常小心,如果不是绝对必要,这几乎不值得鼓励。例如,您的特定代码块必须进行改进,以便sharedGameLayer如果场景不再处于活动状态将返回sharedGameLayer,并且您的“播放器实体”可能想要检查此返回值。 / p>

简短的回答是,只要您不在场景堆栈中移动节点,上面显示的代码就是安全的。各个节点有许多替代方法可以了解游戏的“图表”,包括每个nil的{​​{1}}属性以及parent的{​​{1}}属性

相关问题