CCScene一般情況是遊戲裏面的根節點,稱之爲"場景",運行遊戲時需要通過CCDirector啓動第一個場景。當然,遊戲稍微複雜一點的話,可能會包含很多個場景,這就涉及到場景的切換,也是通過CCDirector來完成。CCScene是個抽象的概念,也沒有可視化顯示的功能,對比CCNode,CCScene基本上沒有額外的代碼:
- // CCScene.h
- #import "CCNode.h"
- @interface CCScene : CCNode
- {
- }
- @end
- // CCScene,m
- #import "CCScene.h"
- #import "Support/CGPointExtension.h"
- #import "CCDirector.h"
- @implementation CCScene
- -(id) init
- {
- if( (self=[super init]) ) {
- CGSize s = [[CCDirector sharedDirector] winSize];
- // 設置position不受anchorPoint影響
- self.isRelativeAnchorPoint = NO;
- // 設置anchorPoint
- anchorPoint_ = ccp(0.5f, 0.5f);
- // 設置CCScene的大小爲屏幕大小
- [self setContentSize:s];
- }
- return self;
- }
- @end
可以發現,對比CCNode,CCScene只是重寫了init方法而已,而且也只是做了一個簡單的設置
常用操作
1.運行第一個場景
我們一般是在應用程序代理AppDelegate的applicationDidFinishLaunching:方法結尾處運行遊戲的第一個場景
- [[CCDirector sharedDirector] runWithScene: [HelloWorldLayer scene]];
2.替換場景
- [[CCDirector sharedDirector] replaceScene:scene];
3.推入和彈出場景
我們知道可以用replaceScene:來運行一個新場景,但是會釋放掉舊場景的內存。有時候我們希望在不釋放舊場景內存的前提下運行一個新場景,這時候就要用到CCDirector的pushScene:和popScene兩個方法了。
1> 使用pushScene:方法推入一個新場景,新場景會層疊在舊場景的上面,但並沒有釋放舊場景的內存,舊場景繼續保留在內存中
- [[CCDirector sharedDirector] pushScene:scene];
2> 使用popScene方法彈出最上層的場景並釋放其內存,使保留在內存中的舊場景重新顯示出來
- [[CCDirector sharedDirector] popScene];
CCTransitionScene
上面介紹了場景的切換,不過都是瞬間完成的,有時候我們想在場景切換的時候有些過渡效果,即以動畫的形式切換場景,我們稱之爲"場景過渡"。要想做場景過渡效果,就必須用CCTransitionScene的子類,CCTransitionScene本身繼承了CCScene,它包含了非常多的子類,每個子類都有不同的場景過渡效果,比如CCTransitionFade是淡入淡出效果,CCTransitionPageTurn是翻頁效果。
下面演示一個翻頁效果:
- CCTransitionPageTurn *page = [CCTransitionPageTurn transitionWithDuration:0.5 scene:scene];
- [[CCDirector sharedDirector] replaceScene:page];
cocos2d中有非常多的過渡效果可以使用,都是CCTransitionScene的子類,類名一般都是以CCTransition開頭的。我就不在這裏一一介紹每個子類有什麼效果,也沒有必要,用到時自己再去查API吧。
注意:CCTransitionScene只能使用在replaceScene:和pushScene:的時候,在popScene彈出場景時是不能用這個過渡效果的
節點的生命週期
說到場景過渡,那就不得不說一下節點的生命週期,即一個節點從開始被添加到屏幕上 到 從屏幕中移除的過程,CCNode提供了相應的生命週期方法:
- // 節點被添加到屏幕上 或者 重新顯示到屏幕上 時調用
- -(void) onEnter;
- // 調用完onEnter後就會調用此方法,如果使用了場景過渡效果,將在場景過渡完畢後才調用此方法
- -(void) onEnterTransitionDidFinish;
- // 節點從屏幕中移除 或者 暫時離開屏幕 時調用
- -(void) onExit;
下面演示在場景切換時,節點生命週期方法的調用順序
假設有2個圖層RedLayer和BlueLayer,它們分別在不同的場景中。點擊RedLayer,就推入BlueLayer所在的場景,點擊BlueLayer就彈出BlueLayer所在的場景。我們就在場景切換的過程中觀察這2個圖層的生命週期。
爲了區分這2個圖層,我讓它們繼承了CCLayerColor,分別設置不用的背景顏色,RedLayer爲紅色,BlueLayer爲藍色。
因爲RedLayer和BlueLayer都繼承CCLayerColor,而且都需要負責創建自己的圖層、負責觀察生命週期方法的調用,那麼我就先抽出一個繼承了CCLayerColor的公共父類BaseLayer,在它裏面完成一些公共操作,然後讓RedLayer和BlueLayer都繼承它
BaseLayer的代碼
- // BaseLayer.h
- #import "cocos2d.h"
- @interface BaseLayer : CCLayerColor
- // 用來創建圖層所在的場景
- + (CCScene *)scene;
- // 圖層的背景顏色,交給子類去實現
- + (ccColor4B)bgColor;
- @end
- // BaseLayer.m
- #import "BaseLayer.h"
- @implementation BaseLayer
- #pragma mark - 初始化場景
- + (CCScene *)scene {
- // 獲取當前類的背景顏色
- ccColor4B color = [self bgColor];
- // 根據當前類名創建圖層
- BaseLayer *layer = [[self class] layerWithColor:color];
- // 接收觸摸輸入
- layer.isTouchEnabled = YES;
- CCScene *scene = [CCScene node];
- [scene addChild:layer];
- return scene;
- }
- #pragma mark - 打印生命週期方法
- - (void)onEnter { // _cmd 代表着當前的selector
- [super onEnter];
- // 第一個%@是打印類名,第二個%@是打印方法名
- NSLog(@"%@ --> %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd));
- }
- - (void)onEnterTransitionDidFinish {
- [super onEnterTransitionDidFinish];
- NSLog(@"%@ --> %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd));
- }
- - (void)onExit {
- [super onExit];
- NSLog(@"%@ --> %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd));
- }
- @end
RedLayer的代碼
- // RedLayer.h
- #import "BaseLayer.h"
- @interface RedLayer : BaseLayer
- @end
- // RedLayer.m
- #import "RedLayer.h"
- #import "BlueLayer.h"
- @implementation RedLayer
- #pragma mark - 點擊紅色圖層時,跳到藍色圖層所在的場景
- - (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
- // 初始化藍色圖層所在的場景
- CCScene *scene = [BlueLayer scene];
- // 推入場景(暫時沒有使用過渡效果)
- [[CCDirector sharedDirector] pushScene:scene];
- }
- #pragma mark - 背景顏色爲紅色
- + (ccColor4B)bgColor {
- return ccc4(255, 0, 0, 255);
- }
- @end
BlueLayer的代碼
- // BlueLayer.h
- #import "BaseLayer.h"
- @interface BlueLayer : BaseLayer
- @end
- // BlueLayer.m
- #import "BlueLayer.h"
- @implementation BlueLayer
- #pragma mark - 當點擊藍色圖層時,彈出場景
- - (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
- [[CCDirector sharedDirector] popScene];
- }
- #pragma mark - 背景顏色爲藍色
- + (ccColor4B)bgColor {
- return ccc4(0, 0, 255, 255);
- }
- @end
1.在應用程序加載完畢後,即在AppDelegate的applicationDidFinishLaunching:方法中啓動第一個場景 ---- 紅色圖層所在的場景
- [[CCDirector sharedDirector] runWithScene: [RedLayer scene]];
運行完畢後,效果如下:
生命週期方法打印如下:
- 2013-02-22 15:47:56.473 HelloWorld[2679:c07] RedLayer --> onEnter
- 2013-02-22 15:47:56.474 HelloWorld[2679:c07] RedLayer --> onEnterTransitionDidFinish
2.點擊紅色圖層,跳到藍色圖層所在的場景
這裏根據有沒有使用過渡效果,要分2種情況
1> 如果沒有使用過渡效果
屏幕直接變爲藍色
生命週期方法打印如下:
- 2013-02-22 15:50:16.381 HelloWorld[2679:c07] RedLayer --> onExit
- 2013-02-22 15:50:16.382 HelloWorld[2679:c07] BlueLayer --> onEnter
- 2013-02-22 15:50:16.384 HelloWorld[2679:c07] BlueLayer --> onEnterTransitionDidFinish
2> 如果使用了過渡效果
先改變下RedLayer中的代碼:
- #pragma mark - 點擊紅色圖層時,跳到藍色圖層所在的場景
- - (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
- // 初始化藍色圖層所在的場景
- CCScene *scene = [BlueLayer scene];
- // 舊場景一邊旋轉一邊縮小,新場景一邊旋轉一邊方法
- CCTransitionRotoZoom *page = [CCTransitionRotoZoom transitionWithDuration:2 scene:scene];
- // 推入場景(暫時沒有使用過渡效果)
- [[CCDirector sharedDirector] pushScene:page];
- }
過渡效果剛開始就會打印:
- 2013-02-22 15:59:38.420 HelloWorld[2862:c07] BlueLayer --> onEnter
然後中間經歷了長達2s的過渡效果:
紅色是在一邊旋轉一邊縮小
紅色完全消失後,藍色在一邊旋轉一邊放大
藍色放大到屏幕大小後
最後會出現以下打印信息:
- 2013-02-22 16:04:28.852 HelloWorld[2910:c07] RedLayer --> onExit
- 2013-02-22 16:04:28.853 HelloWorld[2910:c07] BlueLayer --> onEnterTransitionDidFinish
3> 點擊藍色圖層,彈出藍色圖層所在的場景,重新顯示紅色圖層所在的場景
打印信息如下:
- 2013-02-22 16:06:47.013 HelloWorld[2910:c07] BlueLayer --> onExit
- 2013-02-22 16:06:47.014 HelloWorld[2910:c07] RedLayer --> onEnter
- 2013-02-22 16:06:47.015 HelloWorld[2910:c07] RedLayer --> onEnterTransitionDidFinish
移除藍色,重新顯示紅色
原文地址:http://blog.csdn.net/q199109106q/article/details/8602106
感謝作者~!