Communicating between Two Layers in a Scene Cocos2d 3

539 Views Asked by At

I have two layers set up like so in one scene:

header file for scene:

@interface GameScene1 : CCScene {

GameLayer *gameLayer;

HUDLayer *hudLayer;

}

Main file for scene:

-(id)init {

self = [super init];

if (self != nil) {

gameLayer = [GameLayer node];

[self addChild:gameLayer];

hudLayer = [HUDLayer node];

[self addChild:hudLayer];

}

return self;

}

HUD layer header:

@interface HUDLayer : CCNode {

CCSprite *background;

CGSize screenSize;



}
-(void)updateMonstersSlayed:(NSString*)value;

HUD layer main:

@implementation HudLayer
-(id)init
{
    self = [super init];

    if (self)
    {
        CGSize viewSize = [[CCDirector sharedDirector] viewSize];


        monstersSlayed = [CCLabelTTF labelWithString:@"Monsters Killed: 0" fontName:@"Arial" fontSize:15];
        monstersSlayed.position = ccp(viewSize.width * 0.85, viewSize.height * 0.1 );
        [self addChild:monstersSlayed];


    }
    return self;
}
-(void)updateMonstersSlayed:(NSString*)value
{
    monstersSlayed.string = value;
}

Game Layer main

- (BOOL)ccPhysicsCollisionBegin:(CCPhysicsCollisionPair *)pair collisionPlayer:(CCNode *)user collisionMonster:(CCNode *)monster
{
    if (holdingWeapon)
    {

        HudLayer *myHud = [[HudLayer alloc] init];
        [myHud updateMonstersSlayed:@"Monsters Killed: 1"];

    }
}

Simply trying to get it set to where I can set text from the Game Layer to show up in a Label in the Hud Layer.

How would I accomplish this in Cocos2d 3?

3

There are 3 best solutions below

0
On BEST ANSWER

There are many ways you can do this. But for the sake of simplicity the easiest way you can do this is via notifications. For example in the hud add:

@implementation HudLayer

- (void)onEnter
{
    [super onEnter];

    NSNotificationCenter* notiCenter = [NSNotificationCenter defaultCenter];

    [notiCenter addObserver:self
                   selector:@selector(onUpdateMonsterText:)
                       name:@"HudLayerUpdateMonsterTextNotification"
                     object:nil];
}


- (void)onExit
{
    [super onExit];

    [[NSNotificationCenter defaultCenter] removeObserver:self];
}


- (void)onUpdateMonsterText:(NSNotification *)notification
{
    NSDictionary* userInfo = notification.userInfo;

    if (userInfo)
    {
        NSString* text = userInfo[@"text"];

        if (text)
        {
            [self updateMonstersSlayed:text];
        }
        else
        {
            CCLOG(@"Monster hud text param is invalid!.");
        }
    }
    else
    {
        CCLOG(@"Monster hud user info invalid!");
    }
}

@end

Then anywhere in your application where you want to update text you can just post the notification. Using your physics collision began example:

- (BOOL)ccPhysicsCollisionBegin:(CCPhysicsCollisionPair *)pair
    *emphasized text*collisionPlayer:(CCNode *)user collisionMonster:(CCNode *)monster
{
    if (holdingWeapon)
    {
        NSDictionary* userInfo = @{@"text" : @"Monsters Killed: 1"};
        NSString* notiName = @"HudLayerUpdateMonsterTextNotification";

        [[NSNotificationCenter defaultCenter] postNotificationName:notiName
            object:self userInfo:userInfo];

    }
}

Hope this helps.

1
On

You could use delegation, so your scene would implement GameLayerProtocol and the delegate of GameLayer. That way the scene would be notified of any changes the GameLayer has and act appropriately on the HudLayer.

For example:

// GameLayer class

@protocol GameLayerProtocol <NSObject>

- (void)someThingHappenedInGameLayer;

@end

@interface GameLayer : CCNode

@property (nonatomic, weak) id<GameLayerProtocol> delegate;

@end

@implementation GameLayer

- (void)someActionInGameLayer
{
    [self.delegate someThingHappenedInGameLayer];
}

@end

// Scene class

@interface IntroScene : CCScene <GameLayerProtocol>

@end

@implementation IntroScene

// Implement protocol methods
- (void)someThingHappenedInGameLayer
{
   //Do something with your HUDLayer here
}

@end
2
On

You can use methods. Make a method in HUD layer class.

-(void) giveMeMyText:(NSString*)someText
{
   do something with my someText
}

Don't forget to make the method visible in HUD.h -(void) giveMeMyText; Then import HUD layer class in GameScene1 #import "HUDlayer.h" and use it.

HUDLayer* myHud = [[HUDLayer alloc] init];
[myHud giveMeMyText:@"say hi!"];