访问其他图层中的对象(cocos2d)

时间:2012-03-01 17:46:32

标签: cocos2d-iphone ccsprite

我正在玩一个操纵杆,在一层中移动一个Sprite。现在,根据最佳实践,操纵杆和雪碧必须位于同一场景的不同层中。我已经设法将这些分开,但我现在完全不知道如何将操纵杆命令从一层传递到另一层?建议的方法是什么?

场景

  • 游戏玩法层
    • 的Sprite
  • 游戏控制层
    • 操纵杆

当操纵操纵杆时,我需要将此信息传递给GamePlayLayer来控制精灵。

1 个答案:

答案 0 :(得分:5)

好吧,我收到了一本很棒的Cocos2d书,由Rod Strougo和Ray Wenderlich撰写,名为“Learning Cocos2d”。在他们的书中,他们使用您的初始设置实现了一个游戏,其中实现了操纵杆。 GamePlayLayer包含joyStick和英雄精灵。 (参见第40页)。

我不相信他们会在书中使用不良做法,因为他们非常有才能!

...

话虽如此,如果您希望在不同的层上实现它们,我有可能的解决方案:

GameScene
|
|__>GameLayer
|
|__>ControlLayer

这是你的基本设置。但是,直观地说,控制层的目的是什么?控制游戏层的内容!所以,我建议你在ControlLayer中持有(弱)对GameLayer的引用。这样,使用简单的:

@property (nonatomic, assign) CCSprite* hero;

您现在可以从ControlLayer访问英雄了!

额外(如果需要):

//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有简单的方法,它只依赖于控件在游戏层中需要更新的内容。


编辑:

实施半单身模式,正如Itterheim在他的书中描述的那样。

但是,什么是半单身?

它具有单例模式的属性:您可以使用静态调用从任何地方访问对象实例。

[GameScene sharedScene];

但是,单例对象通常在第一次创建后保留,直到应用程序生命周期结束。在半单身模式中,情况并非如此。

创建实例后,在销毁旧实例之前无法创建另一个实例,但是一旦完成实例,就会销毁它(dealloc)。必要时创建另一个。

回顾: Semi-Singleton:从中创建许多对象,但在任何给定时间只能创建一个。只有在摧毁旧版后重新创建。

实现:

当然,正如您对任何单例类所做的那样,首先要声明一个类相同类型的静态变量:

//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];
...