【游戏开发教程】保卫战,钓鱼岛是大宋的!如何从零开始制作一款iOS塔防游戏教程(四)

最后,使用以下内容替代update方法中的内容:
-(void)update:(ccTime)dt {
if (chosenEnemy){
//We make it turn to target the enemy chosen
CGPoint normalized = ccpNormalize(ccp(chosenEnemy.mySprite.position.x-mySprite.position.x,chosenEnemy.mySprite.position.y-mySprite.position.y));
mySprite.rotation = CC_RADIANS_TO_DEGREES(atan2(normalized.y,-normalized.x))+90;
if(![theGame circle:mySprite.position withRadius:attackRange collisionWithCircle:chosenEnemy.mySprite.position collisionCircleRadius:1])
{
[self lostSightOfEnemy];
}
} else {
for(Enemy * enemy in theGame.enemies)
{
if([theGame circle:mySprite.position withRadius:attackRange collisionWithCircle:enemy.mySprite.position collisionCircleRadius:1])
{
[self chosenEnemyForAttack:enemy];
break;
}
}
}
}

这下子可添加了不少代码。当然,在你添加代码的时候,还可以看到Xcode中不断发出各种警告。显然,有些工作做的不完美。
打开Enemy.h,并对代码做以下修正:
// Add instance variable
NSMutableArray *attackedBy;
// Add method definitions
-(void)getAttacked:(Tower *)attacker;
-(void)gotLostSight:(Tower *)attacker;
-(void)getDamaged:(int)damage;

对Enemy.m中 的代码做出以下修正:
// Add the following at the beginning of initWithTheGame: (within the "if" condition)
attackedBy = [[NSMutableArray alloc] initWithCapacity:5];
// Replace the contents of getRemoved method with the following:
-(void)getRemoved
{
for(Tower * attacker in attackedBy)
{
[attacker targetKilled];
}
[self.parent removeChild:self cleanup:YES];
[theGame.enemies removeObject:self];
//Notify the game that we killed an enemy so we can check if we can send another wave
[theGame enemyGotKilled];
}
// Add the following methods to the end of the file
-(void)getAttacked:(Tower *)attacker
{
[attackedBy addObject:attacker];
}
-(void)gotLostSight:(Tower *)attacker
{
[attackedBy removeObject:attacker];
}
-(void)getDamaged:(int)damage
{
currentHp -=damage;
if(currentHp < =0) { [self getRemoved]; }}

锦上添花

首先来显示钓龟岛基地的剩余血量吧,还有当钓龟岛基地被太阳军攻击的时候,会发生些什么。
打开HelloWorldLayer.h,添加以下三个实例变量:
int playerHp;
CCLabelBMFont *ui_hp_lbl;
BOOL gameEnded;

其中playerHp代表钓龟岛基地的血量,而CCLabelBMFont类型的变量则是一个标签,用于显示血量的数值。gameEnded是个布尔变量,用来表示游戏是否结束。
接下来添加以下方法定义:
-(void)getHpDamage;
-(void)doGameOver;

打开HelloWorldLayer.m,并做出以下代码修改:
// At the end of init, add the following lines of code:
// 7 - Player lives
playerHp = 5;
ui_hp_lbl = [CCLabelBMFont labelWithString:[NSString stringWithFormat:@"HP: %d",playerHp] fntFile:@"font_red_14.fnt"];
[self addChild:ui_hp_lbl z:10];
[ui_hp_lbl setPosition:ccp(35,wins.height-12)];
// Add the following methods to the end of the file
-(void)getHpDamage {
playerHp--;
[ui_hp_lbl setString:[NSString stringWithFormat:@"HP: %d",playerHp]];
if (playerHp < =0) { [self doGameOver]; }}-(void)doGameOver { if (!gameEnded) { gameEnded = YES; [[CCDirector sharedDirector] replaceScene:[CCTransitionRotoZoom transitionWithDuration:1 scene:[HelloWorldLayer scene]]]; }}

以上代码添加了一个方法,用于减少基地的血量,更新标签,并检查基地是否被爆头了。如果是,恭喜你,千古罪人的称号非你莫属了!
每当有太阳军抵达基地时,都会调用getHpDamage方法。你需要将其添加到Enemy.m的update:方法中,以检查当敌军已经走完所有路点后该发生点什么。
幸运的是,这个任务我们在之前的代码中已然完成。如此就可以踹口气了。
编译运行游戏,为了看看效果,管好你的手指,让太阳军顺利抵达基地试试看。忍住,一定要忍住!
【游戏开发教程】保卫战,钓鱼岛是大宋的!如何从零开始制作一款iOS塔防游戏教程(四)
此时,你会看到基地的血量不断减少,直到。。。游戏失败,钓龟岛失陷?!
好吧,接下来要限制下大宋的黄金储备(还需要限制吗?)
大多数的塔防游戏都会采取“零和”博弈策略。这样每个炮塔都需要花费一定的成本来购买,同时限制玩家的黄金储备。
打开HelloWorldLayer.h,并添加以下实例变量:
int playerGold;
CCLabelBMFont *ui_gold_lbl;

