您好,登錄后才能下訂單哦!
這一節將向游戲開發者介紹HelloWorld項目的目錄結構,以及各個部分是如何協同工作的。通過本節的學習,你會對各個部分之間的聯系有個大致的了解。
圖13.22顯示了HelloWorld項目的項目導航面板。
圖13.22
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-SW1。
fps_p_w_picpaths.png文件用于顯示幀率,是不允許刪除或修改的。
Info.plist文件包含了一些與項目相關的配置信息,同時也可以在這個文件中修改一些重要的設置,如項目圖標、支持設備的方向等。
任何一個使用Xcode開發的應用程序或游戲都是從main.m開始的。在導航區域的“Supporting Files”組下面可以找到main.m文件。main.m的代碼如下。
程序清單:codes/13/13.3/HelloWorld/HelloWorld/main.m
#import <UIKit/UIKit.h>
int main(int argc,char *argv[]) {
@autoreleasepool {
int retVal = UIApplicationMain(argc,argv,nil,@"AppController");
return retVal;
}
}
簡單來說,main函數創建了@autoreleasepool(自動釋放池),然后調用UIApplicationMain來啟動程序。其中,AppController是實現UIApplicationDelegate協議的類,AppController類的實現包含在AppDelegate文件中。在啟用了ARC的cocos2d應用程序中,Autorelease Pool(自動釋放池)可以確保內存的對象最終被釋放。
該組中的另一個文件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
每個iOS程序都有一個AppDelegate類,用于實現UIApplicationDelegate協議。AppDelegate實現的方法用于處理iOS應用程序的狀態改變。例如,可以通過它來處理用戶來電或者系統內存不足時程序需要采取的措施。在查看AppDelegate方法的具體實現代碼前,先要了解AppDelegate.h中的類定義。在AppDelegate.h中定義了AppController這個類,它直接繼承自NSObject類,并且遵循UIApplicationDelegate和CCDirectorDelegate兩個協議。
程序加載完成后,立即執行的方法就是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
// 使用CCGLView將OpenGL 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;
// 將FPS(Frames Per Second)和SPF(Second Per Frame)顯示設置為開
// cocos2d會自動計算游戲的當前幀數,并顯示在屏幕的左下角
// 在調試過程中FPS顯示對我們調試會非常有用
// 在游戲正式上傳到設備時可以將其設置為NO,則FPS和SPF不會再顯示在設備中
[director_ setDisplayStats:YES];
// 將動畫間距設置為每秒60次,這也是cocos2d中的默認設置
// 在正常情況下,cocos2d每秒最高會刷新屏幕中的顯示60次
[director_ setAnimationInterval:1.0/60];
// 將openglView綁定到director_導演對象上
[director_ setView:glView];
// 將director_的代理對象設置為self(自身),用于獲取屏幕信息
[director_ setDelegate:self];
// 設置2D或3D投射
[director_ setProjection:kCCDirectorProjection2D];
// [director setProjection:kCCDirectorProjection3D];
// 啟用Retina高清顯示模式
if(! [director_ enableRetinaDisplay:YES] )
CCLOG(@"Retina Display Not supported");
// 設置cocos2d的紋理格式
[CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGBA8888];
// 在iPad或Retina高清顯示模式下,使用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_];
// 設置navigationBarHidden為YES
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
// 當操作系統暫停應用時執行,調用此方法來暫停游戲和所有的計時器
// 當玩家在玩游戲的過程中鎖定了iPad或iPhone,或者有電話打進來
// 或者其他類似事件發生需要強迫游戲進入后臺時,會調用此方法
-(void)applicationWillResignActive:(UIApplication *)application
{
if([navController_ visibleViewController] == director_ )
[director_ pause];
}
// 當玩家解鎖iPad或iPhone,或電話已接聽完畢時,會調用此方法來繼續游戲和所有的計時器
-(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類的實現。
IntroLayer類繼承自CCLayer,因為CCDirector只能運行CCScene對象,所以需要實現IntroLayer的scene方法,它會把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類的實現。
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];
// 將標簽位置設置在屏幕中央,ccp是cocos2d對于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中的核心類。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。