如何设计开发iPhone塔防游戏9-劳命伤财

欢迎继续回到iPhone塔防游戏系列教程。相信玩过塔防游戏的朋友都明白,炮塔不是白给的,是要花钱的,而基地不是无敌的,再牢固的基地也扛不住怪兽一波又一波的攻击。防御神马的是要劳命伤财的。

 

如何设计开发iPhone塔防游戏9-劳命伤财



 

在这部分的教程中,我们将在游戏中添加“金币”的元素,玩家只有花钱才能买炮塔,而金币数量会随着时间的流逝缓慢增长。此外,我们还添加“生命值”,或者血条,毕竟游戏不可能无休无止。



如何设计开发iPhone塔防游戏9-劳命伤财 

 

因此,本部分教程将专门讲述如何实现动态标签和图片,以及背后的游戏机制,这一切都会在GameHUD中实现。

在学习之前,需要先下载上一部分完成后的源代码:

http://www.iphonegametutorials.com/usr/uploads/2012/01/TowerDefensePart6.zip

 

本部分完成后的源代码:

http://www.iphonegametutorials.com/usr/uploads/2012/01/TowerDefensePart7.zip

 

为了在GameHUD类中添加标签,首先要做的是决定要显示的元素,比如金币数量,血条,波次和每种炮塔的价格。

在GameHUD.m中找到init方法,然后找到以下这行代码:

[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];

在这行代码的下面添加以下代码:

// Set up Resources and Resource label
resources = 100;
self->resourceLabel = [CCLabelTTF labelWithString:@"Money $100" dimensions:CGSizeMake(150, 25) alignment:UITextAlignmentRight fontName:@"Marker Felt" fontSize:20];
resourceLabel.position = ccp(30, (winSize.height -15));

resourceLabel.color = ccc3(255,80,20);

[self addChild:resourceLabel z:1];
// Set up BaseHplabel
CCLabelTTF *baseHpLabel = [CCLabelTTF labelWithString:@"Base Health" dimensions:CGSizeMake(150, 25) alignment:UITextAlignmentRight fontName:@"Marker Felt" fontSize:20];
baseHpLabel.position = ccp((winSize.width -185), (winSize.height -15));
baseHpLabel.color = ccc3(255,80,20);
[self addChild:baseHpLabel z:1];
// Set up wavecount label
waveCount = 1;
self->waveCountLabel = [CCLabelTTF labelWithString:@"Wave 1" dimensions:CGSizeMake(150, 25) alignment:UITextAlignmentRight fontName:@"Marker Felt" fontSize:20];
waveCountLabel.position = ccp(((winSize.width/2) -80), (winSize.height -15));
waveCountLabel.color = ccc3(100,0,100);
[self addChild:waveCountLabel z:1];

在上面的代码中,我们通过前三段代码分别设置了资源(金币),基础血条和波次。而且代码都比较简单,接下来就比较有趣了。

紧接着上面的代码添加以下代码:

//Set up health Bar
baseHpPercentage = 100;
self->healthBar = [CCProgressTimer progressWithFile:@"health_bar_green.png"];
self->healthBar.type = kCCProgressTimerTypeHorizontalBarLR;
self->healthBar.percentage = baseHpPercentage;
[self->healthBar setScale:0.5];
self->healthBar.position = ccp(winSize.width -55, winSize.height -15);
[self addChild:healthBar z:1];

在上面的代码中,我们使用”CCProgressTimer”来显示健康条图片。之所以使用CCProgressTimer,是因为它可以按百分比来显示某个图片。这里选择的类型是kCCProgressTimerTypeHori

zontalBarLR,因为健康条图片是一个横条,而我们希望从右侧(100%)向左侧移动(0%),紧接着我们将初始值设置为100,这样就是满血了。

接下来,就是给每种炮塔“明码标价”了。

在init方法中找到以下代码:

NSArray *images = [NSArray arrayWithObjects:@"MachineGunTurret.png", @"FreezeTurret.png", @"MachineGunTurret.png", @"MachineGunTurret.png", nil];
        for(int i = 0; i < images.count; ++i) {
            NSString *image = [images objectAtIndex:i];
            CCSprite *sprite = [CCSprite spriteWithFile:image];
            float offsetFraction = ((float)(i+1))/(images.count+1);
            sprite.position = ccp(winSize.width*offsetFraction, 35);
            sprite.tag = i+1;
            printf("tag %i", sprite.tag);
            [self addChild:sprite];
            [movableSprites addObject:sprite];
        }

将其替换为下面的代码:

