瘋狂打飛機遊戲
本次咱們將帶領你們手動完成一個簡單但功能完整的打飛機遊戲,實現飛機飛行、飛機碰撞、發射×××、敵機發射大×××、背景音樂、×××音效、分數統計、菜單管理等功能。它雖然不會爲你贏得什麼獎項,可是能夠總結前面所學的全部知識,幫助你們更好地掌握cocos2d基本對象的使用,同時體驗cocos2d的強大以及易用性。node
1開始前的準備工做
首先打開Xcode,使用cocos2d iOS模板新建一個項目,命名爲「AirfightGame」,而後選擇一個目錄,單擊「Create」按鈕。爲cocos2d項目的源代碼添加-fno-objc-arc選項讓項目支持ARC。ios
接下來,將所須要的資源文件,包括圖片和聲音拖到項目的「Resources」組。在遊戲開發當中,一般都會使用精靈表單來優化遊戲性能,在這個小遊戲當中,雖然這種性能優化並不會有特別明顯的效果,可是建議你們之後開發遊戲時都使用精靈表單來提升遊戲性能。使用Zwoptex將全部圖片製做成精靈表單,生成對應的airfightSheet.png和airfightSheet.plist文件,並將這兩個文件拖到項目的「Resources」組。數組
2添加遊戲菜單項功能
如今,咱們來爲遊戲添加一個菜單設置功能,在這裏能夠完成開始遊戲、遊戲設置、退出遊戲等操做。步驟以下。xcode
①選擇「AirfightGame」組並單擊右鍵,選擇「New File」,在左邊欄中選擇「cocos2d v2.x」模板,在右邊的模板類中選擇「CCNode class」模板類,「Subclass of」選擇「CCLayer」,而後單擊「Next」按鈕。命名爲「MenuLayer」,而後單擊「Create」按鈕。性能優化
MenuLayer繼承自CCLayer,提供一個類方法scene供CCDirector對象調用。該類的做用是顯示一個菜單場景,讓用戶選擇。ide
打開MenuLayer.m文件,實現代碼以下。性能
程序清單:codes/13/13.14/AirfightGame/AirfightGame/MenuLayer.m優化
-(id) init
{
if( (self=[super init]) ) {
CGSize winSize = [[CCDirector sharedDirector] winSize];
// 建立「開始遊戲」標籤,當觸碰該標籤時,調用startGame:方法
CCMenuItemFont* startItem = [CCMenuItemFont itemWithString:@"開始遊戲"
target:self selector:@selector(startGame:)];
startItem.position=ccp(winSize.width/2, winSize.height*0.6);
// 建立「遊戲設置」標籤,當觸碰該標籤時,調用setting:方法
CCMenuItemFont* settingItem = [CCMenuItemFont itemWithString:@"遊戲設置"
target:self selector:@selector(setting:)];
// 設置「遊戲設置」標籤位置
settingItem.position=ccp(winSize.width/2, winSize.height*0.4);
// 建立控制菜單,並將兩個標籤添加進去
CCMenu* menu = [CCMenu menuWithItems:startItem,settingItem, nil];
menu.position = CGPointZero;
[self addChild:menu];
}
return self;
}
init方法比較簡單,建立了兩個CCMenuItemFont,選擇標籤時會調用對應的startGame:和setting:方法,並將它們添加到CCMenu當中,再將CCMenu添加爲當前層的子節點。動畫
②添加startGame:和setting:兩個方法,實現代碼以下(程序清單同上):spa
-(void) startGame:(id)sender{
// 切換到PreloadLayer場景
CCTransitionSlideInL* transitionScene = [CCTransitionSlideInL
transitionWithDuration:2.0 scene:[PreloadLayer scene]];
[[CCDirector sharedDirector] replaceScene:transitionScene];
}
startGame:方法很是簡單,當用戶選擇「開始遊戲」標籤時,場景切換到PreloadLayer,在下一節中將重點介紹PreloadLayer(程序清單同上)。
-(void) setting:(id)sender{
// 切換到SettingLayer場景
CCTransitionSlideInL* transitionScene = [CCTransitionSlideInL
transitionWithDuration:2.0 scene:[SettingLayer scene]];
[[CCDirector sharedDirector] replaceScene:transitionScene];
}
當用戶選擇「遊戲設置」標籤時,場景切換到SettingLayer,進行遊戲設置。
③同上面的步驟同樣,使用「cocos2d v2.x」模板建立一個類並命名爲「SettingLayer」,繼承自CCLayer。該類的實現代碼以下。
程序清單:codes/13/13.14/AirfightGame/AirfightGame/SettingLayer.m
-(id) init
{
if( (self=[super init]) ) {
CGSize winSize = [[CCDirector sharedDirector] winSize];
// 提示菜單項
CCMenuItemFont* musicItem = [CCMenuItemFont itemWithString:@"背景音樂:"];
musicItem.position = ccp(winSize.width*0.4, winSize.height*0.6);
// 建立「開」和「關」菜單項
CCMenuItemFont* musicOn = [CCMenuItemFont itemWithString:@"開"];
CCMenuItemFont* musicOff = [CCMenuItemFont itemWithString:@"關"];
// CCMenuItemToggle,默認顯示「開」。開=0,關=1
CCMenuItemToggle* musicToggle = [CCMenuItemToggle itemWithTarget:self
selector:@selector(change:) items:musicOff,musicOn, nil];
musicToggle.position = ccp(winSize.width*0.6, winSize.height*0.6);
// 建立「返回主菜單「菜單項
CCMenuItemFont* returnItem = [CCMenuItemFont itemWithString:@"返回主菜單"
target:self selector:@selector(backToMainLayer:)];
returnItem.position = ccp(winSize.width/2, winSize.height*0.4);
// 建立控制菜單,並將3個標籤添加進去
CCMenu* menu = [CCMenu menuWithItems:musicItem,musicToggle,returnItem, nil];
menu.position = CGPointZero;
[self addChild:menu];
// NSUserDefaults用戶首選項能夠用來保存用戶在操做應用的過程當中設置的首選項。
NSUserDefaults* userDef = [NSUserDefaults standardUserDefaults];
// 若是Bool爲No,則顯示1=關
if(![userDef boolForKey:@"music"]){
musicToggle.selectedIndex = 1;
}
}
return self;
}
-(void) change:(id)sender{
// 判斷mute(靜音)屬性,根據屬性狀態進行切換
if([CDAudioManager sharedManager].mute == TRUE){
[CDAudioManager sharedManager].mute = FALSE;
}else{
[CDAudioManager sharedManager].mute = TRUE;
}
NSUserDefaults* userDef = [NSUserDefaults standardUserDefaults];
CCMenuItemToggle* tooggle = (CCMenuItemToggle*)sender;
// 關=1,設置Bool爲NO
if(tooggle.selectedIndex == 1){
[userDef setBool:NO forKey:@"music"];
}else{
[userDef setBool:YES forKey:@"music"];
}
}
// 定義一個CCTransitionSlideInL場景切換效果,並使用CCDirector單例對象來切換場景
-(void) backToMainLayer:(id)sender{
CCTransitionSlideInL* transitionScene =
[CCTransitionSlideInL transitionWithDuration:2.0 scene:[MenuLayer scene]];
[[CCDirector sharedDirector] replaceScene:transitionScene];
}
SettingLayer類代碼在13.13.2節中已經詳細介紹過,這裏再也不贅述。
④修改IntroLayer.m文件
IntroLayer默認加載HelloWorldLayer,但此時咱們再也不使用HelloWorldLayer做爲應用的第一個場景,而是使用MenuLayer做爲應用的第一個場景,所以須要修改IntroLayer,將IntroLayer改成加載MenuLayer場景。修改以下。
在IntroLayer.m文件的頂部添加所包含的頭文件:
#import "MenuLayer.h"
修改-(void) makeTransition:(ccTime)dt方法,將該方法改爲下面的代碼。
程序清單:codes/13/13.14/AirfightGame/AirfightGame/IntroLayer.m
-(void) makeTransition:(ccTime)dt
{
[[CCDirector sharedDirector] replaceScene:
[CCTransitionFade transitionWithDuration:1.0
scene:[MenuLayer scene] withColor:ccWHITE]];
}
瘋狂打飛機遊戲
本次咱們將帶領你們手動完成一個簡單但功能完整的打飛機遊戲,實現飛機飛行、飛機碰撞、發射×××、敵機發射大×××、背景音樂、×××音效、分數統計、菜單管理等功能。它雖然不會爲你贏得什麼獎項,可是能夠總結前面所學的全部知識,幫助你們更好地掌握cocos2d基本對象的使用,同時體驗cocos2d的強大以及易用性。
1開始前的準備工做
首先打開Xcode,使用cocos2d iOS模板新建一個項目,命名爲「AirfightGame」,而後選擇一個目錄,單擊「Create」按鈕。爲cocos2d項目的源代碼添加-fno-objc-arc選項讓項目支持ARC。
接下來,將所須要的資源文件,包括圖片和聲音拖到項目的「Resources」組。在遊戲開發當中,一般都會使用精靈表單來優化遊戲性能,在這個小遊戲當中,雖然這種性能優化並不會有特別明顯的效果,可是建議你們之後開發遊戲時都使用精靈表單來提升遊戲性能。使用Zwoptex將全部圖片製做成精靈表單,生成對應的airfightSheet.png和airfightSheet.plist文件,並將這兩個文件拖到項目的「Resources」組。
2添加遊戲菜單項功能
如今,咱們來爲遊戲添加一個菜單設置功能,在這裏能夠完成開始遊戲、遊戲設置、退出遊戲等操做。步驟以下。
①選擇「AirfightGame」組並單擊右鍵,選擇「New File」,在左邊欄中選擇「cocos2d v2.x」模板,在右邊的模板類中選擇「CCNode class」模板類,「Subclass of」選擇「CCLayer」,而後單擊「Next」按鈕。命名爲「MenuLayer」,而後單擊「Create」按鈕。
MenuLayer繼承自CCLayer,提供一個類方法scene供CCDirector對象調用。該類的做用是顯示一個菜單場景,讓用戶選擇。
打開MenuLayer.m文件,實現代碼以下。
程序清單:codes/13/13.14/AirfightGame/AirfightGame/MenuLayer.m
03 |
if ( (self=[super init]) ) { |
04 |
CGSize winSize = [[CCDirector sharedDirector] winSize]; |
06 |
CCMenuItemFont* startItem = [CCMenuItemFont itemWithString:@ "開始遊戲" |
07 |
target:self selector:@selector(startGame:)]; |
08 |
startItem.position=ccp(winSize.width/2, winSize.height*0.6); |
10 |
CCMenuItemFont* settingItem = [CCMenuItemFont itemWithString:@ "遊戲設置" |
11 |
target:self selector:@selector(setting:)]; |
13 |
settingItem.position=ccp(winSize.width/2, winSize.height*0.4); |
15 |
CCMenu* menu = [CCMenu menuWithItems:startItem,settingItem, nil]; |
16 |
menu.position = CGPointZero; |
init方法比較簡單,建立了兩個CCMenuItemFont,選擇標籤時會調用對應的startGame:和setting:方法,並將它們添加到CCMenu當中,再將CCMenu添加爲當前層的子節點。
②添加startGame:和setting:兩個方法,實現代碼以下(程序清單同上):
1 |
-( void ) startGame:(id)sender{ |
3 |
CCTransitionSlideInL* transitionScene = [CCTransitionSlideInL |
4 |
transitionWithDuration:2.0 scene:[PreloadLayer scene]]; |
5 |
[[CCDirector sharedDirector] replaceScene:transitionScene]; |
startGame:方法很是簡單,當用戶選擇「開始遊戲」標籤時,場景切換到PreloadLayer,在下一節中將重點介紹PreloadLayer(程序清單同上)。
1 |
-( void ) setting:(id)sender{ |
3 |
CCTransitionSlideInL* transitionScene = [CCTransitionSlideInL |
4 |
transitionWithDuration:2.0 scene:[SettingLayer scene]]; |
5 |
[[CCDirector sharedDirector] replaceScene:transitionScene]; |
當用戶選擇「遊戲設置」標籤時,場景切換到SettingLayer,進行遊戲設置。
③同上面的步驟同樣,使用「cocos2d v2.x」模板建立一個類並命名爲「SettingLayer」,繼承自CCLayer。該類的實現代碼以下。
程序清單:codes/13/13.14/AirfightGame/AirfightGame/SettingLayer.m
03 |
if ( (self=[super init]) ) { |
04 |
CGSize winSize = [[CCDirector sharedDirector] winSize]; |
06 |
CCMenuItemFont* musicItem = [CCMenuItemFont itemWithString:@ "背景音樂:" ]; |
07 |
musicItem.position = ccp(winSize.width*0.4, winSize.height*0.6); |
09 |
CCMenuItemFont* musicOn = [CCMenuItemFont itemWithString:@ "開" ]; |
10 |
CCMenuItemFont* musicOff = [CCMenuItemFont itemWithString:@ "關" ]; |
12 |
CCMenuItemToggle* musicToggle = [CCMenuItemToggle itemWithTarget:self |
13 |
selector:@selector(change:) items:musicOff,musicOn, nil]; |
14 |
musicToggle.position = ccp(winSize.width*0.6, winSize.height*0.6); |
16 |
CCMenuItemFont* returnItem = [CCMenuItemFont itemWithString:@ "返回主菜單" |
17 |
target:self selector:@selector(backToMainLayer:)]; |
18 |
returnItem.position = ccp(winSize.width/2, winSize.height*0.4); |
20 |
CCMenu* menu = [CCMenu menuWithItems:musicItem,musicToggle,returnItem, nil]; |
21 |
menu.position = CGPointZero; |
24 |
NSUserDefaults* userDef = [NSUserDefaults standardUserDefaults]; |
26 |
if (![userDef boolForKey:@ "music" ]){ |
27 |
musicToggle.selectedIndex = 1; |
32 |
-( void ) change:(id)sender{ |
34 |
if ([CDAudioManager sharedManager].mute == TRUE){ |
35 |
[CDAudioManager sharedManager].mute = FALSE; |
37 |
[CDAudioManager sharedManager].mute = TRUE; |
39 |
NSUserDefaults* userDef = [NSUserDefaults standardUserDefaults]; |
40 |
CCMenuItemToggle* tooggle = (CCMenuItemToggle*)sender; |
42 |
if (tooggle.selectedIndex == 1){ |
43 |
[userDef setBool:NO forKey:@ "music" ]; |
45 |
[userDef setBool:YES forKey:@ "music" ]; |
49 |
-( void ) backToMainLayer:(id)sender{ |
50 |
CCTransitionSlideInL* transitionScene = |
51 |
[CCTransitionSlideInL transitionWithDuration:2.0 scene:[MenuLayer scene]]; |
52 |
[[CCDirector sharedDirector] replaceScene:transitionScene]; |
SettingLayer類代碼在13.13.2節中已經詳細介紹過,這裏再也不贅述。
④修改IntroLayer.m文件
IntroLayer默認加載HelloWorldLayer,但此時咱們再也不使用HelloWorldLayer做爲應用的第一個場景,而是使用MenuLayer做爲應用的第一個場景,所以須要修改IntroLayer,將IntroLayer改成加載MenuLayer場景。修改以下。
在IntroLayer.m文件的頂部添加所包含的頭文件:
修改-(void) makeTransition:(ccTime)dt方法,將該方法改爲下面的代碼。
程序清單:codes/13/13.14/AirfightGame/AirfightGame/IntroLayer.m
1 |
-( void ) makeTransition:(ccTime)dt |
3 |
[[CCDirector sharedDirector] replaceScene: |
4 |
[CCTransitionFade transitionWithDuration:1.0 |
5 |
scene:[MenuLayer scene] withColor:ccWHITE]]; |
編譯並運行遊戲,運行時模擬器顯示效果如圖13.58所示。
3預加載遊戲資源
在真實項目當中,在遊戲開始前,都會預先加載遊戲所須要的圖片、背景音樂、音效等資源,這裏介紹如何製做一個PreloadLayer來預加載遊戲資源。
1. 建立PreloadLayer
選擇「AirfightGame」組並單擊右鍵,選擇「New File」,在左邊欄中選擇「cocos2d v2.x」模板,在右邊的模板類中選擇「CCNode class」模板類,「Subclass of」選擇「CCLayer」,而後單擊「Next」按鈕。命名爲「PreloadLayer」,而後單擊「Create」按鈕。
PreloadLayer繼承自CCLayer,提供一個類方法scene供CCDirector對象調用。該類的做用是預加載遊戲資源,在加載過程當中會顯示一個進度條,進度條所有顯示完成表明加載完畢,加載完畢後顯示遊戲主場景。
首先打開PreloadLayer.m文件,先在文件上方定義一個私有的Category。實現代碼以下。
程序清單:codes/13/13.14/AirfightGame/AirfightGame/PreloadLayer.m
/**
定義一個私有的Category,爲了避免讓API暴露給客戶端
將一些類內部所使用的方法和變量放在私有的擴展裏面,而不是直接聲明在頭文件當中
*/
@interface PreloadLayer ()
- (void) loadMusics:(NSArray *) musicFiles; // 加載背景音樂
- (void) loadSounds:(NSArray *) soundClips; // 加載遊戲音效
- (void) loadSpriteSheets:(NSArray *) spriteSheets; // 加載精靈表單
- (void) loadingComplete; // 資源所有加載完成,切換到另外一個遊戲場景
- (void) progressUpdate; // 更新遊戲進度條,計算什麼時候加載完成
@end;
這裏定義了一系列的load方法,每一個方法接收一個NSArray數組做爲參數。這些參數表明一些具體資源的文件名,參數值會從一個配置文件中讀取出來,該配置文件在以後的代碼實現時會給出。
而後定義3個變量,其中sourceCount用來保存遊戲須要加載的資源總數;progress用於顯示進度條,CCProgressTimer 類是cocos2d中對進度條的一個封裝,用來實現各類進度條功能,很是方便,以後咱們還會使用該類來實現遊戲的自定義血條量;progressInterval表明進度條更新的次數。實現代碼以下:
@implementation PreloadLayer
// 用來保存遊戲須要加載的資源總數
int sourceCount;
// 顯示進度條的成員變量
CCProgressTimer* progress;
// 表明進度條更新的次數
float progressInterval;
2. PreloadLayer的具體實現
建立一個preloadResources.plist文件,該文件用於保存項目須要的全部資源文件,文件內容如圖13.59所示。

能夠看出,加載的音效是b0.mp3,精靈表單是airfightSheet.plist,背景音樂是s3.wav。
在PreloadLayer.m文件中添加代碼。實現代碼以下。
程序清單:codes/13/13.14/AirfightGame/AirfightGame/PreloadLayer.m
+ (CCScene *) scene
{
CCScene* scene = [CCScene node];
PreloadLayer* layer = [PreloadLayer node];
[scene addChild:layer];
return scene;
}
- (id) init{
if((self = [super init])){
// 獲取屏幕大小
CGSize winSize = [[CCDirector sharedDirector] winSize];
// 建立一個進度條精靈
CCSprite* barSprite = [CCSprite spriteWithFile:@"progressbar.png"];
// 初始化一個CCProgressTimer進度條對象
progress = [CCProgressTimer progressWithSprite:barSprite];
// setPercentage:0.0f,表示並未加載任何資源,表如今屏幕上就是什麼也看不見
[progress setPercentage:0.0f];
// 因爲圖片大小關係,把scale設置成0.5,即縮小一半
progress.scale = 0.5;
// 設置進度條動畫的起始位置,默認在圖片的中點
// 若是想要顯示從左到右的一個動畫效果,必須改爲(0,y)
progress.midpoint = ccp(0,0.5);
// barChangeRate表示是否改變水平或者垂直方向的比例,設置成1表示改變,0表示不改變
progress.barChangeRate = ccp(1,0);
// 本例製做一個從左至右的水平進度條,因此midpoint應該是(0,0.5)
// 由於x方向須要改變,而y方向不須要改變,因此barChangeRate = ccp(1, 0)
// kCCProgressTimerTypeBar表示爲條形進度條
progress.type = kCCProgressTimerTypeBar;
// 設置position在中心點
[progress setPosition:ccp(winSize.width/2,winSize.height/2)];
// 將進度條添加爲當前層的子節點
[self addChild:progress];
}
return self;
}
- (void) onEnterTransitionDidFinish{
[super onEnterTransitionDidFinish];
// 加載preloadResources.plist配置文件
NSString* path = [[CCFileUtils sharedFileUtils]
fullPathFromRelativePath:@"preloadResources.plist"];
// 讀取配置文件中的遊戲資源名稱列表,返回一個NSDictionary對象
NSDictionary* resources = [NSDictionary dictionaryWithContentsOfFile:path];
// 經過key值取出每種不一樣類型資源的數組
NSArray *spriteSheets = [resources objectForKey:@"SpriteSheets"];
NSArray *sounds = [resources objectForKey:@"Sounds"];
NSArray *musics = [resources objectForKey:@"Musics"];
// 調用數組的count方法獲得總共須要加載的資源數量
sourceCount = [spriteSheets count] + [sounds count] + [musics count];
// 設置進度條更新次數=100/須要加載的資源數量
progressInterval = 100.0 / (float) sourceCount;
// 調用performSelectorOnMainThread在主線程上依次加載每種類型的遊戲資源
// waitUntilDone的值爲YES能保證全部的資源按照序列依次加載
if(sounds){
[self performSelectorOnMainThread:@selector(loadSounds:)
withObject:sounds waitUntilDone:YES];
}
if(spriteSheets){
[self performSelectorOnMainThread:@selector(loadSpriteSheets:)
withObject:spriteSheets waitUntilDone:YES];
}
if(musics){
[self performSelectorOnMainThread:@selector(loadMusic:)
withObject:musics waitUntilDone:YES];
}
}
// 加載背景音樂
- (void) loadMusics:(NSArray *)musicFiles{
for (NSString *music in musicFiles) {
[[SimpleAudioEngine sharedEngine] preloadBackgroundMusic:music];
[self progressUpdate];
}
}
// 加載聲音
- (void) loadSounds:(NSArray *)soundClips{
for (NSString *soundClip in soundClips) {
[[SimpleAudioEngine sharedEngine] preloadEffect:soundClip];
[self progressUpdate];
}
}
// 加載精靈表單
- (void) loadSpriteSheets:(NSArray *)spriteSheets{
for (NSString *spriteSheet in spriteSheets) {
// 該方法會加載與該plist文件名稱相同但後綴爲.png的紋理圖片
// 把該plist的全部spriteFrame信息讀取出來
// 在以後的代碼中能夠經過spriteFrameWithName獲取相應的精靈幀
// 本例中airfightSheet.plist對應airfightSheet.png
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile: spriteSheet];
[self progressUpdate];
}
}
- (void) progressUpdate{
// 每次調用該方法說明加載一個資源,自減更新資源總數
if (--sourceCount) {
[progress setPercentage:100.0f-(progressInterval * sourceCount)];
}else{
// CCProgressFromTo動做用於以漸進的方式顯示圖片
// actionWithDuration表示持續0.5秒,from表示進度條百分百從開始一直到100
CCProgressFromTo *ac = [CCProgressFromTo actionWithDuration:0.5
from:progress.percentage to:100];
// 當資源所有加載完畢時調用loadingComplete方法
CCCallBlock *callback = [CCCallBlock actionWithBlock:^() {
[self loadingComplete];
}];
// CCSequence組合動做
id action = [CCSequence actions:ac.callback.nil];
// 進度條執行動做
[progress runAction:action];
}
}
// 延遲2秒以後運行一個場景切換特效跳轉到遊戲主場景,即HelloWorldLayer
- (void) loadingComplete{
CCDelayTime *delay = [CCDelayTime actionWithDuration:2.0f];
CCCallBlock *callblock = [CCCallBlock actionWithBlock:^(void) {
[[CCDirector sharedDirector] replaceScene:
[CCTransitionFade transitionWithDuration:1.0f scene:[HelloWorldLayer scene]]];
}];
CCSequence *sequence = [CCSequence actions:delay.callblock.nil];
[self runAction:sequence];
}
@end
下面依次解釋以上代碼中的每個方法。
+(CCScene *) scene方法很簡單,和前面的同樣,首先建立了一個scene場景,而後建立了一個PreloadLayer層,將PreloadLayer層做爲scene場景的子節點,最後返回scene場景。
init方法首先獲取屏幕窗口大小,而後建立了一個進度條。這裏使用progressbar.png圖片初始化一個精靈,再經過該精靈初始化一個CCProgressTimer對象,設置setPercentage屬性爲0,表示當前未加載任何資源,表如今屏幕上就是什麼也看不見。因爲圖片大小關係,把scale設置成0.5,即縮小一半。
接下來設置CCProgressTimer對象最重要的3個參數。
q
midpoint:表示進度條動畫的起始位置,默認在圖片的中點,若是想要顯示從左到右的一個動畫效果,則必須改爲(0,y)。
q
barChangeRate:表示是否改變水平或者垂直方向的比例,設置成1表示改變,0表示不改變。本例製做一個從左至右的水平進度條,因此midpoint應該是(0,0.5)。由於x方向須要改變,而y方向不須要改變,因此設置barChangeRate爲ccp(1,0)。
q
type:設置爲kCCProgressTimerTypeBar,表示條形進度條。
關於CCProgressTimer類的使用能夠參考官方文檔,讀者也能夠找到cocos2d的示例項目cocos2d-tests-ios.xcodeproj,並運行ActionProgressTest這個TARGET。感興趣的讀者也能夠仔細分析該項目中的ActionProgressTest.m源文件(位於項目的tests目錄下)來掌握不一樣progress的用法示例。
最後設置CCProgressTimer對象的位置,並添加爲當前層的子節點。
onEnterTransitionDidFinish方法加載配置文件preloadResources.plist,讀取配置文件中的遊戲資源名稱列表並存儲在不一樣的數組中。首先使用CCFileUtil得到plist文件的具體路徑,調用NSDictionary的dictionaryWithContentsOfFile方法把該文件轉換成一個字典對象。而後經過字典的key值取出不一樣類型資源的數組,調用每一個數組的count方法累加獲得總共須要加載的資源總數量,使用100除以資源總數量得到進度條須要更新次數用於以後計算進度條顯示的百分比。最後將數組做爲參數調用performSelectorOnMainThread: withObject: waitUntilDone:方法在主線程中依次加載每種類型的遊戲資源,將waitUntilDone的值設置爲「YES」能保證全部的資源按照序列依次加載。
loadMusics:和loadSounds:方法比較簡單,經過循環遍歷數組,預加載背景音樂和音效,加載完後調用progressUpdate方法更新進度條。
這裏須要注意的是loadSpriteSheets:方法,該方法循環遍歷數組,數組的每一個元素是一個plist文件名稱,調用CCSpriteFrameCache的addSpriteFramesWithFile時,該方法會加載與該plist文件名稱相同但後綴爲.png的紋理圖片(本例中airfightSheet.plist對應airfightSheet.png),把該plist的全部spriteFrame信息讀取出來,以後在項目當中就能夠經過spriteFrameWithName獲取相應的精靈幀了。
progressUpdate方法比較簡單,每次被調用時自減更新資源總數變量,修改進度條的百分比。當資源所有加載完畢時調用loadingComplete方法。
loadingComplete方法被調用說明資源加載完畢,延遲2秒後運行一個場景切換特效跳轉到遊戲主場景HelloWorldLayer。
編譯並運行遊戲,選擇「開始遊戲」菜單項,模擬器首先會顯示一個進度條,進度條所有顯示完畢切換到HelloWorldLayer顯示經典的Hello World畫面。恭喜你!資源文件加載成功,進度條功能實現。運行時模擬器顯示效果如圖13.60所示。
————本文節選自《瘋狂ios講義(下)》