COCOS2D(4) 使用过渡场景在多个场景的切换

CCNode有三个方法,使用CCDirector的replaceScene方法替换场景时,每个节点都会调用这三个方法:

onEnter与onExit方法在改变场景过程中的特定时刻被调用,这取决于是否使用CCTransitionScene。

onEnterTransitionDidFinish方法在替换结束时调用。

必须总是调用这些方法的超类实现来避免难输入问题和内存泄漏。

 

-(void) onEnter  
{  
    CCLOG(@"%@: %@", NSStringFromSelector(_cmd), self);  
      
    // must call super here:  
    [super onEnter];  
}  
  
-(void) onEnterTransitionDidFinish  
{  
    CCLOG(@"%@: %@", NSStringFromSelector(_cmd), self);  
      
    // must call super here:  
    [super onEnterTransitionDidFinish];  
}  
  
-(void) onExit  
{  
    CCLOG(@"%@: %@", NSStringFromSelector(_cmd), self);  
      
    // must call super here:  
    [super onExit];  
}

 

编写过渡场景:

LoadingScene充当一个中间场景的角色,它是cocos2d中的CCScene类的派生类,不必为每一次场景创建一个新的LoadingScene。

代码清单:LoadingScene.h

#import <Foundation/Foundation.h>  
#import "cocos2d.h"  
  
typedef enum  
{  
    TargetSceneINVALID = 0,  
    TargetSceneFirstScene,  
    TargetSceneOtherScene,  
    TargetSceneMAX,  
} TargetScenes;  
  
@interface LoadingScene : CCScene {  
      
    TargetScenes targetScene_;  
}  
  
+(id) sceneWithTargetScene:(TargetScenes)targetScene;  
-(id) initWithTargetScene:(TargetScenes)targetScene;  
  
@end

使用enum给各个场景编个号,而且将enum的第一个值设为0,在Objective-c中变量的值会自动初始化为0.并在最后设了个MAX值。

代码清单:LoadingScene.m

#import "LoadingScene.h"  
#import "MyFirstScene.h"  
#import "OtherScene.h"  
  
@interface LoadingScene (PrivateMethods)  
-(void) update:(ccTime)delta;  
@end  
  
@implementation LoadingScene  
+(id) sceneWithTargetScene:(TargetScenes)targetScene;  
{  
    CCLOG(@"===========================================");  
    CCLOG(@"%@: %@", NSStringFromSelector(_cmd), self);  
      
    // This creates an autorelease object of self (the current class: LoadingScene)  
    return [[[self alloc] initWithTargetScene:targetScene] autorelease];  
      
    // Note: this does the exact same, it only replaced self with LoadingScene. The above is much more common.  
    //return [[[LoadingScene alloc] initWithTargetScene:targetScene] autorelease];  
}  
  
-(id) initWithTargetScene:(TargetScenes)targetScene  
{  
    if ((self = [super init]))  
    {  
        targetScene_ = targetScene;  
          
        CCLabelTTF* label = [CCLabelTTF labelWithString:@"Loading ..." fontName:@"Marker Felt" fontSize:64];  
        CGSize size = [[CCDirector sharedDirector] winSize];  
        label.position = CGPointMake(size.width / 2, size.height / 2);  
        [self addChild:label];  
          
        // Must wait one frame before loading the target scene!  
        // Two reasons: first, it would crash if not. Second, the Loading label wouldn't be displayed.  
        [self scheduleUpdate];  
    }  
      
    return self;  
}  
  
-(void) update:(ccTime)delta  
{  
    // It's not strictly necessary, as we're changing the scene anyway. But just to be safe.  
    [self unscheduleAllSelectors];  
      
    // Decide which scene to load based on the TargetScenes enum.  
    // You could also use TargetScene to load the same with using a variety of transitions.  
    switch (targetScene_)  
    {  
        case TargetSceneFirstScene:  
            [[CCDirector sharedDirector] replaceScene:[MyFirstScene scene]];  
            break;  
        case TargetSceneOtherScene:  
            [[CCDirector sharedDirector] replaceScene:[OtherScene scene]];  
            break;  
              
        default:  
            // Always warn if an unspecified enum value was used. It's a reminder for yourself to update the switch  
            // whenever you add more enum values.  
            NSAssert2(nil, @"%@: unsupported TargetScene %i", NSStringFromSelector(_cmd), targetScene_);  
            break;  
    }  
      
    // Tip: example usage of the INVALID and MAX enum values to iterate over all enum values  
    for (TargetScenes i = TargetSceneINVALID + 1; i < TargetSceneMAX; i++)  
    {  
    }  
}  
  
