Reputation: 15698
I have a CCLayer
class that is a child of a base class I created that is, itself, a child of CCLayer
.
After creating this type of class hierarchy, I can not get the onEnter
method of my child class to successfully schedule a method call. How can I fix this?
I am trying to get started on a gaming project but I've hit a bit of a brick wall. This seems to be a common problem, however, I can't find a scenario similar to mine and, thus, can't derive a solution.
I have a child CCLayer class that I've created, and it is essentially the exact same thing as the IntroLayer in the Cocos2D, starter iPhone template. In fact, my class is the exact same class with one major exception-- I created a base class that I derived from CCLayer, and that is used as my parent of my IntroLayer.
My problem is that in the onEnter method of my child layer, I see that my transition method is being set in my scheduleOnce
assignment. The problem, though, is that my transition method is never being called?
I'm not sure what I am doing incorrectly. The code posted below is my .m file for a my IntroLayer.
IntroLayer.m
@implementation IntroLayer //Child of "MyBaseCCLayer"
+(CCScene *) scene
{
CCScene *scene = [CCScene node];
IntroLayer *layer = [IntroLayer node];
[scene addChild: layer];
return scene;
}
-(void) onEnter
{
//This is calling an overridden onEnter of my base CCLayer.
// See snippet below.
[super onEnter];
CGSize size = [[CCDirector sharedDirector] winSize];
CCSprite *background;
background = [CCSprite spriteWithFile:@"Default.png"];
[background setPosition:ccp(size.width/2, size.height/2)];
[background setZOrder: Z_BACKGROUND];
[self addChild: background];
//In one second transition to the new scene
// I can put a break point here, and this being set.
// It never gets called, though.
[self scheduleOnce:@selector(makeTransition:) delay:1.0];
}
-(void) makeTransition:(ccTime)delay
{
//Here is where I would transition to my menu.
// This is a fresh project, so it's going to a test screen.
// The problem is this method never fires.
[[CCDirector sharedDirector]
replaceScene:[CCTransitionFade
transitionWithDuration:0.5
scene:[TestLayer scene]
withColor:ccBLACK]];
}
-(void) dealloc
{
[super dealloc];
}
@end
MyBaseCCLayer.m
//^boilerplate snip^
-(void) onEnter
{
//Setup overlay
CGSize size = [[CCDirector sharedDirector] winSize];
ccTexParams tp = {GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT};
//overlay is a class variable, CCSprite object.
overlay = [CCSprite spriteWithFile:@"tile_overlay.png" rect:CGRectMake(0, 0, size.width, size.height)];
[overlay retain];
[overlay setPosition: ccp(size.width/2, size.height/2)];
[overlay.texture setTexParameters:&tp];
//Always on top!
[overlay setZOrder:Z_OVERLAY];
}
-(void) dealloc
{
[overlay release];
[super dealloc];
}
As you can see, there is nothing ground breaking going on here. I created this base class because I want to apply the overlay sprite to ever CCLayer
in my application. This is why it made sense to create my own base, CCLayer
. However, now that I've created my own base class, my IntroLayer
won't call my scheduled method that I'm setting in onEnter
. How can I get this to work?
Upvotes: 0
Views: 539
Reputation: 536
Your custom class MyBaseCCLayer is overriding the onEnter
method, but you omitted the call to [super onEnter]
. It's easy to forget sometimes, but calling [super onEnter]
is critical to the custom class. Here is the description of the method from the Cocos2D documentation:
Event that is called every time the CCNode enters the 'stage'. If the CCNode enters the 'stage' with a transition, this event is called when the transition starts. During onEnter you can't access a sibling node. If you override onEnter, you shall call [super onEnter].
If you take a look inside CCNode.m, you will see what happens inside onEnter
:
-(void) onEnter
{
[children_ makeObjectsPerformSelector:@selector(onEnter)];
[self resumeSchedulerAndActions];
isRunning_ = YES;
}
So you can see that if you override the onEnter
method in your custom class, and you don't call [super onEnter]
, you miss out on this functionality. Essentially your custom node will remain in a 'paused' state.
Upvotes: 2