瘋狂ios講義之建立cocos2d項目(3)

13.3.3 cocos2d項目結構和代碼分析

這一節將向遊戲開發者介紹HelloWorld項目的目錄結構,以及各個部分是如何協同工做的。經過本節的學習,你會對各個部分之間的聯繫有個大體的瞭解。html

13.22顯示了HelloWorld項目的項目導航面板。node

164919_6G44_262659.jpg

164945_DMil_262659.jpg

164955_P8CU_262659.jpg

13.22
ios


cocos2d項目引用兩類不一樣的文件:源碼文件和資源文件(包括圖像文件、聲音文件和屬性文件等)。Default.png文件是在iOS加載應用程序時顯示的圖像,Icon.png是應用程序部署在設備上的圖標。不一樣設備上可能使用這些文件類型的不一樣版本。例如,Retina 設備上會加載帶有@2x後綴的圖像文件。關於應用程序圖標、啓動圖像等圖像尺寸和格式的完整列表,能夠參考蘋果公司的開發者文檔中的Custom Icon and Image Creation Guidelines,具體網址是:http://developer.apple.com/library/ios/ documentation/userexperience/conceptual/ mobilehig/IconsImages/IconsImages.html#//apple_ref/doc/uid/TP40006556-CH14-SW1app

fps_p_w_picpaths.png文件用於顯示幀率,是不容許刪除或修改的。框架

Info.plist文件包含了一些與項目相關的配置信息,同時也能夠在這個文件中修改一些重要的設置,如項目圖標、支持設備的方向等。ide

1. 主程序入口main.m

任何一個使用Xcode開發的應用程序或遊戲都是從main.m開始的。在導航區域的「Supporting Files」組下面能夠找到main.m文件。main.m的代碼以下。函數

程序清單:codes/13/13.3/HelloWorld/HelloWorld/main.m學習

#import <UIKit/UIKit.h>動畫

int mainint argcchar *argv[] {ui

@autoreleasepool {

int retVal = UIApplicationMain(argc,argv,nil,@"AppController");

return retVal;

}

}

簡單來講,main函數建立了@autoreleasepool(自動釋放池),而後調用UIApplicationMain來啓動程序。其中,AppController是實現UIApplicationDelegate協議的類,AppController類的實現包含在AppDelegate文件中。在啓用了ARCcocos2d應用程序中,Autorelease Pool(自動釋放池)能夠確保內存的對象最終被釋放。

2. 預編譯頭文件Prefix.pch

該組中的另外一個文件Prefix.pch是預編譯頭文件,用於加快編譯速度。pch表示Pre-Compiled Header,遊戲開發者應該把不常變化的框架(Frameworks)頭文件添加到該文件中。這樣作可使框架的代碼提早被編譯,並對全部類可見。

不過,這樣作要注意一個問題:若是pch前綴頭文件中的一個頭文件發生了變化,項目中的全部代碼都將會從新編譯。因此,pch前綴頭文件中只應該添加那些極少或者歷來都不發生變化的頭文件。

遊戲開發者能夠將cocos2d.h頭文件添加到pch前綴頭文件中,由於它幾乎不會改變。並且,一開始就將cocos2d.h添加到預編譯頭文件中是一個很是好的習慣,這樣在其餘源文件中就沒必要再寫「#import "cocos2d.h"」了。在預編譯頭文件中加入cocos2d.h,代碼以下。

程序清單:codes/13/13.3/HelloWorld/HelloWorld/Prefix.pch

#import <Availability.h>

#ifndef __IPHONE_3_0

#warning "This project uses features only available in iPhone SDK 3.0 and later."

#endif

#ifdef __OBJC__

#import <UIKit/UIKit.h>

#import <Foundation/Foundation.h>

#import "cocos2d.h"

#endif

3. AppDelegate

每一個iOS程序都有一個AppDelegate類,用於實現UIApplicationDelegate協議。AppDelegate實現的方法用於處理iOS應用程序的狀態改變。例如,能夠經過它來處理用戶來電或者系統內存不足時程序須要採起的措施。在查看AppDelegate方法的具體實現代碼前,先要了解AppDelegate.h中的類定義。在AppDelegate.h中定義了AppController這個類,它直接繼承自NSObject類,而且遵循UIApplicationDelegateCCDirectorDelegate兩個協議。

程序加載完成後,當即執行的方法就是applicationDidFinishLaunchingWithOptions:,在該方法中,一般都是應用啓動後須要執行的初始化代碼。

Xcode中打開AppDelegate.m文件,找到applicationDidFinishLaunchingWithOptions方法,代碼以下。

程序清單:codes/13/13.3/HelloWorld/HelloWorld/AppDelegate.m

-(BOOL)application:(UIApplication *)application

didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