-(void) dealloc  
{  
    CCLOG(@"%@: %@", NSStringFromSelector(_cmd), self);  
      
    // don't forget to call "super dealloc"  
    [super dealloc];  
}  
@end

由于LoadingScene类由CCScene派生出来,所以不需要调用[CCScene node],sceneWithTargetScene方法先为self分配空间,然后调用initWithTargetScene初始化

在MyFirstScene中调用LoadingScene:

CCScene *newScene = [LoadingScene sceneWithTargetScene:TargetSceneOtherScene];  
[[CCDirector sharedDirector] replaceScene:newScene];

在OtherScene中调用基本类似,请读者自行实践。

下面给出了在执行过程中的一些输出信息,它详细的说明了各个方法的调用顺序:

2012-10-06 13:50:03.404 MutiScene[1884:1be03] ===========================================  
2012-10-06 13:50:03.405 MutiScene[1884:1be03] scene: MyFirstScene  
2012-10-06 13:50:03.406 MutiScene[1884:1be03] init : <MyFirstScene = 0x94e2540 | Tag = -1>  
2012-10-06 13:50:08.610 MutiScene[1884:1be03] cocos2d: animation started with frame interval: 60.00  
2012-10-06 13:50:08.613 MutiScene[1884:1be03] cocos2d: surface size: 480x320  
2012-10-06 13:50:08.614 MutiScene[1884:1be03] onEnter: <MyFirstScene = 0x94e2540 | Tag = -1>  
2012-10-06 13:50:08.615 MutiScene[1884:1be03] onEnterTransitionDidFinish: <MyFirstScene = 0x94e2540 | Tag = -1>  
2012-10-06 13:50:11.844 MutiScene[1884:1be03] ===========================================  
2012-10-06 13:50:11.845 MutiScene[1884:1be03] scene: OtherScene  
2012-10-06 13:50:11.846 MutiScene[1884:1be03] init: <OtherScene = 0x9418280 | Tag = -1>  
2012-10-06 13:50:16.907 MutiScene[1884:1be03] onEnter: <OtherScene = 0x9418280 | Tag = -1>  
2012-10-06 13:50:19.944 MutiScene[1884:1be03] onExit: <MyFirstScene = 0x94e2540 | Tag = -1>  
2012-10-06 13:50:19.945 MutiScene[1884:1be03] onEnterTransitionDidFinish: <OtherScene = 0x9418280 | Tag = -1>  
2012-10-06 13:50:19.947 MutiScene[1884:1be03] dealloc : <MyFirstScene = 0x94e2540 | Tag = -1>  
2012-10-06 13:50:29.953 MutiScene[1884:1be03] ===========================================  
2012-10-06 13:50:29.954 MutiScene[1884:1be03] sceneWithTargetScene:: LoadingScene  
2012-10-06 13:50:29.961 MutiScene[1884:1be03] onExit: <OtherScene = 0x9418280 | Tag = -1>  
2012-10-06 13:50:29.962 MutiScene[1884:1be03] dealloc: <OtherScene = 0x9418280 | Tag = -1>  
2012-10-06 13:50:29.977 MutiScene[1884:1be03] ===========================================  
2012-10-06 13:50:29.979 MutiScene[1884:1be03] scene: MyFirstScene  
2012-10-06 13:50:29.980 MutiScene[1884:1be03] init : <MyFirstScene = 0x9418280 | Tag = -1>  
2012-10-06 13:50:35.031 MutiScene[1884:1be03] dealloc: <LoadingScene = 0x11a59950 | Tag = -1>  
2012-10-06 13:50:35.032 MutiScene[1884:1be03] onEnter: <MyFirstScene = 0x9418280 | Tag = -1>  
2012-10-06 13:50:35.032 MutiScene[1884:1be03] onEnterTransitionDidFinish: <MyFirstScene = 0x9418280 | Tag = -1>

 

 

 

 

posted @ 2012-10-06 17:03  orangef  阅读(637)  评论(0编辑  收藏  举报