如今,咱们来给玩家加入游戏积分统计功能。步骤以下。算法
打开HelloWorldLayer.m文件,添加变量,实现代码以下(程序清单同上)。数组
// 分数值标签ide
CCLabelTTF* scoreLabel;学习
// 分数动画
int scoreValue;spa
找到onEnter方法,在初始化×××和敌机数组以后初始化分数值标签和分数,实现代码以下。.net
// 初始化分数标签orm
scoreLabel = [CCLabelTTF labelWithString:@"00" fontName:@"Arial" fontSize:20];对象
scoreLabel.position = ccp(60, screenHeight-20);游戏
[self addChild:scoreLabel];
// 初始化分数值
scoreValue = 0;
修改检查碰撞方法collisionDetection:,当敌机生命值小于0时,增长计分算法,小飞机每一个计分100,小飞碟每一个计分500,实现代码以下(程序清单同上)。
if (enemyPlaneSprite.lifeValue <= 0) {
// 删除敌机精灵
[enemyPlaneArray removeObject:enemyPlaneSprite];
[batchNode removeChild:enemyPlaneSprite cleanup:YES];
// 播放爆炸动画
[self bombAnimate:@"blast" :enemyPlaneSprite.position ];
// 播放爆炸音效
[[SimpleAudioEngine sharedEngine] playEffect:@"b0.mp3"];
if ([enemyPlaneSprite.name isEqualToString:@"e1"])
scoreValue += 500;
else
scoreValue += 100;
}
在私有分类中添加一个根据分数值实时更新相应的Label的方法,实现代码以下(程序清单同上)。
-(void) updateHUD:(ccTime)delta;
updateHUD:方法实时更新生命值和分数值,地图、分数、血条、时间进度条和技能条等都是HUD(Head-UpDisplay)。实现代码以下(程序清单同上)。
-(void) updateHUD:(ccTime)delta{
[scoreLabel setString:[NSString stringWithFormat:@"%i",scoreValue]];
}
修改update方法,实现代码以下(程序清单同上)。
-(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];
}
再次编译并运行游戏,控制玩家飞机发射×××,×××击中敌机,左上角的分数标签不断统计玩家得分。模拟器显示效果如图13.65所示。
图13.65统计积分效果
到如今为止,一个基本的打飞机游戏已经快完成了,让咱们再给它添加一个大Boss,增长一点游戏的趣味性和难度吧!增长大Boss的具体步骤以下。
打开HelloWorldLayer.m文件,添加变量,实现代码以下(程序清单同上)。
FKSprite* bossSprite;
// Boss×××精灵数组
CCArray* bossBulletArray;
// 是否启动Boss和Boss是否发射×××
BOOL isStartBoss,isMoveBoss,isShootingBoss,isTemp;
在私有分类中添加3个方法,实现代码以下(程序清单同上)。
// Boss出动
-(void) startBossSprite:(ccTime)delta;
// Boss在屏幕上不规则移动
-(void) moveBossSprite:(ccTime)delta;
// Boss更新×××
-(void) updateBossShooting:(ccTime)delta;
startBossSprite:方法用于启动Boss。实现代码以下(程序清单同上)。
-(void) startBossSprite:(ccTime)delta{
if(isStartBoss && !isMoveBoss && !isTemp ){
isTemp = YES;
CCSpriteBatchNode *batchNode = (CCSpriteBatchNode*)[self getChildByTag: kTagBatchNode];
FKSprite* enemyPlaneSprite;
// 删除全部敌机
CCARRAY_FOREACH(enemyPlaneArray, enemyPlaneSprite){
[batchNode removeChild:enemyPlaneSprite cleanup:YES];
}
[enemyPlaneArray removeAllObjects];
// Boss出动
bossSprite= [FKSprite spriteWithSpriteFrameName:@"e-10.png"];
bossSprite.position=ccp(screenWidth/2, screenHeight+bossSprite.contentSize.height);
bossSprite.name = @"boss";
bossSprite.lifeValue = 600;
// 建立一个进度条精灵
CCSprite* barSprite = [CCSprite spriteWithFile:@"planeHP.png"];
// 初始化一个Boss血条对象
bossSprite.enemyPlaneHP = [CCProgressTimer progressWithSprite:barSprite];
// setPercentage:0.0f,表示并未加载任何资源,表如今画面上就是什么也看不见
[bossSprite.enemyPlaneHP setPercentage:0.0f];
// 因为图片大小关系,把scale设置成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精灵添加到敌机数组
[enemyPlaneArray addObject:bossSprite];
[batchNode addChild:bossSprite z:4];
// Boss移动到屏幕上方
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×××数组
bossBulletArray = [[CCArray alloc] init];
}
}
startBossSprite:方法首先判断isStartBoss是否为“YES”(默认设置为“NO”,当玩家达到10000分时会将该值改成“YES”,则Boss启动),若是是,则先获取精灵表单,循环遍历敌机数组,从精灵表单中删除敌机,再从敌机数组中删除敌机(若是玩家是高手,但愿玩到高难度的打飞机游戏,则能够不执行这段代码,游戏就会变成Boss和大量的小敌机轮番轰炸玩家)。接下来,建立一个Boss精灵,设置名称为“Boss”,生命值为600,为Boss建立一个血条,并计算血条比率。而后将Boss添加到敌机数组和精灵表单中。最后,执行一个moveBy动做,实际效果是Boss缓缓移动到屏幕上方,再将isMoveBoss设置为“YES”(Boss开始不规则动做)。记得初始化Boss×××数组。
moveBossSprite:方法用于Boss启动后在屏幕上方作不规则运动。实现代码以下(程序清单同上)。
-(void) moveBossSprite:(ccTime)delta{
if(isMoveBoss && !isShootingBoss){
isShootingBoss = YES;
// 不停地在屏幕上方左右移动
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中不能包含这个反复的动做。
id repeat = [CCRepeatForever actionWithAction:sequence];
[bossSprite runAction:repeat];
}
}
moveBossSprite:方法首先判断isMoveBoss是否为“YES”,若是是,则说明Boss精灵已经启动,开始作不规则运动,而且设置isShootingBoss = YES,表示Boss能够发射×××***玩家精灵。
updateBossShooting:方法用于Boss开始发射×××。实现代码以下(程序清单同上)。
-(void) updateBossShooting:(ccTime)delta{
if (isShootingBoss) {
// Boss精灵坐标
CGPoint pos = bossSprite.position;
// Boss血条显示坐标位置
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)
{
// 建立表明×××的精灵
CCSprite* bossBulletSprite = [CCSprite spriteWithSpriteFrameName:@"bullet1.png"];
// 设置×××坐标
CGPoint bulletPos = ccp(pos.x, pos.y - bossSprite.contentSize.height/2);
bossBulletSprite.position = bulletPos;
// ×××精灵可见
bossBulletSprite.visible = YES;
// ×××移动时间为0.5秒,移动距离为屏幕高度-×××的y轴
id moveBy=[CCMoveBy actionWithDuration:2.0f position:ccp(0,-screenHeight-bulletPos.y)];
[bossBulletSprite runAction:moveBy];
// 添加到Boss×××数组中
[bossBulletArray addObject:bossBulletSprite];
// 将×××精灵添加到精灵表单中
[batchNode addChild:bossBulletSprite z:4];
}
}
}
updateBossShooting:首先判断isShootingBoss是否为“YES”,若是是,则设置Boss血条的坐标位置,并显示Boss血条。当count % 80 == 0时,发射Boss×××,同时将Boss×××添加到Boss×××数组和精灵表单中。
修改collisionDetection:方法,从新判断玩家得分,并在爆炸效果以后添加代码,当玩家积分达到10000时,启动Boss。实现代码以下(程序清单同上)。
if ([enemyPlaneSprite.name isEqualToString:@"boss"]) {
// 播放爆炸动画
[self bombAnimate:@"bomb" :enemyPlaneSprite.position ];
// 播放爆炸音效
[[SimpleAudioEngine sharedEngine] playEffect:@"b1.mp3"];
scoreValue += 5000;
// 游戏胜利
[self gameOver:@"游戏胜利!"];
}else{
// 播放爆炸动画
[self bombAnimate:@"blast" :enemyPlaneSprite.position ];
// 播放爆炸音效
[[SimpleAudioEngine sharedEngine] playEffect:@"b0.mp3"];
if ([enemyPlaneSprite.name isEqualToString:@"e1"])
scoreValue += 500;
else
scoreValue += 100;
}
// 10000分大Boss出动
if (scoreValue >= 10000) {
isStartBoss = YES;
break;
}
}
循环遍历完×××数组以后,再添加遍历Boss×××数组的代码,判断Boss×××是否击中玩家飞机。实现代码以下(程序清单同上)。
// 判断Boss的×××和玩家飞机的碰撞
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"];
// 播放爆炸动画
[self bombAnimate:@"blast" :planeSprite.position ];
[self gameOver:@"游戏结束!"];
}
}
}
修改updateEnemySprite:方法,判断是否更新敌机时增长!isStartBoss进行判断,意味着Boss出动后再也不更新敌机。实现代码以下(程序清单同上)。
if (count % 30 == 0 && !isStartBoss)
if (count % 200 == 0 && !isStartBoss)
修改update方法,实现代码以下(程序清单同上)。
-(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];
}
再次编译并运行游戏,当玩家得分达到10000分时,Boss出动。模拟器显示效果如图13.66所示。
当玩家控制飞机***大Boss时,Boss的血条会随着生命值的减小而缩短。当Boss生命值为0时,播放爆炸效果,提示游戏胜利,模拟器显示效果如图13.67所示。
到此为止,这个打飞机游戏基本已经开发完成,包括背景滚动、飞机飞行动画、背景音乐、音效、大量敌机***、玩家射击、Boss大招、玩家积分统计和游戏设置等功能。记得有位软件大师曾经说过,游戏没有真正意义上的完结,由于开发者老是能够不断地完善它,赋予游戏更多的新元素和新玩法。好比,咱们可让敌机俯冲时发射炮弹、敌机作不规则运动、Boss出动时伴随大量小飞机、玩家飞机增长大×××功能、每过一关玩家飞机增长一架等。这个游戏咱们暂时就介绍到这里,本节咱们的目的是学习使用cocos2d制做一个简单的游戏。游戏虽然简单,可是包括的知识点不少,但愿你们好好掌握,未来制做出更加有趣和完美的游戏。