您好,登錄后才能下訂單哦!
現(xiàn)在,我們來給玩家加入游戲積分統(tǒng)計(jì)功能。步驟如下。
打開HelloWorldLayer.m文件,添加變量,實(shí)現(xiàn)代碼如下(程序清單同上)。
// 分?jǐn)?shù)值標(biāo)簽
CCLabelTTF* scoreLabel;
// 分?jǐn)?shù)
int scoreValue;
找到onEnter方法,在初始化×××和敵機(jī)數(shù)組之后初始化分?jǐn)?shù)值標(biāo)簽和分?jǐn)?shù),實(shí)現(xiàn)代碼如下。
// 初始化分?jǐn)?shù)標(biāo)簽
scoreLabel = [CCLabelTTF labelWithString:@"00" fontName:@"Arial" fontSize:20];
scoreLabel.position = ccp(60, screenHeight-20);
[self addChild:scoreLabel];
// 初始化分?jǐn)?shù)值
scoreValue = 0;
修改檢查碰撞方法collisionDetection:,當(dāng)敵機(jī)生命值小于0時(shí),增加計(jì)分算法,小飛機(jī)每個(gè)計(jì)分100,小飛碟每個(gè)計(jì)分500,實(shí)現(xiàn)代碼如下(程序清單同上)。
if (enemyPlaneSprite.lifeValue <= 0) {
// 刪除敵機(jī)精靈
[enemyPlaneArray removeObject:enemyPlaneSprite];
[batchNode removeChild:enemyPlaneSprite cleanup:YES];
// 播放爆炸動(dòng)畫
[self bombAnimate:@"blast" :enemyPlaneSprite.position ];
// 播放爆炸音效
[[SimpleAudioEngine sharedEngine] playEffect:@"b0.mp3"];
if ([enemyPlaneSprite.name isEqualToString:@"e1"])
scoreValue += 500;
else
scoreValue += 100;
}
在私有分類中添加一個(gè)根據(jù)分?jǐn)?shù)值實(shí)時(shí)更新相應(yīng)的Label的方法,實(shí)現(xiàn)代碼如下(程序清單同上)。
-(void) updateHUD:(ccTime)delta;
updateHUD:方法實(shí)時(shí)更新生命值和分?jǐn)?shù)值,地圖、分?jǐn)?shù)、血條、時(shí)間進(jìn)度條和技能條等都是HUD(Head-UpDisplay)。實(shí)現(xiàn)代碼如下(程序清單同上)。
-(void) updateHUD:(ccTime)delta{
[scoreLabel setString:[NSString stringWithFormat:@"%i",scoreValue]];
}
修改update方法,實(shí)現(xiàn)代碼如下(程序清單同上)。
-(void) update:(ccTime)delta{
count++;
[self updateBackground:delta];
[self updateEnemySprite:delta];
[self removeEnemySprite:delta];
[self updateShooting:delta];
[self removeBulletSprite:delta];
self collisionDetection:delta];
[self updateHUD:delta];
}
再次編譯并運(yùn)行游戲,控制玩家飛機(jī)發(fā)射×××,×××擊中敵機(jī),左上角的分?jǐn)?shù)標(biāo)簽不斷統(tǒng)計(jì)玩家得分。模擬器顯示效果如圖13.65所示。
圖13.65統(tǒng)計(jì)積分效果
到現(xiàn)在為止,一個(gè)基本的打飛機(jī)游戲已經(jīng)快完成了,讓我們?cè)俳o它添加一個(gè)大Boss,增加一點(diǎn)游戲的趣味性和難度吧!增加大Boss的具體步驟如下。
打開HelloWorldLayer.m文件,添加變量,實(shí)現(xiàn)代碼如下(程序清單同上)。
FKSprite* bossSprite;
// Boss×××精靈數(shù)組
CCArray* bossBulletArray;
// 是否啟動(dòng)Boss和Boss是否發(fā)射×××
BOOL isStartBoss,isMoveBoss,isShootingBoss,isTemp;
在私有分類中添加3個(gè)方法,實(shí)現(xiàn)代碼如下(程序清單同上)。
// Boss出動(dòng)
-(void) startBossSprite:(ccTime)delta;
// Boss在屏幕上不規(guī)則移動(dòng)
-(void) moveBossSprite:(ccTime)delta;
// Boss更新×××
-(void) updateBossShooting:(ccTime)delta;
startBossSprite:方法用于啟動(dòng)Boss。實(shí)現(xiàn)代碼如下(程序清單同上)。
-(void) startBossSprite:(ccTime)delta{
if(isStartBoss && !isMoveBoss && !isTemp ){
isTemp = YES;
CCSpriteBatchNode *batchNode = (CCSpriteBatchNode*)[self getChildByTag: kTagBatchNode];
FKSprite* enemyPlaneSprite;
// 刪除所有敵機(jī)
CCARRAY_FOREACH(enemyPlaneArray, enemyPlaneSprite){
[batchNode removeChild:enemyPlaneSprite cleanup:YES];
}
[enemyPlaneArray removeAllObjects];
// Boss出動(dòng)
bossSprite= [FKSprite spriteWithSpriteFrameName:@"e-10.png"];
bossSprite.position=ccp(screenWidth/2, screenHeight+bossSprite.contentSize.height);
bossSprite.name = @"boss";
bossSprite.lifeValue = 600;
// 創(chuàng)建一個(gè)進(jìn)度條精靈
CCSprite* barSprite = [CCSprite spriteWithFile:@"planeHP.png"];
// 初始化一個(gè)Boss血條對(duì)象
bossSprite.enemyPlaneHP = [CCProgressTimer progressWithSprite:barSprite];
// setPercentage:0.0f,表示并未加載任何資源,表現(xiàn)在畫面上就是什么也看不見
[bossSprite.enemyPlaneHP setPercentage:0.0f];
// 由于圖片大小關(guān)系,把scale設(shè)置成0.5,即縮小一半
bossSprite.enemyPlaneHP.scale = 0.25;
bossSprite.enemyPlaneHP.midpoint = ccp(0,0.5);
bossSprite.enemyPlaneHP.barChangeRate = ccp(1, 0);
bossSprite.enemyPlaneHP.type = kCCProgressTimerTypeBar;
bossSprite.enemyPlaneHP.percentage = 100;
[bossSprite.enemyPlaneHP setPosition:ccp(screenWidth/2, screenHeight/2)];
bossSprite.enemyPlaneHP.visible = NO;
[self addChild:bossSprite.enemyPlaneHP];
// 血條更新量,100/10=10
bossSprite.HPInterval = 100.0 / (float)bossSprite.lifeValue;
// 將Boss精靈添加到敵機(jī)數(shù)組
[enemyPlaneArray addObject:bossSprite];
[batchNode addChild:bossSprite z:4];
// Boss移動(dòng)到屏幕上方
id moveTo = [CCMoveTo actionWithDuration:2
position:ccp(screenWidth/2, screenHeight-bossSprite.contentSize.height-20)];
id action = [CCSequence actions:moveTo,[CCCallBlock actionWithBlock:^(){
isMoveBoss = YES;
}], nil] ;
[bossSprite runAction:action];
// 初始化Boss×××數(shù)組
bossBulletArray = [[CCArray alloc] init];
}
}
startBossSprite:方法首先判斷isStartBoss是否為“YES”(默認(rèn)設(shè)置為“NO”,當(dāng)玩家達(dá)到10000分時(shí)會(huì)將該值改為“YES”,則Boss啟動(dòng)),如果是,則先獲取精靈表單,循環(huán)遍歷敵機(jī)數(shù)組,從精靈表單中刪除敵機(jī),再?gòu)臄硻C(jī)數(shù)組中刪除敵機(jī)(如果玩家是高手,希望玩到高難度的打飛機(jī)游戲,則可以不執(zhí)行這段代碼,游戲就會(huì)變成Boss和大量的小敵機(jī)輪番轟炸玩家)。接下來,創(chuàng)建一個(gè)Boss精靈,設(shè)置名稱為“Boss”,生命值為600,為Boss創(chuàng)建一個(gè)血條,并計(jì)算血條比率。然后將Boss添加到敵機(jī)數(shù)組和精靈表單中。最后,執(zhí)行一個(gè)moveBy動(dòng)作,實(shí)際效果是Boss緩緩移動(dòng)到屏幕上方,再將isMoveBoss設(shè)置為“YES”(Boss開始不規(guī)則動(dòng)作)。記得初始化Boss×××數(shù)組。
moveBossSprite:方法用于Boss啟動(dòng)后在屏幕上方做不規(guī)則運(yùn)動(dòng)。實(shí)現(xiàn)代碼如下(程序清單同上)。
-(void) moveBossSprite:(ccTime)delta{
if(isMoveBoss && !isShootingBoss){
isShootingBoss = YES;
// 不停地在屏幕上方左右移動(dòng)
id moveToLift = [CCMoveTo actionWithDuration:3
position:ccp(screenWidth-bossSprite.contentSize.width/2,
screenHeight-bossSprite.contentSize.height-20)];
id moveRight = [CCMoveTo actionWithDuration:3
position:ccp(0+bossSprite.contentSize.width/2,
screenHeight-bossSprite.contentSize.height-20)];
id delay = [CCDelayTime actionWithDuration:2];
id sequence = [CCSequence actions:delay,moveToLift,moveRight, nil];
// 注意:CCSequence中不能包含這個(gè)反復(fù)的動(dòng)作。
id repeat = [CCRepeatForever actionWithAction:sequence];
[bossSprite runAction:repeat];
}
}
moveBossSprite:方法首先判斷isMoveBoss是否為“YES”,如果是,則說明Boss精靈已經(jīng)啟動(dòng),開始做不規(guī)則運(yùn)動(dòng),并且設(shè)置isShootingBoss = YES,表示Boss可以發(fā)射×××***玩家精靈。
updateBossShooting:方法用于Boss開始發(fā)射×××。實(shí)現(xiàn)代碼如下(程序清單同上)。
-(void) updateBossShooting:(ccTime)delta{
if (isShootingBoss) {
// Boss精靈坐標(biāo)
CGPoint pos = bossSprite.position;
// Boss血條顯示坐標(biāo)位置
bossSprite.enemyPlaneHP.position = ccp(pos.x, pos.y+55);
if (!bossSprite.enemyPlaneHP.visible) {
bossSprite.enemyPlaneHP.visible = YES;
}
// 獲得精靈表單
CCSpriteBatchNode *batchNode = (CCSpriteBatchNode*)[self getChildByTag:kTagBatchNode];
if(count % 80 == 0)
{
// 創(chuàng)建代表×××的精靈
CCSprite* bossBulletSprite = [CCSprite spriteWithSpriteFrameName:@"bullet1.png"];
// 設(shè)置×××坐標(biāo)
CGPoint bulletPos = ccp(pos.x, pos.y - bossSprite.contentSize.height/2);
bossBulletSprite.position = bulletPos;
// ×××精靈可見
bossBulletSprite.visible = YES;
// ×××移動(dòng)時(shí)間為0.5秒,移動(dòng)距離為屏幕高度-×××的y軸
id moveBy=[CCMoveBy actionWithDuration:2.0f position:ccp(0,-screenHeight-bulletPos.y)];
[bossBulletSprite runAction:moveBy];
// 添加到Boss×××數(shù)組中
[bossBulletArray addObject:bossBulletSprite];
// 將×××精靈添加到精靈表單中
[batchNode addChild:bossBulletSprite z:4];
}
}
}
updateBossShooting:首先判斷isShootingBoss是否為“YES”,如果是,則設(shè)置Boss血條的坐標(biāo)位置,并顯示Boss血條。當(dāng)count % 80 == 0時(shí),發(fā)射Boss×××,同時(shí)將Boss×××添加到Boss×××數(shù)組和精靈表單中。
修改collisionDetection:方法,重新判斷玩家得分,并在爆炸效果之后添加代碼,當(dāng)玩家積分達(dá)到10000時(shí),啟動(dòng)Boss。實(shí)現(xiàn)代碼如下(程序清單同上)。
if ([enemyPlaneSprite.name isEqualToString:@"boss"]) {
// 播放爆炸動(dòng)畫
[self bombAnimate:@"bomb" :enemyPlaneSprite.position ];
// 播放爆炸音效
[[SimpleAudioEngine sharedEngine] playEffect:@"b1.mp3"];
scoreValue += 5000;
// 游戲勝利
[self gameOver:@"游戲勝利!"];
}else{
// 播放爆炸動(dòng)畫
[self bombAnimate:@"blast" :enemyPlaneSprite.position ];
// 播放爆炸音效
[[SimpleAudioEngine sharedEngine] playEffect:@"b0.mp3"];
if ([enemyPlaneSprite.name isEqualToString:@"e1"])
scoreValue += 500;
else
scoreValue += 100;
}
// 10000分大Boss出動(dòng)
if (scoreValue >= 10000) {
isStartBoss = YES;
break;
}
}
循環(huán)遍歷完×××數(shù)組之后,再添加遍歷Boss×××數(shù)組的代碼,判斷Boss×××是否擊中玩家飛機(jī)。實(shí)現(xiàn)代碼如下(程序清單同上)。
// 判斷Boss的×××和玩家飛機(jī)的碰撞
if (isShootingBoss) {
CCSprite* bossBulletSprite;
CCARRAY_FOREACH(bossBulletArray, bossBulletSprite){
if(CGRectIntersectsRect(planeSprite.boundingBox,bossBulletSprite.boundingBox)){
[planeSprite stopAllActions];
// 刪除玩家精靈
[batchNode removeChild:planeSprite cleanup:YES];
// 爆炸聲音
[[SimpleAudioEngine sharedEngine] playEffect:@"b0.mp3"];
// 播放爆炸動(dòng)畫
[self bombAnimate:@"blast" :planeSprite.position ];
[self gameOver:@"游戲結(jié)束!"];
}
}
}
修改updateEnemySprite:方法,判斷是否更新敵機(jī)時(shí)增加!isStartBoss進(jìn)行判斷,意味著Boss出動(dòng)后不再更新敵機(jī)。實(shí)現(xiàn)代碼如下(程序清單同上)。
if (count % 30 == 0 && !isStartBoss)
if (count % 200 == 0 && !isStartBoss)
修改update方法,實(shí)現(xiàn)代碼如下(程序清單同上)。
-(void) update:(ccTime)delta{
count++;
[self updateBackground:delta];
[self updateEnemySprite:delta];
[self removeEnemySprite:delta];
[self updateShooting:delta];
[self removeBulletSprite:delta];
self collisionDetection:delta];
[self updateHUD:delta];
[self startBossSprite:delta];
[self moveBossSprite:delta];
[self updateBossShooting:delta];
}
再次編譯并運(yùn)行游戲,當(dāng)玩家得分達(dá)到10000分時(shí),Boss出動(dòng)。模擬器顯示效果如圖13.66所示。
當(dāng)玩家控制飛機(jī)***大Boss時(shí),Boss的血條會(huì)隨著生命值的減少而縮短。當(dāng)Boss生命值為0時(shí),播放爆炸效果,提示游戲勝利,模擬器顯示效果如圖13.67所示。
到此為止,這個(gè)打飛機(jī)游戲基本已經(jīng)開發(fā)完成,包括背景滾動(dòng)、飛機(jī)飛行動(dòng)畫、背景音樂、音效、大量敵機(jī)***、玩家射擊、Boss大招、玩家積分統(tǒng)計(jì)和游戲設(shè)置等功能。記得有位軟件大師曾經(jīng)說過,游戲沒有真正意義上的完結(jié),因?yàn)殚_發(fā)者總是可以不斷地完善它,賦予游戲更多的新元素和新玩法。比如,我們可以讓敵機(jī)俯沖時(shí)發(fā)射炮彈、敵機(jī)做不規(guī)則運(yùn)動(dòng)、Boss出動(dòng)時(shí)伴隨大量小飛機(jī)、玩家飛機(jī)增加大×××功能、每過一關(guān)玩家飛機(jī)增加一架等。這個(gè)游戲我們暫時(shí)就介紹到這里,本節(jié)我們的目的是學(xué)習(xí)使用cocos2d制作一個(gè)簡(jiǎn)單的游戲。游戲雖然簡(jiǎn)單,但是包括的知識(shí)點(diǎn)很多,希望大家好好掌握,將來制作出更加有趣和完美的游戲。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。