cocos2D(七)---- CCScene

CCScene一般情況是遊戲裏面的根節點,稱之爲"場景",運行遊戲時需要通過CCDirector啓動第一個場景。當然,遊戲稍微複雜一點的話,可能會包含很多個場景,這就涉及到場景的切換,也是通過CCDirector來完成。CCScene是個抽象的概念,也沒有可視化顯示的功能,對比CCNode,CCScene基本上沒有額外的代碼:

[java] view plaincopy
  1. // CCScene.h  
  2. #import "CCNode.h"  
  3.   
  4. @interface CCScene : CCNode  
  5. {  
  6. }  
  7. @end  



[java] view plaincopy
  1. // CCScene,m  
  2. #import "CCScene.h"  
  3. #import "Support/CGPointExtension.h"  
  4. #import "CCDirector.h"  
  5.   
  6. @implementation CCScene  
  7. -(id) init  
  8. {  
  9.     if( (self=[super init]) ) {  
  10.         CGSize s = [[CCDirector sharedDirector] winSize];  
  11.         // 設置position不受anchorPoint影響  
  12.         self.isRelativeAnchorPoint = NO;      
  13.         // 設置anchorPoint  
  14.         anchorPoint_ = ccp(0.5f, 0.5f);  
  15.         // 設置CCScene的大小爲屏幕大小  
  16.         [self setContentSize:s];      
  17.     }  
  18.       
  19.     return self;  
  20. }  
  21. @end  

可以發現,對比CCNode,CCScene只是重寫了init方法而已,而且也只是做了一個簡單的設置


常用操作

1.運行第一個場景

我們一般是在應用程序代理AppDelegate的applicationDidFinishLaunching:方法結尾處運行遊戲的第一個場景

[java] view plaincopy
  1. [[CCDirector sharedDirector] runWithScene: [HelloWorldLayer scene]];  
這裏的[HelloWorldLayer scene]返回的是一個CCScene對象


2.替換場景

[java] view plaincopy
  1. [[CCDirector sharedDirector] replaceScene:scene];  
這個方法會用新的場景替換舊的場景,cocos2d會釋放舊場景的內存,刪除舊場景中所有的節點,停止所有動作和消息調度,因此我們不用手動釋放舊場景的內存


3.推入和彈出場景

我們知道可以用replaceScene:來運行一個新場景,但是會釋放掉舊場景的內存。有時候我們希望在不釋放舊場景內存的前提下運行一個新場景,這時候就要用到CCDirector的pushScene:和popScene兩個方法了。

1> 使用pushScene:方法推入一個新場景,新場景會層疊在舊場景的上面,但並沒有釋放舊場景的內存,舊場景繼續保留在內存中

[java] view plaincopy
  1. [[CCDirector sharedDirector] pushScene:scene];  

2> 使用popScene方法彈出最上層的場景並釋放其內存,使保留在內存中的舊場景重新顯示出來

[java] view plaincopy
  1. [[CCDirector sharedDirector] popScene];  


CCTransitionScene

上面介紹了場景的切換,不過都是瞬間完成的,有時候我們想在場景切換的時候有些過渡效果,即以動畫的形式切換場景,我們稱之爲"場景過渡"。要想做場景過渡效果,就必須用CCTransitionScene的子類,CCTransitionScene本身繼承了CCScene,它包含了非常多的子類,每個子類都有不同的場景過渡效果,比如CCTransitionFade是淡入淡出效果,CCTransitionPageTurn是翻頁效果。

下面演示一個翻頁效果:

[java] view plaincopy
  1. CCTransitionPageTurn *page = [CCTransitionPageTurn transitionWithDuration:0.5 scene:scene];  
  2. [[CCDirector sharedDirector] replaceScene:page];  
意思是在0.5秒的時間內使用翻頁效果從舊場景過渡到scene這個新場景,因爲CCTransitionScene是CCScene的子類,所以可以作爲replaceScene:的參數。

cocos2d中有非常多的過渡效果可以使用,都是CCTransitionScene的子類,類名一般都是以CCTransition開頭的。我就不在這裏一一介紹每個子類有什麼效果,也沒有必要,用到時自己再去查API吧。

意:CCTransitionScene只能使用在replaceScene:和pushScene:的時候,在popScene彈出場景時是不能用這個過渡效果的