{

// 建立程序主窗口

window_ = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

// 建立CCGLView對象,用於遊戲中的渲染

// cocos2d v2.0以後,CCGLView替代了以前的EAGLView

// 使用CCGLViewOpenGL ES命令發送給OpenGL ES驅動

CCGLView *glView =[CCGLView viewWithFrame:[window_ bounds]

pixelFormat:kEAGLColorFormatRGB565depthFormat:0

preserveBackbuffer:NOsharegroup:nilmultiSampling:NO

numberOfSamples:0];

// ①建立導演對象

director_ =(CCDirectorIOS*) [CCDirector sharedDirector];

director_.wantsFullScreenLayout = YES;

// FPSFrames Per Second)和SPFSecond Per Frame)顯示設置爲開

// cocos2d會自動計算遊戲的當前幀數,並顯示在屏幕的左下角

// 在調試過程當中FPS顯示對咱們調試會很是有用

// 在遊戲正式上傳到設備時能夠將其設置爲NO,則FPSSPF不會再顯示在設備中

[director_ setDisplayStats:YES];

// 將動畫間距設置爲每秒60次,這也是cocos2d中的默認設置

// 在正常狀況下,cocos2d每秒最高會刷新屏幕中的顯示60

[director_ setAnimationInterval:1.0/60];

// openglView綁定到director_導演對象上

[director_ setView:glView];

// director_的代理對象設置爲self(自身),用於獲取屏幕信息

[director_ setDelegate:self];

// 設置2D3D投射

[director_ setProjection:kCCDirectorProjection2D];

// [director setProjection:kCCDirectorProjection3D];

// 啓用Retina高清顯示模式

if(! [director_ enableRetinaDisplay:YES] )

CCLOG(@"Retina Display Not supported");

// 設置cocos2d的紋理格式

[CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGBA8888];

// iPadRetina高清顯示模式下,使用CCFileUtils自動添加圖片的後綴

CCFileUtils *sharedFileUtils = [CCFileUtils sharedFileUtils];

[sharedFileUtils setEnableFallbackSuffixes:NO];

[sharedFileUtils setiPhoneRetinaDisplaySuffix:@"-hd"];

[sharedFileUtils setiPadSuffix:@"-ipad"];

[sharedFileUtils setiPadRetinaDisplaySuffix:@"-ipadhd"];

// 設置PVR圖像具有多重透明度

[CCTexture2D PVRImagesHavePremultipliedAlpha:YES];

// ②初始化IntroLayer場景,並使用pushScene方法切換到該場景

[director_ pushScene: [IntroLayer scene]];

// 使用director_建立NavigationController導航控制器

navController_ = [[UINavigationController alloc] initWithRootViewController:director_];

// 設置navigationBarHiddenYES

navController_.navigationBarHidden = YES;

// NavigationController導航控制器設置爲根視圖控制器

[window_ setRootViewController:navController_];

// 設置主窗口可見

[window_ makeKeyAndVisible];

return YES;

}

applicationDidFinishLaunchingWithOptions方法中,①號代碼建立了一個CCDirector導演對象,在cocos2d中,CCDirector導演對象負責遊戲的循環運行,而且在遊戲中渲染全部的圖像,它會掌控遊戲的運行、暫停或中止。AppController中包括了CCDirector響應iOS操做系統在內的暫停或繼續等各個事件。代碼以下。

程序清單:codes/13.3/HelloWorld/HelloWorld/AppDelegate.m

// 當操做系統暫停應用時執行,調用此方法來暫停遊戲和全部的計時器

// 當玩家在玩遊戲的過程當中鎖定了iPadiPhone,或者有電話打進來

// 或者其餘相似事件發生須要強迫遊戲進入後臺時,會調用此方法

-(void)applicationWillResignActive:(UIApplication *)application

{

if([navController_ visibleViewController] == director_ )

[director_ pause];

}

// 當玩家解鎖iPadiPhone,或電話已接聽完畢時,會調用此方法來繼續遊戲和全部的計時器

