How to use one HUD layer on multiple scenes?

Forums Programming cocos2d support (graphics engine) How to use one HUD layer on multiple scenes?

This topic contains 5 replies, has 3 voices, and was last updated by  zardon 1 year, 10 months ago.

Viewing 6 posts - 1 through 6 (of 6 total)
Author Posts
Author Posts
May 19, 2012 at 4:48 pm #241659

zardon
Participant
@zardon

I am in the middle of programming a tycoon-like game and have a HUD layer which displays a player’s avatar, cash and other details. Thus it needs to be on more than one scene.

However, I am having a problem, once the HUD has been added to the CCNode, it cannot be added again — so when I move from the Dashboard page to a sub-menu I get an assertion error;

Assertion failure in -[CCMenuItemSprite addChild:z:tag:]

This is pointing to the Avatar image which is part of the HUD.

The HUD layer is basically this;

HUD layer;

- (id)init {

if ((self = [super init]))
{
CGSize winSize = [[CCDirector sharedDirector] winSize];
GameStateManager *state = [GameStateManager sharedGameStateManager];
NSLog(@"listOfPlayers.size = %d", [state.listOfPlayers count]);

// Player 1 data
Player *p = state.humanPlayer;

NSString *txtCash = @"";

// Cash formatting
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterCurrencyStyle];
[formatter setMaximumFractionDigits:0];

if ([p.cash intValue]<1000000) {
txtCash = [NSString stringWithFormat:@"%@", [formatter stringFromNumber:p.cash]];
} else {
double cash = [p.cash doubleValue];
txtCash = [NSString stringWithFormat:@"%@", [state formatCurrencyValue:cash]];
} // end if
[formatter release];

CCLayer *headerLayer = [CCLayer node];
[headerLayer setAnchorPoint:CGPointMake(0, 0.5)];
[headerLayer setPosition:CGPointMake(0, winSize.height-65)];
[headerLayer setContentSize:CGSizeMake(winSize.width, 65)];

// Player avatar
CCSprite *playerSprite = p.spriteOff;
[playerSprite setPosition:CGPointMake(25, 25)];

CCMenuItemSprite *hdrAvatar = [CCMenuItemSprite itemFromNormalSprite:playerSprite selectedSprite:nil target:nil selector:nil];
[hdrAvatar setScale:0.65f];

// Menu
CCMenu *menu = [CCMenu menuWithItems:nil];
[menu setAnchorPoint:CGPointMake(0, 0.5)];
[menu setPosition:CGPointMake(35, 35)];
[menu addChild:hdrAvatar];
[headerLayer addChild:menu];

// add to ccnode
[self addChild:headerLayer];

} // end if
return self;
}

My dashboard page is basic, but calls the HUD like this;

DashboardLayer *layer = [[[DashboardLayer alloc] initWithHUD:hud] autorelease];

-(id) initWithHUD:(HeaderHUDLayer *)hud
{
if ((self = [super init]))
{
NSLog(@"Dashboard page");
_hud = hud;
}
return self;
}

The dashboard has a button, once clicked it goes to a sub-page; whereupon I repeat the process of initWithHUD:hud except that it crashes and returns an assertion error.

I can only think it must be because the avatar sprite has already been added.

I am wondering, what is the correct way to have a HUD layer that will appear on multiple scenes? It would seem that I am doing it wrong.

Thanks

May 19, 2012 at 6:24 pm #377739

Eternity
Participant
@eternity

I think it shall be done as described in this thread.

http://www.cocos2d-iphone.org/forum/topic/32269

I don’t understand your code at a glance, but conceptually I think that your HUD layer shall be instantiated by each scene that needs it. And it shall be destroyed when you leave the scene. To me, the HUD layer only displays HUD information.

I don’t know what your Dashboard layer does, but I think that a scene shall instantiate both the Dashboard layer and the HUD layer if both those layers are needed.

Just my two cents…

May 19, 2012 at 6:51 pm #377740

zardon
Participant
@zardon

You are correct, the hud layer is instantiated by every scene that needs it. I don’t know about destroying it, I always assume Cocos2d cleaned up after itself.

The dashboard is just a bunch of menus, it doesn’t do anything now, I am testing moving from the dashboard page to child pages.

I think it must be the sprite, because I’ve tried removing the CCMenuItemImage and adding the sprite and removing all other content so that the sprite is the only thing in the HUD, and it falls over on any child page.

May 20, 2012 at 6:21 am #377741

cc_dev
Participant
@cc_dev

Should

CCMenu *menu = [CCMenu menuWithItems:nil];
[menu setAnchorPoint:CGPointMake(0, 0.5)];
[menu setPosition:CGPointMake(35, 35)];
[menu addChild:hdrAvatar];

be

CCMenu *menu = [CCMenu menuWithItems: hdrAvatar, nil];
[menu setAnchorPoint:CGPointMake(0, 0.5)];
[menu setPosition:CGPointMake(35, 35)];

?

I’ve never seen it done the first way before, so I’m not sure if that’s what’s causing your problem.

May 21, 2012 at 1:42 pm #377742

zardon
Participant
@zardon

@cc_dev You can make a CCMenu with nil items and then add the items later; this is incredibily useful because a lot of my menus are generated on the fly based off one reason or another.

Just to confirm.

Lets say we have 3 scenes.

1. Dashboard page (main menu)

2. Inventory page (screen showing a list of stuff they have)

3. RPG Shop page (where users buy things from some RPG shop)

I want to move between 1-2 and 3 and use the same HUD for all of them.

June 6, 2012 at 1:23 pm #377743

zardon
Participant
@zardon

I’ve fixed this problem, thanks to the guys from Empire of the Eclipse

Viewing 6 posts - 1 through 6 (of 6 total)

You must be logged in to reply to this topic.