節點的生命週期

說到場景過渡,那就不得不說一下節點的生命週期,即一個節點從開始被添加到屏幕上 到 從屏幕中移除的過程,CCNode提供了相應的生命週期方法:

[java] view plaincopy
  1. // 節點被添加到屏幕上  或者 重新顯示到屏幕上 時調用  
  2. -(void) onEnter;  
  3.   
  4. // 調用完onEnter後就會調用此方法,如果使用了場景過渡效果,將在場景過渡完畢後才調用此方法  
  5. -(void) onEnterTransitionDidFinish;  
  6.   
  7. // 節點從屏幕中移除 或者 暫時離開屏幕 時調用  
  8. -(void) onExit;  


下面演示在場景切換時,節點生命週期方法的調用順序

設有2個圖層RedLayer和BlueLayer,它們分別在不同的場景中。點擊RedLayer,就推入BlueLayer所在的場景,點擊BlueLayer就彈出BlueLayer所在的場景。我們就在場景切換的過程中觀察這2個圖層的生命週期。

爲了區分這2個圖層,我讓它們繼承了CCLayerColor,分別設置不用的背景顏色,RedLayer爲紅色,BlueLayer爲藍色。

因爲RedLayer和BlueLayer都繼承CCLayerColor,而且都需要負責創建自己的圖層、負責觀察生命週期方法的調用,那麼我就先抽出一個繼承了CCLayerColor的公共父類BaseLayer,在它裏面完成一些公共操作,然後讓RedLayer和BlueLayer都繼承它


BaseLayer的代碼

[java] view plaincopy
  1. // BaseLayer.h  
  2. #import "cocos2d.h"  
  3.   
  4. @interface BaseLayer : CCLayerColor  
  5. // 用來創建圖層所在的場景  
  6. + (CCScene *)scene;  
  7.   
  8. // 圖層的背景顏色,交給子類去實現  
  9. + (ccColor4B)bgColor;  
  10. @end  