-(void)applicationDidBecomeActive: (UIApplication *application

{

if( [navController_ visibleViewController] == director_ )

[director_ resume];

}

// iOS 4.0及之後的版本中,開始支持應用在後臺運行,此時會中止運行屏幕中的動畫

-(void)applicationDidEnterBackground: (UIApplication*)application

{

if( [navController_ visibleViewController] == director_ )

[director_ stopAnimation];

}

// 當應用從新回到前臺來運行時,從新啓動屏幕中的動畫

-(void)applicationWillEnterForeground: (UIApplication*)application

{

if( [navController_ visibleViewController] == director_ )

[director_ startAnimation];

}

// 應用程序即將停止時調用此方法

// 該方法會終止CCDirector的控制,並從應用程序的UIWindow中解除對CCGLView的綁定

// 同時還將結束遊戲循環,從內存中清除全部的紋理和計時器

-(void)applicationWillTerminate: (UIApplication *)application

{

CC_DIRECTOR_END();

}

// 當系統收到內存不足的警告時,會調用此方法從內存中清除未在屏幕中顯示的紋理圖。

-(void)applicationDidReceiveMemoryWarning: (UIApplication *)application

{

[[CCDirector sharedDirector] purgeCachedData];

}

// 將上一次時間調用和當前事件調用間的增量時間設置爲0

// 該方法的調用場景是:兩次調用之間已通過了太長的時間。

// 這一般是因爲iPhone從新調整了系統時間而致使。

-(void)applicationSignificantTimeChange: (UIApplication *)application

{

[[CCDirector sharedDirector] setNextDeltaTimeZero:YES];

}

applicationDidFinishLaunchingWithOptions方法中,編號②代碼初始化IntroLayer場景,並使用pushScene方法切換到該場景。下面咱們來看看IntroLayer類的實現。

4. IntroLayer

IntroLayer類繼承自CCLayer,由於CCDirector只能運行CCScene對象,因此須要實現IntroLayerscene方法,它會把IntroLayer看成惟一的子節點添加進去,並返回一個CCScene。打開IntroLayer.m文件,找到scene方法,代碼以下。

程序清單:codes/13/13.3/HelloWorld/HelloWorld/IntroLayer.m

+(CCScene *)scene

{

// 建立CCScene場景對象

CCScene *scene = [CCScene node];

// 建立IntroLayer層對象

IntroLayer *layer = [IntroLayer node];

// layer添加爲scene的子節點

[scene addChild: layer];

// 返回scene對象

return scene;

}

之前的cocos2d版本中是不存在IntroLayer類的,這是cocos2d 2.0新加的類,它的主要目的就是在進入遊戲以前,能夠顯示遊戲製做公司的Logo等信息。顯示Logo的實現代碼在onEnter方法當中,代碼以下(程序清單同上)。

-(void)onEnter

{

[super onEnter];

// 得到設備支持的窗口大小

CGSize size = [[CCDirector sharedDirector] winSize];

CCSprite *background;

// 判斷設備是iPhone仍是iPad,並據此來加載不一樣的背景資源圖片

if(UI_USER_INTERFACE_IDIOM()== UIUserInterfaceIdiomPhone ){

background = [CCSprite spriteWithFile:@"Default.png"];

background.rotation = 90;

} else {

background = [CCSprite spriteWithFile:@"Default-Landscape~ipad.png"];

}

// 設置背景圖片的位置居中

background.position = ccp(size.width/2,size.height/2);

// 把背景圖片添加到IntroLayer

[self addChild: background];

// 觸發一個定時器方法調用,在1秒後會調用makeTransition函數

[self scheduleOnce:@selector(makeTransition:)delay:1];

}

接下來看看makeTransition方法的實現,代碼以下(程序清單同上)。

-(void)makeTransition: (ccTime)delta

{

[[CCDirector sharedDirector] replaceScene:

[CCTransitionFade transitionWithDuration:1.0

scene:[HelloWorldLayer scene] withColor:ccWHITE]];

}

該方法只有一句代碼調用,就是使用CCDirector配合CCTransitionFade場景切換特效類,把HelloWorldLayer類在1秒屏幕變白後展現出來。最後來看看HelloWordLayer類的實現。

5. HelloWorldLayer.m

HelloWorldLayer類繼承自CCLayer。由於CCScene只是一個抽象的接口,而默認設置場景的方法一般是在類裏使用一個靜態初始化方法+(id)scene。此方法會建立一個CCScene對象,而且將HelloWorldLayer的對象添加爲場景的子節點。代碼以下。

程序清單:codes/13/13.3/HelloWorld/HelloWorld/HelloWorldLayer.m

+(CCScene *)scene

{

// 建立CCScene場景對象

CCScene *scene = [CCScene node];

// 建立HelloWorldLayer層對象

HelloWorldLayer *layer = [HelloWorldLayer node];

// layer添加爲scene的子節點

[scene addChild: layer];

// 返回scene對象

return scene;

}

接下來再看看-(id)init初始化方法的實現,代碼以下(程序清單同上)。

-(id) init

{

if((self=[super init])) {

// 建立和初始化一個標籤對象

CCLabelTTF *label = [CCLabelTTF labelWithString:@"Hello World"

fontName:@"Marker Felt" fontSize:64];

// 實例化獲得一個CCDirector的單例,並得到窗口的尺寸

CGSize size = [[CCDirector sharedDirector] winSize];

// 將標籤位置設置在屏幕中央,ccpcocos2d對於CGPointMake的宏定義

label.position = ccp(size.width /2,size.height/2);

// label添加爲scene的子節點

[self addChild: label];

// 下面是初始化遊戲中心的成就榜和高分榜的代碼,此處先略去暫時不討論

}

return self;

}

以上就是HelloWorld項目的詳細實現過程。讀者以前已經學習過iOS基礎知識,因此這裏並無對全部類的全部實現代碼進行逐行解釋和分析。但經過以上詳細代碼分析,咱們初步瞭解了一個cocos2d應用的啓動和運行過程,這將爲之後開發更復雜的遊戲或應用程序打下紮實的基礎。

HelloWorld項目中,使用了場景(CCScene)、層(CCLayer)、導演(CCDirector)等核心類,在cocos2d的開發中,幾乎任何一款cocos2d遊戲中都會用到這些類,因此瞭解它們的做用、屬性和方法,以及如何將這些類組織在一塊兒,是咱們學習cocos2d遊戲開發的必修課。掌握了這些基本知識以後,你們就會發現使用cocos2d開發遊戲其實很簡單。接下來重點介紹cocos2d中的核心類。

相關文章
相關標籤/搜索