Floating HUD layer over a box2d world

Forums Programming cocos2d support (graphics engine) Floating HUD layer over a box2d world

This topic contains 6 replies, has 3 voices, and was last updated by  andrew 3 years ago.

Viewing 7 posts - 1 through 7 (of 7 total)
Author Posts
Author Posts
April 17, 2011 at 12:09 pm #230473

simonread
@simonread

Hey guys, I am pretty new to Cocos2D and am trying to put together a simple sidescrolling platform game for a university project. I have been following this excellent tutorial in order to get my box2d game ‘world’ up and running:

http://www.uchidacoonga.com/2011/03/simple-platformer-using-cocos2d-and-box2d-with-collision-detection/

I am pretty sure this is using Cocos2D v0.99.5-rc1, and I am designing for the iPhone 4.3 iOS.

I’m trying to add a basic HUD to my game that contains a few buttons to control the player, along with a Pause button. From what I have read by searching this forum the best approach to this is to create another Scene and then have it ‘floating’ on a separate layer above the game world. Ideally the HUD would stay stationary and the game world would be moving back and forth under it. Currently I’ve got a GameHUD.h and GameHUD.mm set up with my pause button as a CCMenuItem.

In my GameScene.mm file I have added an #import for GameHUD.h and used the following code:

+(id) scene
{
// 'scene' is an autorelease object.
CCScene *scene = [CCScene node];

// 'layer' is an autorelease object.
GameScene *layer = [GameScene node];
GameHUD *hudlayer = [GameHUD node];

// add layer as a child to scene
[scene addChild: layer z:1];
[scene addChild: hudlayer z:2];

In theory the hudlayer with the pause button on it should be appearing above the game world. However I am not seeing this when I run it in the iPhone Simulator, only the box2d game world with no sign of the HUD. Can anybody help me figure out why this isn’t happening as it should?

April 17, 2011 at 12:57 pm #325812

badawe
Participant
@badawe

I do that with 2 layers, you don’t need another scene, just create another class like InterfaceLayer, and add that in your actual scene!

April 17, 2011 at 1:05 pm #325813

simonread
@simonread

Thanks for the quick reply badawe. Could you possibly explain a little more detail how you achieved that? How would I go about setting up the InterfaceLayer and making sure it stayed above my game layer?

April 17, 2011 at 1:17 pm #325814

badawe
Participant
@badawe

Like a new project using Cocos2D template, you have something like that right?

This is your HelloWorldLayer.m:

//
// HelloWorldLayer.m
// Example
//
// Created by Bruno Mikoski on 17/04/11.
// Copyright Midia Digital 2011. All rights reserved.
//

// Import the interfaces
#import "HelloWorldLayer.h"

// HelloWorldLayer implementation
@implementation HelloWorldLayer

+(CCScene *) scene
{
// 'scene' is an autorelease object.
CCScene *scene = [CCScene node];

// 'layer' is an autorelease object.
HelloWorldLayer *layer = [HelloWorldLayer node];

// add layer as a child to scene
[scene addChild: layer];

// return the scene
return scene;
}

// on "init" you need to initialize your instance
-(id) init
{
// always call "super" init
// Apple recommends to re-assign "self" with the "super" return value
if( (self=[super init])) {

// create and initialize a Label
CCLabelTTF *label = [CCLabelTTF labelWithString:@"Hello World" fontName:@"Marker Felt" fontSize:64];

// ask director the the window size
CGSize size = [[CCDirector sharedDirector] winSize];

// position the label on the center of the screen
label.position = ccp( size.width /2 , size.height/2 );

// add the label as a child to this Layer
[self addChild: label];
}
return self;
}

// on "dealloc" you need to release all your retained objects
- (void) dealloc
{
// in case you have something to dealloc, do it in this method
// in this particular example nothing needs to be released.
// cocos2d will automatically release all the children (Label)

// don't forget to call "super dealloc"
[super dealloc];
}
@end

Sou you create a new file -> Objective-C Class ->Subclass of CCLayer -> Save as NewLayer

In your new layer in .h file, you must add cocos2d. And your .m its like that:

//
// NewLayer.m
// Example
//
// Created by Bruno Mikoski on 17/04/11.
// Copyright 2011 Midia Digital. All rights reserved.
//

#import "NewLayer.h"

@implementation NewLayer

// on "init" you need to initialize your instance
-(id) init
{
// always call "super" init
// Apple recommends to re-assign "self" with the "super" return value
if( (self=[super init])) {

// create and initialize a Label
CCLabelTTF *label = [CCLabelTTF labelWithString:@"Another Layer" fontName:@"Marker Felt" fontSize:64];

// ask director the the window size
CGSize size = [[CCDirector sharedDirector] winSize];

// position the label on the center of the screen
label.position = ccp( size.width /2 , size.height/2 );

// add the label as a child to this Layer
[self addChild: label];
}
return self;
}

// on "dealloc" you need to release all your retained objects
- (void) dealloc
{
// in case you have something to dealloc, do it in this method
// in this particular example nothing needs to be released.
// cocos2d will automatically release all the children (Label)

// don't forget to call "super dealloc"
[super dealloc];
}

@end

And in your HelloWorldLayer.m

you do something like that:

//
// HelloWorldLayer.m
// Example
//
// Created by Bruno Mikoski on 17/04/11.
// Copyright Midia Digital 2011. All rights reserved.
//

// Import the interfaces
#import "HelloWorldLayer.h"
#import "NewLayer.h"// <- Import your new layer

// HelloWorldLayer implementation
@implementation HelloWorldLayer

+(CCScene *) scene
{
// 'scene' is an autorelease object.
CCScene *scene = [CCScene node];

// 'layer' is an autorelease object.
HelloWorldLayer *layer = [HelloWorldLayer node];

// add layer as a child to scene
[scene addChild: layer];

NewLayer *_newLayer = [[NewLayer alloc] init];
[scene addChild:_newLayer]; // <- ADD new layer to your scene!

// return the scene
return scene;
}

// on "init" you need to initialize your instance
-(id) init
{
// always call "super" init
// Apple recommends to re-assign "self" with the "super" return value
if( (self=[super init])) {

// create and initialize a Label
CCLabelTTF *label = [CCLabelTTF labelWithString:@"Hello World" fontName:@"Marker Felt" fontSize:64];

// ask director the the window size
CGSize size = [[CCDirector sharedDirector] winSize];

// position the label on the center of the screen
label.position = ccp( size.width /2 , size.height/2 );

// add the label as a child to this Layer
[self addChild: label];

}
return self;
}

// on "dealloc" you need to release all your retained objects
- (void) dealloc
{
// in case you have something to dealloc, do it in this method
// in this particular example nothing needs to be released.
// cocos2d will automatically release all the children (Label)

// don't forget to call "super dealloc"
[super dealloc];
}
@end

April 17, 2011 at 3:02 pm #325815

simonread
@simonread

Thanks for the explanation badawe.

I’ve implemented your code on my game’s menu Scene, as a test, and got the NewLayer to show up fine. However when I try and set it up within my gameplay scene it does not show up. The code doesn’t throw any kind of error either, so it is difficult to work out what is going on here. I’m guessing that box2d is the issue here. I have tried altering the ‘z’ value of each of the two layers, giving the NewLayer some crazy high value like 999, but the game layer still seems to be being placed on top of my HUD layer.

Do you have any thoughts or ideas as to what could be causing this? Does box2d and box2d worlds have a different method of creating/organising layers compared to a more basic Cocos2d Scene?

April 24, 2011 at 2:22 pm #325816

simonread
@simonread

I have spent the last week or so working on this issue and I still cannot see what the problem is. Can anyone see what could be going wrong with my ‘game’ and ‘HUD’ layers here?

April 24, 2011 at 2:48 pm #325817

andrew
Participant
@andrew95

@badawe

NewLayer *_newLayer = [[NewLayer alloc] init];
[scene addChild:_newLayer]; // <- ADD new layer to your scene!

would cause a memory leak – you should use [NewLayer node]; instead of [[NewLayer alloc] init];

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

You must be logged in to reply to this topic.