[java] view plaincopy
  1. // BaseLayer.m  
  2. #import "BaseLayer.h"  
  3.   
  4. @implementation BaseLayer  
  5.   
  6. #pragma mark - 初始化場景  
  7. + (CCScene *)scene {  
  8.     // 獲取當前類的背景顏色  
  9.     ccColor4B color = [self bgColor];  
  10.     // 根據當前類名創建圖層  
  11.     BaseLayer *layer = [[self class] layerWithColor:color];  
  12.     // 接收觸摸輸入  
  13.     layer.isTouchEnabled = YES;   
  14.       
  15.     CCScene *scene = [CCScene node];  
  16.     [scene addChild:layer];  
  17.     return scene;  
  18. }  
  19.   
  20. #pragma mark - 打印生命週期方法  
  21. - (void)onEnter { // _cmd 代表着當前的selector  
  22.     [super onEnter];  
  23.     // 第一個%@是打印類名,第二個%@是打印方法名  
  24.     NSLog(@"%@ --> %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd));  
  25. }  
  26.   
  27. - (void)onEnterTransitionDidFinish {  
  28.     [super onEnterTransitionDidFinish];  
  29.     NSLog(@"%@ --> %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd));  
  30. }  
  31.   
  32. - (void)onExit {  
  33.     [super onExit];  
  34.     NSLog(@"%@ --> %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd));  
  35. }  
  36. @end  

RedLayer的代碼

[java] view plaincopy
  1. // RedLayer.h  
  2. #import "BaseLayer.h"  
  3.   
  4. @interface RedLayer : BaseLayer  
  5. @end  
[java] view plaincopy
  1. // RedLayer.m  
  2. #import "RedLayer.h"  
  3. #import "BlueLayer.h"  
  4.   
  5. @implementation RedLayer  
  6.   
  7. #pragma mark - 點擊紅色圖層時,跳到藍色圖層所在的場景  
  8. - (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {  
  9.     // 初始化藍色圖層所在的場景  
  10.     CCScene *scene = [BlueLayer scene];  
  11.     // 推入場景(暫時沒有使用過渡效果)  
  12.     [[CCDirector sharedDirector] pushScene:scene];  
  13. }  
  14.   
  15. #pragma mark - 背景顏色爲紅色  
  16. + (ccColor4B)bgColor {  
  17.     return ccc4(25500255);  
  18. }  
  19. @end  

BlueLayer的代

[java] view plaincopy
  1. // BlueLayer.h  
  2. #import "BaseLayer.h"  
  3.   
  4. @interface BlueLayer : BaseLayer  
  5. @end  
[java] view plaincopy
  1. // BlueLayer.m  
  2. #import "BlueLayer.h"  
  3.   
  4. @implementation BlueLayer  
  5. #pragma mark - 當點擊藍色圖層時,彈出場景  
  6. - (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {  
  7.     [[CCDirector sharedDirector] popScene];  
  8. }  
  9.   
  10. #pragma mark - 背景顏色爲藍色  
  11. + (ccColor4B)bgColor {  
  12.     return ccc4(00255255);  
  13. }  
  14. @end  


1.在應用程序加載完畢後,即在AppDelegate的applicationDidFinishLaunching:方法中啓動第一個場景 ---- 紅色圖層所在的場景

[java] view plaincopy
  1. [[CCDirector sharedDirector] runWithScene: [RedLayer scene]];  

運行完畢後,效果如下:

生命週期方法打印如下:

[java] view plaincopy
  1. 2013-02-22 15:47:56.473 HelloWorld[2679:c07] RedLayer --> onEnter  
  2. 2013-02-22 15:47:56.474 HelloWorld[2679:c07] RedLayer --> onEnterTransitionDidFinish  

2.點擊紅色圖層,跳到藍色圖層所在的場景

這裏根據有沒有使用過渡效果,要分2種情況

1> 如果沒有使用過渡效果

屏幕直接變爲藍色

生命週期方法打印如下:

[java] view plaincopy
  1. 2013-02-22 15:50:16.381 HelloWorld[2679:c07] RedLayer --> onExit  
  2. 2013-02-22 15:50:16.382 HelloWorld[2679:c07] BlueLayer --> onEnter  
  3. 2013-02-22 15:50:16.384 HelloWorld[2679:c07] BlueLayer --> onEnterTransitionDidFinish  
可以看出,是先移除紅色,再添加藍色


2> 如果使用了過渡效果

先改變下RedLayer中的代碼:

[java] view plaincopy
  1. #pragma mark - 點擊紅色圖層時,跳到藍色圖層所在的場景  
  2. - (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {  
  3.     // 初始化藍色圖層所在的場景  
  4.     CCScene *scene = [BlueLayer scene];  
  5.     // 舊場景一邊旋轉一邊縮小,新場景一邊旋轉一邊方法  
  6.     CCTransitionRotoZoom *page = [CCTransitionRotoZoom transitionWithDuration:2 scene:scene];  
  7.     // 推入場景(暫時沒有使用過渡效果)  
  8.     [[CCDirector sharedDirector] pushScene:page];  
  9. }  
接下來看一下屏幕效果和打印信息

過渡效果剛開始就會打印:

[java] view plaincopy
  1. 2013-02-22 15:59:38.420 HelloWorld[2862:c07] BlueLayer --> onEnter  
說明是先初始化並添加BlueLayer

然後中間經歷了長達2s的過渡效果:

紅色是在一邊旋轉一邊縮小

紅色完全消失後,藍色在一邊旋轉一邊放大

藍色放大到屏幕大小後

最後會出現以下打印信息:

[java] view plaincopy
  1. 2013-02-22 16:04:28.852 HelloWorld[2910:c07] RedLayer --> onExit  
  2. 2013-02-22 16:04:28.853 HelloWorld[2910:c07] BlueLayer --> onEnterTransitionDidFinish  
移除紅色,藍色過渡完畢


3> 點擊藍色圖層,彈出藍色圖層所在的場景,重新顯示紅色圖層所在的場景

打印信息如下:

[java] view plaincopy
  1. 2013-02-22 16:06:47.013 HelloWorld[2910:c07] BlueLayer --> onExit  
  2. 2013-02-22 16:06:47.014 HelloWorld[2910:c07] RedLayer --> onEnter  
  3. 2013-02-22 16:06:47.015 HelloWorld[2910:c07] RedLayer --> onEnterTransitionDidFinish  

移除藍色,重新顯示紅色



原文地址:http://blog.csdn.net/q199109106q/article/details/8602106

感謝作者~!

發佈了27 篇原創文章 · 獲贊 3 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章