嗯,我得到了一本很棒的 Cocos2d 书,由 Rod Strougo 和 Ray Wenderlich 撰写,书名是“学习 Cocos2d”。在他们的书中,他们使用您的初始设置实现了一个游戏,其中实现了操纵杆等。 GamePlayLayer 包含 JoyStick 和英雄精灵。 (参见本书第 40 页)。
我不相信他们会在书中使用不好的做法,因为他们非常有才华!
...
话虽如此,如果您希望在不同的层上实现它们,我有可能的解决方案:
GameScene
|
|__>GameLayer
|
|__>ControlLayer
这就是你的基本设置。但是,直观地说,控制层的目的是什么?控制游戏层的内容!因此,我建议您在 ControlLayer 中保留对 GameLayer 的(弱)引用。这样,使用一个简单的方法:
@property (nonatomic, assign) CCSprite* hero;
您现在可以从控制层访问英雄了!
额外(如果需要):
//GameScene init:
- (id)init {
....
gameLayer = [GameLayer node];
controlLayer = [ControlLayer node];
[controlLayer setGameLayerRef:gameLayer];
...
}
// Control layer:
@property (nonatomic, assign) GameLayer* gameLayerRef;
尽管我只是建议这样做,但我不会在我的游戏中使用它:)
我通常做的是:
使 GameScene 类成为“半单例”。 (我从 Itterheim 的“学习 iPhone 和 iPad 游戏开发”(又名游戏恐怖、Kobold2d 发行商...等)中学到了这种方法。
然后,在控制层内,我将调用 GameScene 对象:
[[GameScene sharedScene] doSomethingToTheGameLayer];
是的,gameScene 具有简单的方法,仅依赖于游戏层中控件需要更新的内容。
Edit:
实现半单例模式,正如 Itterheim 在他的书中所描述的那样。
但是,什么是半单例呢?
它具有单例模式的属性:您可以使用静态调用从任何地方访问对象实例。
[GameScene sharedScene];
然而,单例对象通常会在第一次创建后被保留,直到应用程序生命周期结束。在半单例模式中,情况并非如此。
一旦创建了实例,您就无法在销毁旧实例之前创建另一个实例,但是一旦您完成了该实例,你销毁它(dealloc)。必要时创建另一个。
回顾:
半单例:从中创建多个对象,但在任何给定时间只能创建一个。只有在摧毁旧的之后才能重新创建。
执行:
当然,就像处理任何单例类一样,首先声明一个与该类相同类型的静态变量:
//In GameScene.m
static GameScene* instance = nil;
@implementation
//Here we have the static method to access the instance:
+(GameScene*)sharedScene {
//you must have created one before trying to access it "Globally".
///Typically, created where you transition the GameScene using CCDirector's replaceScene.
NSAssert(instance != nil, @"GameScene not instantiated!!");
return instance;
}
-(id)init {
if((self = [super init])) {
//Make sure you don't have another instance of the class created
//NOTE: Possible race condition that I wouldn't worry about, since it should never happen.
NSAssert(instance == nil, @"Another instance is already created!!");
instance = self;
...
}
return self;
}
//Don't forget!! Dealloc!!
- (void)dealloc {
//the only instance we had is dealloc'd! We are back to zero. Can create a new one later! :D
instance = nil;
[super dealloc];
}
Edit2:
那么,时间线:
CCScene* scene = [GameScene node];
[[CCDirector sharedDirector] replaceScene:scene];
...
[[GameScene sharedScene] doSomething];
...
[[CCDirector sharedDirector] replaceScene:otherScene];
//After the new scene replaces GameScene, dealloc will be called, implicitly. Making instance = nil;
instance = nil;
[super dealloc];
...
//Loop again
CCScene* scene = [GameScene node];
[[CCDirector sharedDirector] replaceScene:scene];
...