在onEnter中设置时,scheduleOnce不能在我的CCLayer类上工作

时间:2013-01-24 13:39:33

标签: objective-c cocos2d-iphone scheduler

我有一个 CCLayer 类,它是我创建的基类的子类,它本身就是 CCLayer的子类。

创建此类类层次结构后,我无法获得子类的 onEnter 方法来成功调度方法调用。我该如何解决这个问题?


我正在尝试开始一个游戏项目,但我已经打了一个砖墙。这似乎是一个常见的问题,但是,我无法找到与我类似的情景,因此无法获得解决方案。

我有一个我已创建的子CCLayer类,它与Cocos2D中的IntroLayer完全相同,即启动式iPhone模板。事实上,我的类是完全相同的类,有一个主要的例外 - 我创建了一个我从CCLayer派生的基类,它被用作我的IntroLayer的父类。

我的问题是,在我的子图层的onEnter方法中,我看到我的scheduleOnce作业中正在设置我的转换方法。但问题是我的转换方法永远不会被调用?

我不确定我做错了什么。下面发布的代码是我的.m文件,用于我的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];
}

正如你所看到的,这里没有任何突破性的进展。我创建了这个基类,因为我想在我的应用程序中将覆盖精灵应用到CCLayer。这就是创建我自己的基础CCLayer有意义的原因。但是,既然我已经创建了自己的基类,我的IntroLayer就不会调用我在onEnter设置的预定方法。我怎样才能让它发挥作用?

1 个答案:

答案 0 :(得分:2)

您的自定义类MyBaseCCLayer正在覆盖onEnter方法,但您忽略了对[super onEnter]的调用。有时很容易忘记,但调用[super onEnter]对自定义类至关重要。以下是Cocos2D文档中方法的描述:

  

每次CCNode进入“阶段”时调用的事件。如果   CCNode通过转换进入“阶段”,此事件在调用时调用   过渡开始了。在onEnter期间,您无法访问兄弟   节点。如果你覆盖onEnter,你应该调用[super onEnter]。

如果您查看CCNode.m内部,您会看到onEnter内发生了什么:

-(void) onEnter
{
    [children_ makeObjectsPerformSelector:@selector(onEnter)];
    [self resumeSchedulerAndActions];

    isRunning_ = YES;
}

因此,您可以看到,如果您覆盖自定义类中的onEnter方法,并且未调用[super onEnter],则会错过此功能。基本上,您的自定义节点将保持“暂停”状态。