for(int i = 0; i < images.count; ++i) {

    NSString *image = [images objectAtIndex:i];

    CCSprite *sprite = [CCSprite spriteWithFile:image];

    float offsetFraction = ((float)(i+1))/(images.count+1);

    sprite.position = ccp(winSize.width*offsetFraction, 35);

    sprite.tag = i+1; printf("tag %i", sprite.tag);

    [self addChild:sprite];

    [movableSprites addObject:sprite];

    //Set up and place towerCost labels

    CCLabelTTF *towerCost = [CCLabelTTF labelWithString:@"$" fontName:@"Marker Felt" fontSize:10];

    towerCost.position = ccp(winSize.width*offsetFraction, 15);

    towerCost.color = ccc3(0, 0, 0);

    [self addChild:towerCost z:1];

    //Set cost values

    switch (i) {

          case 0:
                [towerCost setString:[NSString stringWithFormat:@"$ 25]];
          break;

          case 1:
                [towerCost setString:[NSString stringWithFormat:@"$ 35”]];
          break;

          case 2:
                [towerCost setString:[NSString stringWithFormat:@"$ 25]];
          break;

          case 3:
                [towerCost setString:[NSString stringWithFormat:@"$ 25]];
          break;

          default:
          break;
    }

}

在上面的代码中,只是在每种炮塔图片的下面放置了一个价格标签,每种炮塔一个单独的价格。

还有一件事情要做,就是设置标签中的参数。在GameHUD.h添加几个实例变量的声明如下:

      CCLabelTTF *resourceLabel;
      CCLabelTTF *waveCountLabel;
      float baseHpPercentage;
      CCProgressTimer *healthBar;
}
@property (nonatomic, assign) int resources;
@property (nonatomic, assign) float baseHpPercentage;

然后在GameHUD.m中添加以下代码:

-(void) updateResources:(int)amount {
      resources += amount;
      [self->resourceLabel setString:[NSString stringWithFormat: @"Money $ %i",resources]];
}

-(void) updateResourcesNom {
      resources += 1;
      [self->resourceLabel setString:[NSString stringWithFormat: @"Money $ %i",resources]];
}

接下来需要添加标签的逻辑机制,从而让它们可以向玩家提供有用的游戏信息。

在Xcode中切换到GameHUD.m,并添加以下方法(记得在头文件中添加声明):

-(void) updateResources:(int)amount {
      resources += amount;
      [self->resourceLabel setString:[NSString stringWithFormat: @"Money $ %i",resources]];
}

-(void) updateResourcesNom {
      resources += 1;
      [self->resourceLabel setString:[NSString stringWithFormat: @"Money $ %i",resources]];
}

这样一来,我们就可以使用该方法来更新金币数量,并在屏幕上显示新的数字信息。

接下来切换到TutorialScene.m,找到addTower方法。使用以下代码替换switch语句:

switch (towerTag) {

    case 1:
          if (gameHUD.resources >= 25) {

                target = [MachineGunTower tower];

                [gameHUD updateResources:-25];

          } else return;
    break;

    case 2:
          if (gameHUD.resources >= 35) {
                target = [FreezeTower tower];
                [gameHUD updateResources:-35];
           } else return;
    break;

    case 3:
          if (gameHUD.resources >= 25) {
                target = [MachineGunTower tower];
                [gameHUD updateResources:-25];
           } else return;
    break;

    case 4:
          if (gameHUD.resources >= 25) {

                target = [MachineGunTower tower];

                [gameHUD updateResources:-25];

          } else return;
    break;

    default:
    break;
}

以上代码的作用是判断是否有足够的金币购买某种炮塔。如果是,则创建所选择的炮塔,并从金币中扣除所需的成本。

 

接下来需要增加金币资源。玩家有两种方式来获取金币:

1.随着时间的流逝金币会缓慢增长

2.通过秒杀怪物来获取金币。

这两种方法我们都需要来实现,首先实现第二种。

切换到TutorialScene.m,找到update方法,把creep.hp <=0的判断语句修改如下;

if(creep.hp

接下来实现第一种。在TutorialScene.m中找到init方法,并在GameHUD方法的声明后添加以下代码:

[gameHUD schedule:@selector(updateResourcesNom) interval: 2.0];

这样,每2秒钟玩家的金币会自动增加1。

编译运行游戏,我们的金币系统就OK了。

接下来需要在敌人抵挡路径终点时更改基地的血条,在GameHUD.m(及头文件)中添加以下方法:

-(void) updateBaseHp:(int)amount {

    baseHpPercentage += amount;
    if (baseHpPercentage healthBar setSprite:[CCSprite spriteWithFile:@"health_bar_red.png"]];

          [self->healthBar setScale:0.5];

    }
    if (baseHpPercentage healthBar setPercentage:baseHpPercentage];
}

以上方法的作用是使用指定数量来更新baseHpPercentage。如果该值小于25%,就将图片更好成红色的血条。而如果该值小于等于0,就说明游戏结束了(下一部分教程中会实现更多内容)。

 

在Xcode中切换到Creep.m,找到getNextWaypoint方法,并添加以下代码:

gameHUD = [GameHUD sharedHUD];

if (gameHUD.baseHpPercentage > 0) {
      [gameHUD updateBaseHp:-10];
}

此时,每当有敌人抵挡终点时,血条生命值会降低10点。

 

当然,最后还需要更新波次信息。

在GameHUD.m(及头文件)中添加以下方法:

-(void) updateWaveCount {
      waveCount++;
      [self->waveCountLabel setString:[NSString stringWithFormat: @"Wave %i",waveCount]];
}

然后切换到TutorialScene.m,找到update方法,在判断是否抵挡当前波次终点的if

语句中添加语句以调用updateWaveCount方法:

Wave *wave = [self getCurrentWave];

if ([m._targets count] ==0 && wave.redCreeps

ok,到此为止,我们已经成功添加了3个动态标签,并使用特定的逻辑进行更新。

 

后续将尽快补充剩下的内容。

 

原文在此:

http://www.iphonegametutorials.com/2012/01/24/how-to-build-a-tower-defense-game-for-the-iphone-part-7-money-and-health/

标签: cocos2d教程, 塔防游戏教程

?>