如同之前一样,这里添加的变量用于保存黄金储备,并使用标签来显示它。同时,添加一个新的方法定义:
-(void)awardGold:(int)gold;
现在,打开HelloWorldLayer.m,并对代码进行以下修改:
//Add the following method before init
-(void)awardGold:(int)gold {
playerGold += gold;
[ui_gold_lbl setString:[NSString stringWithFormat:@"GOLD: %d",playerGold]];
}
// Add at the end of init:
// 8 - Gold
playerGold = 1000;
ui_gold_lbl = [CCLabelBMFont labelWithString:[NSString stringWithFormat:@"GOLD: %d",playerGold] fntFile:@"font_red_14.fnt"];
[self addChild:ui_gold_lbl z:10];
[ui_gold_lbl setPosition:ccp(135,wins.height-12)];
[ui_gold_lbl setAnchorPoint:ccp(0,0.5)];
//Replace canBuyTower method with the following:
-(BOOL)canBuyTower {
if (playerGold - kTOWER_COST >=0)
return YES;
return NO;
}
// In ccTouchesBegan, add the following lines inside the if statement, where you commented that we would spend our gold later:
playerGold -= kTOWER_COST;
[ui_gold_lbl setString:[NSString stringWithFormat:@"GOLD: %d",playerGold]];

以上代码将会在玩家放置炮塔时检查是否有足够的黄金储备(神马?黄金都在大美丽坚那里?)如果是,就会放置炮塔,并从黄金储备中减少炮塔的成本。当然,在每次击溃某只太阳军的时候,也需要小小的奖励一些黄金吧。
在Enemy.m的getDamaged:方法中添加以下语句(在if条件从句中):
[theGame awardGold:200];
编译运行游戏,你会发现现在自己不能随心所欲的安放炮塔了(哎,黄金储备都存在瑞士银行和花在三母消费上了,我北洋舰队和附属炮台就这样沦为太阳军的炮灰?!)
幸运的是,杀灭太阳军会有一定的黄金奖励,这样还能多撑一会儿,待得小马哥拍马杀来救援。
【游戏开发教程】保卫战,钓鱼岛是大宋的!如何从零开始制作一款iOS塔防游戏教程(四)
好了,最后的最后,我们该加点激动人心的背景音乐和音效了。感谢Kevin MacLeod提供的背景音乐和使用cxfr制作的一些音效。
打开HelloWorldLayer.m,并对其中的代码做以下修正:
//At the top of the file:
#import "SimpleAudioEngine.h"
//At the beginning of init: (inside the "if" condition)
[[SimpleAudioEngine sharedEngine] playBackgroundMusic:@"8bitDungeonLevel.mp3" loop:YES];
//Inside ccTouchesBegan, before instantiating a new Tower object:
[[SimpleAudioEngine sharedEngine] playEffect:@"tower_place.wav"];
//At the beginning of getHpDamage
[[SimpleAudioEngine sharedEngine] playEffect:@"life_lose.wav"];

然后打开Enemy.m,并添加以下代码:
//At the top of the file:
#import "SimpleAudioEngine.h"
//At the beginning of getDamaged:
[[SimpleAudioEngine sharedEngine] playEffect:@"laser_shoot.wav"];

噢了!马上进入钓龟岛保卫战吧,小马哥在直升机上等你呢!
后续的后续
其实钓龟岛保卫战才刚刚开始,接下来还有很多可以完善的地方:
1.添加不同类型的太阳军,不同的速度,生命值,等等。
2.不同类型的炮塔,带有不同的攻击模式,当然价格也不一样。
3.不同的行进路线,不同的路点摆放模式。
4.不同的关卡。
最后的最后的最后,钓龟岛是大宋的,苍老师是全球的。

iOS塔防游戏开发教程全集

[dl href=’http://vdisk.weibo.com/s/cMmnZ’]点此下载教程代码[/dl]
[dl href=’http://pan.baidu.com/share/link?shareid=60919&uk=2502824232′]备用下载链接[/dl]