瘋狂打飛機(jī)游戲
本次我們將帶領(lǐng)大家手動(dòng)完成一個(gè)簡單但功能完整的打飛機(jī)游戲,實(shí)現(xiàn)飛機(jī)飛行、飛機(jī)碰撞、發(fā)射×××、敵機(jī)發(fā)射大×××、背景音樂、×××音效、分?jǐn)?shù)統(tǒng)計(jì)、菜單管理等功能。它雖然不會為你贏得什么獎(jiǎng)項(xiàng),但是可以總結(jié)前面所學(xué)的所有知識,幫助大家更好地掌握cocos2d基本對象的使用,同時(shí)體驗(yàn)cocos2d的強(qiáng)大以及易用性。
網(wǎng)站建設(shè)公司,為您提供網(wǎng)站建設(shè),網(wǎng)站制作,網(wǎng)頁設(shè)計(jì)及定制網(wǎng)站建設(shè)服務(wù),專注于成都企業(yè)網(wǎng)站建設(shè),高端網(wǎng)頁制作,對電動(dòng)窗簾等多個(gè)行業(yè)擁有豐富的網(wǎng)站建設(shè)經(jīng)驗(yàn)的網(wǎng)站建設(shè)公司。專業(yè)網(wǎng)站設(shè)計(jì),網(wǎng)站優(yōu)化推廣哪家好,專業(yè)成都網(wǎng)站推廣優(yōu)化,H5建站,響應(yīng)式網(wǎng)站。
1開始前的準(zhǔn)備工作
首先打開Xcode,使用cocos2d iOS模板新建一個(gè)項(xiàng)目,命名為“AirfightGame”,然后選擇一個(gè)目錄,單擊“Create”按鈕。為cocos2d項(xiàng)目的源代碼添加-fno-objc-arc選項(xiàng)讓項(xiàng)目支持ARC。
接下來,將所需要的資源文件,包括圖片和聲音拖到項(xiàng)目的“Resources”組。在游戲開發(fā)當(dāng)中,通常都會使用精靈表單來優(yōu)化游戲性能,在這個(gè)小游戲當(dāng)中,雖然這種性能優(yōu)化并不會有特別明顯的效果,但是建議大家以后開發(fā)游戲時(shí)都使用精靈表單來提高游戲性能。使用Zwoptex將所有圖片制作成精靈表單,生成對應(yīng)的airfightSheet.png和airfightSheet.plist文件,并將這兩個(gè)文件拖到項(xiàng)目的“Resources”組。
2添加游戲菜單項(xiàng)功能
現(xiàn)在,我們來為游戲添加一個(gè)菜單設(shè)置功能,在這里可以完成開始游戲、游戲設(shè)置、退出游戲等操作。步驟如下。
①選擇“AirfightGame”組并單擊右鍵,選擇“New File”,在左邊欄中選擇“cocos2d v2.x”模板,在右邊的模板類中選擇“CCNode class”模板類,“Subclass of”選擇“CCLayer”,然后單擊“Next”按鈕。命名為“MenuLayer”,然后單擊“Create”按鈕。
MenuLayer繼承自CCLayer,提供一個(gè)類方法scene供CCDirector對象調(diào)用。該類的作用是顯示一個(gè)菜單場景,讓用戶選擇。
打開MenuLayer.m文件,實(shí)現(xiàn)代碼如下。
程序清單:codes/13/13.14/AirfightGame/AirfightGame/MenuLayer.m
-(id) init
{
if( (self=[super init]) ) {
CGSize winSize = [[CCDirector sharedDirector] winSize];
// 創(chuàng)建“開始游戲”標(biāo)簽,當(dāng)觸碰該標(biāo)簽時(shí),調(diào)用startGame:方法
CCMenuItemFont* startItem = [CCMenuItemFont itemWithString:@"開始游戲"
target:self selector:@selector(startGame:)];
startItem.position=ccp(winSize.width/2, winSize.height*0.6);
// 創(chuàng)建“游戲設(shè)置”標(biāo)簽,當(dāng)觸碰該標(biāo)簽時(shí),調(diào)用setting:方法
CCMenuItemFont* settingItem = [CCMenuItemFont itemWithString:@"游戲設(shè)置"
target:self selector:@selector(setting:)];
// 設(shè)置“游戲設(shè)置”標(biāo)簽位置
settingItem.position=ccp(winSize.width/2, winSize.height*0.4);
// 創(chuàng)建控制菜單,并將兩個(gè)標(biāo)簽添加進(jìn)去
CCMenu* menu = [CCMenu menuWithItems:startItem,settingItem, nil];
menu.position = CGPointZero;
[self addChild:menu];
}
return self;
}
init方法比較簡單,創(chuàng)建了兩個(gè)CCMenuItemFont,選擇標(biāo)簽時(shí)會調(diào)用對應(yīng)的startGame:和setting:方法,并將它們添加到CCMenu當(dāng)中,再將CCMenu添加為當(dāng)前層的子節(jié)點(diǎn)。
②添加startGame:和setting:兩個(gè)方法,實(shí)現(xiàn)代碼如下(程序清單同上):
-(void) startGame:(id)sender{
// 切換到PreloadLayer場景
CCTransitionSlideInL* transitionScene = [CCTransitionSlideInL
transitionWithDuration:2.0 scene:[PreloadLayer scene]];
[[CCDirector sharedDirector] replaceScene:transitionScene];
}
startGame:方法非常簡單,當(dāng)用戶選擇“開始游戲”標(biāo)簽時(shí),場景切換到PreloadLayer,在下一節(jié)中將重點(diǎn)介紹PreloadLayer(程序清單同上)。
-(void) setting:(id)sender{
// 切換到SettingLayer場景
CCTransitionSlideInL* transitionScene = [CCTransitionSlideInL
transitionWithDuration:2.0 scene:[SettingLayer scene]];
[[CCDirector sharedDirector] replaceScene:transitionScene];
}
當(dāng)用戶選擇“游戲設(shè)置”標(biāo)簽時(shí),場景切換到SettingLayer,進(jìn)行游戲設(shè)置。
③同上面的步驟一樣,使用“cocos2d v2.x”模板創(chuàng)建一個(gè)類并命名為“SettingLayer”,繼承自CCLayer。該類的實(shí)現(xiàn)代碼如下。
程序清單:codes/13/13.14/AirfightGame/AirfightGame/SettingLayer.m
-(id) init
{
if( (self=[super init]) ) {
CGSize winSize = [[CCDirector sharedDirector] winSize];
// 提示菜單項(xiàng)
CCMenuItemFont* musicItem = [CCMenuItemFont itemWithString:@"背景音樂:"];
musicItem.position = ccp(winSize.width*0.4, winSize.height*0.6);
// 創(chuàng)建“開”和“關(guān)”菜單項(xiàng)
CCMenuItemFont* musicOn = [CCMenuItemFont itemWithString:@"開"];
CCMenuItemFont* musicOff = [CCMenuItemFont itemWithString:@"關(guān)"];
// CCMenuItemToggle,默認(rèn)顯示“開”。開=0,關(guān)=1
CCMenuItemToggle* musicToggle = [CCMenuItemToggle itemWithTarget:self
selector:@selector(change:) items:musicOff,musicOn, nil];
musicToggle.position = ccp(winSize.width*0.6, winSize.height*0.6);
// 創(chuàng)建“返回主菜單“菜單項(xiàng)
CCMenuItemFont* returnItem = [CCMenuItemFont itemWithString:@"返回主菜單"
target:self selector:@selector(backToMainLayer:)];
returnItem.position = ccp(winSize.width/2, winSize.height*0.4);
// 創(chuàng)建控制菜單,并將3個(gè)標(biāo)簽添加進(jìn)去
CCMenu* menu = [CCMenu menuWithItems:musicItem,musicToggle,returnItem, nil];
menu.position = CGPointZero;
[self addChild:menu];
// NSUserDefaults用戶首選項(xiàng)可以用來保存用戶在操作應(yīng)用的過程中設(shè)置的首選項(xiàng)。
NSUserDefaults* userDef = [NSUserDefaults standardUserDefaults];
// 如果Bool為No,則顯示1=關(guān)
if(![userDef boolForKey:@"music"]){
musicToggle.selectedIndex = 1;
}
}
return self;
}
-(void) change:(id)sender{
// 判斷mute(靜音)屬性,根據(jù)屬性狀態(tài)進(jìn)行切換
if([CDAudioManager sharedManager].mute == TRUE){
[CDAudioManager sharedManager].mute = FALSE;
}else{
[CDAudioManager sharedManager].mute = TRUE;
}
NSUserDefaults* userDef = [NSUserDefaults standardUserDefaults];
CCMenuItemToggle* tooggle = (CCMenuItemToggle*)sender;
// 關(guān)=1,設(shè)置Bool為NO
if(tooggle.selectedIndex == 1){
[userDef setBool:NO forKey:@"music"];
}else{
[userDef setBool:YES forKey:@"music"];
}
}
// 定義一個(gè)CCTransitionSlideInL場景切換效果,并使用CCDirector單例對象來切換場景
-(void) backToMainLayer:(id)sender{
CCTransitionSlideInL* transitionScene =
[CCTransitionSlideInL transitionWithDuration:2.0 scene:[MenuLayer scene]];
[[CCDirector sharedDirector] replaceScene:transitionScene];
}
SettingLayer類代碼在13.13.2節(jié)中已經(jīng)詳細(xì)介紹過,這里不再贅述。
④修改IntroLayer.m文件
IntroLayer默認(rèn)加載HelloWorldLayer,但此時(shí)我們不再使用HelloWorldLayer作為應(yīng)用的第一個(gè)場景,而是使用MenuLayer作為應(yīng)用的第一個(gè)場景,因此需要修改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]];
}
ios講義之瘋狂打飛機(jī)(1)
瘋狂打飛機(jī)游戲
本次我們將帶領(lǐng)大家手動(dòng)完成一個(gè)簡單但功能完整的打飛機(jī)游戲,實(shí)現(xiàn)飛機(jī)飛行、飛機(jī)碰撞、發(fā)射×××、敵機(jī)發(fā)射大×××、背景音樂、×××音效、分?jǐn)?shù)統(tǒng)計(jì)、菜單管理等功能。它雖然不會為你贏得什么獎(jiǎng)項(xiàng),但是可以總結(jié)前面所學(xué)的所有知識,幫助大家更好地掌握cocos2d基本對象的使用,同時(shí)體驗(yàn)cocos2d的強(qiáng)大以及易用性。
1開始前的準(zhǔn)備工作
首先打開Xcode,使用cocos2d iOS模板新建一個(gè)項(xiàng)目,命名為“AirfightGame”,然后選擇一個(gè)目錄,單擊“Create”按鈕。為cocos2d項(xiàng)目的源代碼添加-fno-objc-arc選項(xiàng)讓項(xiàng)目支持ARC。
接下來,將所需要的資源文件,包括圖片和聲音拖到項(xiàng)目的“Resources”組。在游戲開發(fā)當(dāng)中,通常都會使用精靈表單來優(yōu)化游戲性能,在這個(gè)小游戲當(dāng)中,雖然這種性能優(yōu)化并不會有特別明顯的效果,但是建議大家以后開發(fā)游戲時(shí)都使用精靈表單來提高游戲性能。使用Zwoptex將所有圖片制作成精靈表單,生成對應(yīng)的airfightSheet.png和airfightSheet.plist文件,并將這兩個(gè)文件拖到項(xiàng)目的“Resources”組。
2添加游戲菜單項(xiàng)功能
現(xiàn)在,我們來為游戲添加一個(gè)菜單設(shè)置功能,在這里可以完成開始游戲、游戲設(shè)置、退出游戲等操作。步驟如下。
①選擇“AirfightGame”組并單擊右鍵,選擇“New File”,在左邊欄中選擇“cocos2d v2.x”模板,在右邊的模板類中選擇“CCNode class”模板類,“Subclass of”選擇“CCLayer”,然后單擊“Next”按鈕。命名為“MenuLayer”,然后單擊“Create”按鈕。
MenuLayer繼承自CCLayer,提供一個(gè)類方法scene供CCDirector對象調(diào)用。該類的作用是顯示一個(gè)菜單場景,讓用戶選擇。
打開MenuLayer.m文件,實(shí)現(xiàn)代碼如下。
程序清單:codes/13/13.14/AirfightGame/AirfightGame/MenuLayer.m
03 |
if ( (self=[super init]) ) { |
04 |
CGSize winSize = [[CCDirector sharedDirector] winSize]; |
05 |
// 創(chuàng)建“開始游戲”標(biāo)簽,當(dāng)觸碰該標(biāo)簽時(shí),調(diào)用startGame:方法 |
06 |
CCMenuItemFont* startItem = [CCMenuItemFont itemWithString:@ "開始游戲" |
07 |
target:self selector:@selector(startGame:)]; |
08 |
startItem.position=ccp(winSize.width/2, winSize.height*0.6); |
09 |
// 創(chuàng)建“游戲設(shè)置”標(biāo)簽,當(dāng)觸碰該標(biāo)簽時(shí),調(diào)用setting:方法 |
10 |
CCMenuItemFont* settingItem = [CCMenuItemFont itemWithString:@ "游戲設(shè)置" |
11 |
target:self selector:@selector(setting:)]; |
12 |
// 設(shè)置“游戲設(shè)置”標(biāo)簽位置 |
13 |
settingItem.position=ccp(winSize.width/2, winSize.height*0.4); |
14 |
// 創(chuàng)建控制菜單,并將兩個(gè)標(biāo)簽添加進(jìn)去 |
15 |
CCMenu* menu = [CCMenu menuWithItems:startItem,settingItem, nil]; |
16 |
menu.position = CGPointZero; |
init方法比較簡單,創(chuàng)建了兩個(gè)CCMenuItemFont,選擇標(biāo)簽時(shí)會調(diào)用對應(yīng)的startGame:和setting:方法,并將它們添加到CCMenu當(dāng)中,再將CCMenu添加為當(dāng)前層的子節(jié)點(diǎn)。
②添加startGame:和setting:兩個(gè)方法,實(shí)現(xiàn)代碼如下(程序清單同上):
1 | -( void ) startGame:(id)sender{ |
3 |
CCTransitionSlideInL* transitionScene = [CCTransitionSlideInL |
4 |
transitionWithDuration:2.0 scene:[PreloadLayer scene]]; |
5 |
[[CCDirector sharedDirector] replaceScene:transitionScene]; |
startGame:方法非常簡單,當(dāng)用戶選擇“開始游戲”標(biāo)簽時(shí),場景切換到PreloadLayer,在下一節(jié)中將重點(diǎn)介紹PreloadLayer(程序清單同上)。
1 | -( void ) setting:(id)sender{ |
3 |
CCTransitionSlideInL* transitionScene = [CCTransitionSlideInL |
4 |
transitionWithDuration:2.0 scene:[SettingLayer scene]]; |
5 |
[[CCDirector sharedDirector] replaceScene:transitionScene]; |
當(dāng)用戶選擇“游戲設(shè)置”標(biāo)簽時(shí),場景切換到SettingLayer,進(jìn)行游戲設(shè)置。
③同上面的步驟一樣,使用“cocos2d v2.x”模板創(chuàng)建一個(gè)類并命名為“SettingLayer”,繼承自CCLayer。該類的實(shí)現(xiàn)代碼如下。
程序清單: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); |
08 |
// 創(chuàng)建“開”和“關(guān)”菜單項(xiàng) |
09 |
CCMenuItemFont* musicOn = [CCMenuItemFont itemWithString:@ "開" ]; |
10 |
CCMenuItemFont* musicOff = [CCMenuItemFont itemWithString:@ "關(guān)" ]; |
11 |
// CCMenuItemToggle,默認(rèn)顯示“開”。開=0,關(guān)=1 |
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); |
15 |
// 創(chuàng)建“返回主菜單“菜單項(xiàng) |
16 |
CCMenuItemFont* returnItem = [CCMenuItemFont itemWithString:@ "返回主菜單" |
17 |
target:self selector:@selector(backToMainLayer:)]; |
18 |
returnItem.position = ccp(winSize.width/2, winSize.height*0.4); |
19 |
// 創(chuàng)建控制菜單,并將3個(gè)標(biāo)簽添加進(jìn)去 |
20 |
CCMenu* menu = [CCMenu menuWithItems:musicItem,musicToggle,returnItem, nil]; |
21 |
menu.position = CGPointZero; |
23 |
// NSUserDefaults用戶首選項(xiàng)可以用來保存用戶在操作應(yīng)用的過程中設(shè)置的首選項(xiàng)。 |
24 |
NSUserDefaults* userDef = [NSUserDefaults standardUserDefaults]; |
25 |
// 如果Bool為No,則顯示1=關(guān) |
26 |
if (![userDef boolForKey:@ "music" ]){ |
27 |
musicToggle.selectedIndex = 1; |
32 | -( void ) change:(id)sender{ |
33 |
// 判斷mute(靜音)屬性,根據(jù)屬性狀態(tài)進(jìn)行切換 |
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; |
41 |
// 關(guān)=1,設(shè)置Bool為NO |
42 |
if (tooggle.selectedIndex == 1){ |
43 |
[userDef setBool:NO forKey:@ "music" ]; |
45 |
[userDef setBool:YES forKey:@ "music" ]; |
48 | // 定義一個(gè)CCTransitionSlideInL場景切換效果,并使用CCDirector單例對象來切換場景 |
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節(jié)中已經(jīng)詳細(xì)介紹過,這里不再贅述。
④修改IntroLayer.m文件
IntroLayer默認(rèn)加載HelloWorldLayer,但此時(shí)我們不再使用HelloWorldLayer作為應(yīng)用的第一個(gè)場景,而是使用MenuLayer作為應(yīng)用的第一個(gè)場景,因此需要修改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]]; |
編譯并運(yùn)行游戲,運(yùn)行時(shí)模擬器顯示效果如圖13.58所示。
3預(yù)加載游戲資源
在真實(shí)項(xiàng)目當(dāng)中,在游戲開始前,都會預(yù)先加載游戲所需要的圖片、背景音樂、音效等資源,這里介紹如何制作一個(gè)PreloadLayer來預(yù)加載游戲資源。
1. 創(chuàng)建PreloadLayer
選擇“AirfightGame”組并單擊右鍵,選擇“New File”,在左邊欄中選擇“cocos2d v2.x”模板,在右邊的模板類中選擇“CCNode class”模板類,“Subclass of”選擇“CCLayer”,然后單擊“Next”按鈕。命名為“PreloadLayer”,然后單擊“Create”按鈕。
PreloadLayer繼承自CCLayer,提供一個(gè)類方法scene供CCDirector對象調(diào)用。該類的作用是預(yù)加載游戲資源,在加載過程中會顯示一個(gè)進(jìn)度條,進(jìn)度條全部顯示完成代表加載完畢,加載完畢后顯示游戲主場景。
首先打開PreloadLayer.m文件,先在文件上方定義一個(gè)私有的Category。實(shí)現(xiàn)代碼如下。
程序清單:codes/13/13.14/AirfightGame/AirfightGame/PreloadLayer.m
/**
定義一個(gè)私有的Category,為了不讓API暴露給客戶端
將一些類內(nèi)部所使用的方法和變量放在私有的擴(kuò)展里面,而不是直接聲明在頭文件當(dāng)中
*/
@interface PreloadLayer ()
- (void) loadMusics:(NSArray *) musicFiles; // 加載背景音樂
- (void) loadSounds:(NSArray *) soundClips; // 加載游戲音效
- (void) loadSpriteSheets:(NSArray *) spriteSheets; // 加載精靈表單
- (void) loadingComplete; // 資源全部加載完成,切換到另一個(gè)游戲場景
- (void) progressUpdate; // 更新游戲進(jìn)度條,計(jì)算何時(shí)加載完成
@end;
這里定義了一系列的load方法,每個(gè)方法接收一個(gè)NSArray數(shù)組作為參數(shù)。這些參數(shù)代表一些具體資源的文件名,參數(shù)值會從一個(gè)配置文件中讀取出來,該配置文件在之后的代碼實(shí)現(xiàn)時(shí)會給出。
然后定義3個(gè)變量,其中sourceCount用來保存游戲需要加載的資源總數(shù);progress用于顯示進(jìn)度條,CCProgressTimer 類是cocos2d中對進(jìn)度條的一個(gè)封裝,用來實(shí)現(xiàn)各種進(jìn)度條功能,非常方便,之后我們還會使用該類來實(shí)現(xiàn)游戲的自定義血條量;progressInterval代表進(jìn)度條更新的次數(shù)。實(shí)現(xiàn)代碼如下:
@implementation PreloadLayer
// 用來保存游戲需要加載的資源總數(shù)
int sourceCount;
// 顯示進(jìn)度條的成員變量
CCProgressTimer* progress;
// 代表進(jìn)度條更新的次數(shù)
float progressInterval;
2. PreloadLayer的具體實(shí)現(xiàn)
創(chuàng)建一個(gè)preloadResources.plist文件,該文件用于保存項(xiàng)目需要的所有資源文件,文件內(nèi)容如圖13.59所示。
可以看出,加載的音效是b0.mp3,精靈表單是airfightSheet.plist,背景音樂是s3.wav。
在PreloadLayer.m文件中添加代碼。實(shí)現(xiàn)代碼如下。
程序清單: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];
// 創(chuàng)建一個(gè)進(jìn)度條精靈
CCSprite* barSprite = [CCSprite spriteWithFile:@"progressbar.png"];
// 初始化一個(gè)CCProgressTimer進(jìn)度條對象
progress = [CCProgressTimer progressWithSprite:barSprite];
// setPercentage:0.0f,表示并未加載任何資源,表現(xiàn)在屏幕上就是什么也看不見
[progress setPercentage:0.0f];
// 由于圖片大小關(guān)系,把scale設(shè)置成0.5,即縮小一半
progress.scale = 0.5;
// 設(shè)置進(jìn)度條動(dòng)畫的起始位置,默認(rèn)在圖片的中點(diǎn)
// 如果想要顯示從左到右的一個(gè)動(dòng)畫效果,必須改成(0,y)
progress.midpoint = ccp(0,0.5);
// barChangeRate表示是否改變水平或者垂直方向的比例,設(shè)置成1表示改變,0表示不改變
progress.barChangeRate = ccp(1,0);
// 本例制作一個(gè)從左至右的水平進(jìn)度條,所以midpoint應(yīng)該是(0,0.5)
// 因?yàn)閤方向需要改變,而y方向不需要改變,所以barChangeRate = ccp(1, 0)
// kCCProgressTimerTypeBar表示為條形進(jìn)度條
progress.type = kCCProgressTimerTypeBar;
// 設(shè)置position在中心點(diǎn)
[progress setPosition:ccp(winSize.width/2,winSize.height/2)];
// 將進(jìn)度條添加為當(dāng)前層的子節(jié)點(diǎn)
[self addChild:progress];
}
return self;
}
- (void) onEnterTransitionDidFinish{
[super onEnterTransitionDidFinish];
// 加載preloadResources.plist配置文件
NSString* path = [[CCFileUtils sharedFileUtils]
fullPathFromRelativePath:@"preloadResources.plist"];
// 讀取配置文件中的游戲資源名稱列表,返回一個(gè)NSDictionary對象
NSDictionary* resources = [NSDictionary dictionaryWithContentsOfFile:path];
// 通過key值取出每種不同類型資源的數(shù)組
NSArray *spriteSheets = [resources objectForKey:@"SpriteSheets"];
NSArray *sounds = [resources objectForKey:@"Sounds"];
NSArray *musics = [resources objectForKey:@"Musics"];
// 調(diào)用數(shù)組的count方法得到總共需要加載的資源數(shù)量
sourceCount = [spriteSheets count] + [sounds count] + [musics count];
// 設(shè)置進(jìn)度條更新次數(shù)=100/需要加載的資源數(shù)量
progressInterval = 100.0 / (float) sourceCount;
// 調(diào)用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獲取相應(yīng)的精靈幀
// 本例中airfightSheet.plist對應(yīng)airfightSheet.png
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile: spriteSheet];
[self progressUpdate];
}
}
- (void) progressUpdate{
// 每次調(diào)用該方法說明加載一個(gè)資源,自減更新資源總數(shù)
if (--sourceCount) {
[progress setPercentage:100.0f-(progressInterval * sourceCount)];
}else{
// CCProgressFromTo動(dòng)作用于以漸進(jìn)的方式顯示圖片
// actionWithDuration表示持續(xù)0.5秒,from表示進(jìn)度條百分百從開始一直到100
CCProgressFromTo *ac = [CCProgressFromTo actionWithDuration:0.5
from:progress.percentage to:100];
// 當(dāng)資源全部加載完畢時(shí)調(diào)用loadingComplete方法
CCCallBlock *callback = [CCCallBlock actionWithBlock:^() {
[self loadingComplete];
}];
// CCSequence組合動(dòng)作
id action = [CCSequence actions:ac.callback.nil];
// 進(jìn)度條執(zhí)行動(dòng)作
[progress runAction:action];
}
}
// 延遲2秒之后運(yùn)行一個(gè)場景切換特效跳轉(zhuǎn)到游戲主場景,即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
下面依次解釋以上代碼中的每一個(gè)方法。
+(CCScene *) scene方法很簡單,和前面的一樣,首先創(chuàng)建了一個(gè)scene場景,然后創(chuàng)建了一個(gè)PreloadLayer層,將PreloadLayer層作為scene場景的子節(jié)點(diǎn),最后返回scene場景。
init方法首先獲取屏幕窗口大小,然后創(chuàng)建了一個(gè)進(jìn)度條。這里使用progressbar.png圖片初始化一個(gè)精靈,再通過該精靈初始化一個(gè)CCProgressTimer對象,設(shè)置setPercentage屬性為0,表示當(dāng)前未加載任何資源,表現(xiàn)在屏幕上就是什么也看不見。由于圖片大小關(guān)系,把scale設(shè)置成0.5,即縮小一半。
接下來設(shè)置CCProgressTimer對象最重要的3個(gè)參數(shù)。
qmidpoint:表示進(jìn)度條動(dòng)畫的起始位置,默認(rèn)在圖片的中點(diǎn),如果想要顯示從左到右的一個(gè)動(dòng)畫效果,則必須改成(0,y)。
qbarChangeRate:表示是否改變水平或者垂直方向的比例,設(shè)置成1表示改變,0表示不改變。本例制作一個(gè)從左至右的水平進(jìn)度條,所以midpoint應(yīng)該是(0,0.5)。因?yàn)?em>x方向需要改變,而y方向不需要改變,所以設(shè)置barChangeRate為ccp(1,0)。
qtype:設(shè)置為kCCProgressTimerTypeBar,表示條形進(jìn)度條。
關(guān)于CCProgressTimer類的使用可以參考官方文檔,讀者也可以找到cocos2d的示例項(xiàng)目cocos2d-tests-ios.xcodeproj,并運(yùn)行ActionProgressTest這個(gè)TARGET。感興趣的讀者也可以仔細(xì)分析該項(xiàng)目中的ActionProgressTest.m源文件(位于項(xiàng)目的tests目錄下)來掌握不同progress的用法示例。
最后設(shè)置CCProgressTimer對象的位置,并添加為當(dāng)前層的子節(jié)點(diǎn)。
onEnterTransitionDidFinish方法加載配置文件preloadResources.plist,讀取配置文件中的游戲資源名稱列表并存儲在不同的數(shù)組中。首先使用CCFileUtil獲得plist文件的具體路徑,調(diào)用NSDictionary的dictionaryWithContentsOfFile方法把該文件轉(zhuǎn)換成一個(gè)字典對象。然后通過字典的key值取出不同類型資源的數(shù)組,調(diào)用每個(gè)數(shù)組的count方法累加得到總共需要加載的資源總數(shù)量,使用100除以資源總數(shù)量獲得進(jìn)度條需要更新次數(shù)用于之后計(jì)算進(jìn)度條顯示的百分比。最后將數(shù)組作為參數(shù)調(diào)用performSelectorOnMainThread: withObject: waitUntilDone:方法在主線程中依次加載每種類型的游戲資源,將waitUntilDone的值設(shè)置為“YES”能保證所有的資源按照序列依次加載。
loadMusics:和loadSounds:方法比較簡單,通過循環(huán)遍歷數(shù)組,預(yù)加載背景音樂和音效,加載完后調(diào)用progressUpdate方法更新進(jìn)度條。
這里需要注意的是loadSpriteSheets:方法,該方法循環(huán)遍歷數(shù)組,數(shù)組的每個(gè)元素是一個(gè)plist文件名稱,調(diào)用CCSpriteFrameCache的addSpriteFramesWithFile時(shí),該方法會加載與該plist文件名稱相同但后綴為.png的紋理圖片(本例中airfightSheet.plist對應(yīng)airfightSheet.png),把該plist的所有spriteFrame信息讀取出來,之后在項(xiàng)目當(dāng)中就可以通過spriteFrameWithName獲取相應(yīng)的精靈幀了。
progressUpdate方法比較簡單,每次被調(diào)用時(shí)自減更新資源總數(shù)變量,修改進(jìn)度條的百分比。當(dāng)資源全部加載完畢時(shí)調(diào)用loadingComplete方法。
loadingComplete方法被調(diào)用說明資源加載完畢,延遲2秒后運(yùn)行一個(gè)場景切換特效跳轉(zhuǎn)到游戲主場景HelloWorldLayer。
編譯并運(yùn)行游戲,選擇“開始游戲”菜單項(xiàng),模擬器首先會顯示一個(gè)進(jìn)度條,進(jìn)度條全部顯示完畢切換到HelloWorldLayer顯示經(jīng)典的Hello World畫面。恭喜你!資源文件加載成功,進(jìn)度條功能實(shí)現(xiàn)。運(yùn)行時(shí)模擬器顯示效果如圖13.60所示。
————本文節(jié)選自《瘋狂ios講義(下)》
文章題目:瘋狂ios講義之瘋狂打飛機(jī)(1)
文章位置:http://bm7419.com/article14/gosdge.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信公眾號、外貿(mào)網(wǎng)站建設(shè)、移動(dòng)網(wǎng)站建設(shè)、服務(wù)器托管、建站公司、搜索引擎優(yōu)化
廣告
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源:
創(chuàng)新互聯(lián)