這一節(jié)將向游戲開發(fā)者介紹HelloWorld項(xiàng)目的目錄結(jié)構(gòu),以及各個部分是如何協(xié)同工作的。通過本節(jié)的學(xué)習(xí),你會對各個部分之間的聯(lián)系有個大致的了解。
安居網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)公司!從網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、響應(yīng)式網(wǎng)站設(shè)計(jì)等網(wǎng)站項(xiàng)目制作,到程序開發(fā),運(yùn)營維護(hù)。創(chuàng)新互聯(lián)公司成立與2013年到現(xiàn)在10年的時間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)公司。
圖13.22顯示了HelloWorld項(xiàng)目的項(xiàng)目導(dǎo)航面板。
圖13.22
cocos2d項(xiàng)目引用兩類不同的文件:源碼文件和資源文件(包括圖像文件、聲音文件和屬性文件等)。Default.png文件是在iOS加載應(yīng)用程序時顯示的圖像,Icon.png是應(yīng)用程序部署在設(shè)備上的圖標(biāo)。不同設(shè)備上可能使用這些文件類型的不同版本。例如,Retina 設(shè)備上會加載帶有@2x后綴的圖像文件。關(guān)于應(yīng)用程序圖標(biāo)、啟動圖像等圖像尺寸和格式的完整列表,可以參考蘋果公司的開發(fā)者文檔中的Custom Icon and Image Creation Guidelines,具體網(wǎng)址是:http://developer.apple.com/library/ios/ documentation/userexperience/conceptual/ mobilehig/IconsImages/IconsImages.html#//apple_ref/doc/uid/TP40006556-CH14-SW1。
fps_p_w_picpaths.png文件用于顯示幀率,是不允許刪除或修改的。
Info.plist文件包含了一些與項(xiàng)目相關(guān)的配置信息,同時也可以在這個文件中修改一些重要的設(shè)置,如項(xiàng)目圖標(biāo)、支持設(shè)備的方向等。
任何一個使用Xcode開發(fā)的應(yīng)用程序或游戲都是從main.m開始的。在導(dǎo)航區(qū)域的“Supporting Files”組下面可以找到main.m文件。main.m的代碼如下。
程序清單:codes/13/13.3/HelloWorld/HelloWorld/main.m
#import
int main(int argc,char *argv[]) {
@autoreleasepool {
int retVal = UIApplicationMain(argc,argv,nil,@"AppController");
return retVal;
}
}
簡單來說,main函數(shù)創(chuàng)建了@autoreleasepool(自動釋放池),然后調(diào)用UIApplicationMain來啟動程序。其中,AppController是實(shí)現(xiàn)UIApplicationDelegate協(xié)議的類,AppController類的實(shí)現(xiàn)包含在AppDelegate文件中。在啟用了ARC的cocos2d應(yīng)用程序中,Autorelease Pool(自動釋放池)可以確保內(nèi)存的對象最終被釋放。
該組中的另一個文件Prefix.pch是預(yù)編譯頭文件,用于加快編譯速度。pch表示Pre-Compiled Header,游戲開發(fā)者應(yīng)該把不常變化的框架(Frameworks)頭文件添加到該文件中。這樣做可以使框架的代碼提前被編譯,并對所有類可見。
不過,這樣做要注意一個問題:如果pch前綴頭文件中的一個頭文件發(fā)生了變化,項(xiàng)目中的所有代碼都將會重新編譯。所以,pch前綴頭文件中只應(yīng)該添加那些極少或者從來都不發(fā)生變化的頭文件。
游戲開發(fā)者可以將cocos2d.h頭文件添加到pch前綴頭文件中,因?yàn)樗鼛缀醪粫淖?。而且,一開始就將cocos2d.h添加到預(yù)編譯頭文件中是一個非常好的習(xí)慣,這樣在其他源文件中就不必再寫“#import "cocos2d.h"”了。在預(yù)編譯頭文件中加入cocos2d.h,代碼如下。
程序清單:codes/13/13.3/HelloWorld/HelloWorld/Prefix.pch
#import
#ifndef __IPHONE_3_0
#warning "This project uses features only available in iPhone SDK 3.0 and later."
#endif
#ifdef __OBJC__
#import
#import
#import "cocos2d.h"
#endif
每個iOS程序都有一個AppDelegate類,用于實(shí)現(xiàn)UIApplicationDelegate協(xié)議。AppDelegate實(shí)現(xiàn)的方法用于處理iOS應(yīng)用程序的狀態(tài)改變。例如,可以通過它來處理用戶來電或者系統(tǒng)內(nèi)存不足時程序需要采取的措施。在查看AppDelegate方法的具體實(shí)現(xiàn)代碼前,先要了解AppDelegate.h中的類定義。在AppDelegate.h中定義了AppController這個類,它直接繼承自NSObject類,并且遵循UIApplicationDelegate和CCDirectorDelegate兩個協(xié)議。
程序加載完成后,立即執(zhí)行的方法就是applicationDidFinishLaunchingWithOptions:,在該方法中,通常都是應(yīng)用啟動后需要執(zhí)行的初始化代碼。
在Xcode中打開AppDelegate.m文件,找到applicationDidFinishLaunchingWithOptions方法,代碼如下。
程序清單:codes/13/13.3/HelloWorld/HelloWorld/AppDelegate.m
-(BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// 創(chuàng)建程序主窗口
window_ = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// 創(chuàng)建CCGLView對象,用于游戲中的渲染
// 從cocos2d v2.0之后,CCGLView替代了之前的EAGLView
// 使用CCGLView將OpenGL ES命令發(fā)送給OpenGL ES驅(qū)動
CCGLView *glView =[CCGLView viewWithFrame:[window_ bounds]
pixelFormat:kEAGLColorFormatRGB565depthFormat:0
preserveBackbuffer:NOsharegroup:nilmultiSampling:NO
numberOfSamples:0];
// ①創(chuàng)建導(dǎo)演對象
director_ =(CCDirectorIOS*) [CCDirector sharedDirector];
director_.wantsFullScreenLayout = YES;
// 將FPS(Frames Per Second)和SPF(Second Per Frame)顯示設(shè)置為開
// cocos2d會自動計(jì)算游戲的當(dāng)前幀數(shù),并顯示在屏幕的左下角
// 在調(diào)試過程中FPS顯示對我們調(diào)試會非常有用
// 在游戲正式上傳到設(shè)備時可以將其設(shè)置為NO,則FPS和SPF不會再顯示在設(shè)備中
[director_ setDisplayStats:YES];
// 將動畫間距設(shè)置為每秒60次,這也是cocos2d中的默認(rèn)設(shè)置
// 在正常情況下,cocos2d每秒最高會刷新屏幕中的顯示60次
[director_ setAnimationInterval:1.0/60];
// 將openglView綁定到director_導(dǎo)演對象上
[director_ setView:glView];
// 將director_的代理對象設(shè)置為self(自身),用于獲取屏幕信息
[director_ setDelegate:self];
// 設(shè)置2D或3D投射
[director_ setProjection:kCCDirectorProjection2D];
// [director setProjection:kCCDirectorProjection3D];
// 啟用Retina高清顯示模式
if(! [director_ enableRetinaDisplay:YES] )
CCLOG(@"Retina Display Not supported");
// 設(shè)置cocos2d的紋理格式
[CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGBA8888];
// 在iPad或Retina高清顯示模式下,使用CCFileUtils自動添加圖片的后綴
CCFileUtils *sharedFileUtils = [CCFileUtils sharedFileUtils];
[sharedFileUtils setEnableFallbackSuffixes:NO];
[sharedFileUtils setiPhoneRetinaDisplaySuffix:@"-hd"];
[sharedFileUtils setiPadSuffix:@"-ipad"];
[sharedFileUtils setiPadRetinaDisplaySuffix:@"-ipadhd"];
// 設(shè)置PVR圖像具備多重透明度
[CCTexture2D PVRImagesHavePremultipliedAlpha:YES];
// ②初始化IntroLayer場景,并使用pushScene方法切換到該場景
[director_ pushScene: [IntroLayer scene]];
// 使用director_創(chuàng)建NavigationController導(dǎo)航控制器
navController_ = [[UINavigationController alloc] initWithRootViewController:director_];
// 設(shè)置navigationBarHidden為YES
navController_.navigationBarHidden = YES;
// 將NavigationController導(dǎo)航控制器設(shè)置為根視圖控制器
[window_ setRootViewController:navController_];
// 設(shè)置主窗口可見
[window_ makeKeyAndVisible];
return YES;
}
在applicationDidFinishLaunchingWithOptions方法中,①號代碼創(chuàng)建了一個CCDirector導(dǎo)演對象,在cocos2d中,CCDirector導(dǎo)演對象負(fù)責(zé)游戲的循環(huán)運(yùn)行,并且在游戲中渲染所有的圖像,它會掌控游戲的運(yùn)行、暫?;蛲V?。AppController中包括了CCDirector響應(yīng)iOS操作系統(tǒng)在內(nèi)的暫?;蚶^續(xù)等各個事件。代碼如下。
程序清單:codes/13.3/HelloWorld/HelloWorld/AppDelegate.m
// 當(dāng)操作系統(tǒng)暫停應(yīng)用時執(zhí)行,調(diào)用此方法來暫停游戲和所有的計(jì)時器
// 當(dāng)玩家在玩游戲的過程中鎖定了iPad或iPhone,或者有電話打進(jìn)來
// 或者其他類似事件發(fā)生需要強(qiáng)迫游戲進(jìn)入后臺時,會調(diào)用此方法
-(void)applicationWillResignActive:(UIApplication *)application
{
if([navController_ visibleViewController] == director_ )
[director_ pause];
}
// 當(dāng)玩家解鎖iPad或iPhone,或電話已接聽完畢時,會調(diào)用此方法來繼續(xù)游戲和所有的計(jì)時器
-(void)applicationDidBecomeActive: (UIApplication *)application
{
if( [navController_ visibleViewController] == director_ )
[director_ resume];
}
// 在iOS 4.0及以后的版本中,開始支持應(yīng)用在后臺運(yùn)行,此時會停止運(yùn)行屏幕中的動畫
-(void)applicationDidEnterBackground: (UIApplication*)application
{
if( [navController_ visibleViewController] == director_ )
[director_ stopAnimation];
}
// 當(dāng)應(yīng)用重新回到前臺來運(yùn)行時,重新啟動屏幕中的動畫
-(void)applicationWillEnterForeground: (UIApplication*)application
{
if( [navController_ visibleViewController] == director_ )
[director_ startAnimation];
}
// 應(yīng)用程序即將中止時調(diào)用此方法
// 該方法會終止CCDirector的控制,并從應(yīng)用程序的UIWindow中解除對CCGLView的綁定
// 同時還將結(jié)束游戲循環(huán),從內(nèi)存中清除所有的紋理和計(jì)時器
-(void)applicationWillTerminate: (UIApplication *)application
{
CC_DIRECTOR_END();
}
// 當(dāng)系統(tǒng)收到內(nèi)存不足的警告時,會調(diào)用此方法從內(nèi)存中清除未在屏幕中顯示的紋理圖。
-(void)applicationDidReceiveMemoryWarning: (UIApplication *)application
{
[[CCDirector sharedDirector] purgeCachedData];
}
// 將上一次時間調(diào)用和當(dāng)前事件調(diào)用間的增量時間設(shè)置為0。
// 該方法的調(diào)用場景是:兩次調(diào)用之間已經(jīng)過了太長的時間。
// 這通常是由于iPhone重新調(diào)整了系統(tǒng)時間而導(dǎo)致。
-(void)applicationSignificantTimeChange: (UIApplication *)application
{
[[CCDirector sharedDirector] setNextDeltaTimeZero:YES];
}
在applicationDidFinishLaunchingWithOptions方法中,編號②代碼初始化IntroLayer場景,并使用pushScene方法切換到該場景。下面我們來看看IntroLayer類的實(shí)現(xiàn)。
IntroLayer類繼承自CCLayer,因?yàn)镃CDirector只能運(yùn)行CCScene對象,所以需要實(shí)現(xiàn)IntroLayer的scene方法,它會把IntroLayer當(dāng)作唯一的子節(jié)點(diǎn)添加進(jìn)去,并返回一個CCScene。打開IntroLayer.m文件,找到scene方法,代碼如下。
程序清單:codes/13/13.3/HelloWorld/HelloWorld/IntroLayer.m
+(CCScene *)scene
{
// 創(chuàng)建CCScene場景對象
CCScene *scene = [CCScene node];
// 創(chuàng)建IntroLayer層對象
IntroLayer *layer = [IntroLayer node];
// 將layer添加為scene的子節(jié)點(diǎn)
[scene addChild: layer];
// 返回scene對象
return scene;
}
以前的cocos2d版本中是不存在IntroLayer類的,這是cocos2d 2.0新加的類,它的主要目的就是在進(jìn)入游戲之前,可以顯示游戲制作公司的Logo等信息。顯示Logo的實(shí)現(xiàn)代碼在onEnter方法當(dāng)中,代碼如下(程序清單同上)。
-(void)onEnter
{
[super onEnter];
// 獲得設(shè)備支持的窗口大小
CGSize size = [[CCDirector sharedDirector] winSize];
CCSprite *background;
// 判斷設(shè)備是iPhone還是iPad,并據(jù)此來加載不同的背景資源圖片
if(UI_USER_INTERFACE_IDIOM()== UIUserInterfaceIdiomPhone ){
background = [CCSprite spriteWithFile:@"Default.png"];
background.rotation = 90;
} else {
background = [CCSprite spriteWithFile:@"Default-Landscape~ipad.png"];
}
// 設(shè)置背景圖片的位置居中
background.position = ccp(size.width/2,size.height/2);
// 把背景圖片添加到IntroLayer中
[self addChild: background];
// 觸發(fā)一個定時器方法調(diào)用,在1秒后會調(diào)用makeTransition函數(shù)
[self scheduleOnce:@selector(makeTransition:)delay:1];
}
接下來看看makeTransition方法的實(shí)現(xiàn),代碼如下(程序清單同上)。
-(void)makeTransition: (ccTime)delta
{
[[CCDirector sharedDirector] replaceScene:
[CCTransitionFade transitionWithDuration:1.0
scene:[HelloWorldLayer scene] withColor:ccWHITE]];
}
該方法只有一句代碼調(diào)用,就是使用CCDirector配合CCTransitionFade場景切換特效類,把HelloWorldLayer類在1秒屏幕變白后展示出來。最后來看看HelloWordLayer類的實(shí)現(xiàn)。
HelloWorldLayer類繼承自CCLayer。因?yàn)镃CScene只是一個抽象的接口,而默認(rèn)設(shè)置場景的方法通常是在類里使用一個靜態(tài)初始化方法+(id)scene。此方法會創(chuàng)建一個CCScene對象,并且將HelloWorldLayer的對象添加為場景的子節(jié)點(diǎn)。代碼如下。
程序清單:codes/13/13.3/HelloWorld/HelloWorld/HelloWorldLayer.m
+(CCScene *)scene
{
// 創(chuàng)建CCScene場景對象
CCScene *scene = [CCScene node];
// 創(chuàng)建HelloWorldLayer層對象
HelloWorldLayer *layer = [HelloWorldLayer node];
// 將layer添加為scene的子節(jié)點(diǎn)
[scene addChild: layer];
// 返回scene對象
return scene;
}
接下來再看看-(id)init初始化方法的實(shí)現(xiàn),代碼如下(程序清單同上)。
-(id) init
{
if((self=[super init])) {
// 創(chuàng)建和初始化一個標(biāo)簽對象
CCLabelTTF *label = [CCLabelTTF labelWithString:@"Hello World"
fontName:@"Marker Felt" fontSize:64];
// 實(shí)例化得到一個CCDirector的單例,并獲得窗口的尺寸
CGSize size = [[CCDirector sharedDirector] winSize];
// 將標(biāo)簽位置設(shè)置在屏幕中央,ccp是cocos2d對于CGPointMake的宏定義
label.position = ccp(size.width /2,size.height/2);
// 將label添加為scene的子節(jié)點(diǎn)
[self addChild: label];
// 下面是初始化游戲中心的成就榜和高分榜的代碼,此處先略去暫時不討論
}
return self;
}
以上就是HelloWorld項(xiàng)目的詳細(xì)實(shí)現(xiàn)過程。讀者之前已經(jīng)學(xué)習(xí)過iOS基礎(chǔ)知識,所以這里并沒有對所有類的所有實(shí)現(xiàn)代碼進(jìn)行逐行解釋和分析。但通過以上詳細(xì)代碼分析,我們初步了解了一個cocos2d應(yīng)用的啟動和運(yùn)行過程,這將為以后開發(fā)更復(fù)雜的游戲或應(yīng)用程序打下扎實(shí)的基礎(chǔ)。
在HelloWorld項(xiàng)目中,使用了場景(CCScene)、層(CCLayer)、導(dǎo)演(CCDirector)等核心類,在cocos2d的開發(fā)中,幾乎任何一款cocos2d游戲中都會用到這些類,所以了解它們的作用、屬性和方法,以及如何將這些類組織在一起,是我們學(xué)習(xí)cocos2d游戲開發(fā)的必修課。掌握了這些基本知識之后,大家就會發(fā)現(xiàn)使用cocos2d開發(fā)游戲其實(shí)很簡單。接下來重點(diǎn)介紹cocos2d中的核心類。