And we are back! Well, wasn’t that fun, we now have a multiple wave game, which we can program to increase in difficulty as we go along. However, there is still one thing nagging at me….. We still have no real control over how many creeps of each type are spawned in a wave, what if we wanted one wave to be completely made up of Red creeps, or Green Creeps. There are a few ways to do this, but I will explain the way that I did it.
Before we get into it, you’ll find things much easier to follow if you’ve already looked at Part5a of this tutorial series – So go there and come back… don’t worry we’ll wait.
Source code after the break…
Here is the source code: Tower Defense Part 5b. Once again, we’re using the Cocos2d framework which you can download here!
The first thing I did is to change the make up of the wave class. open wave.m and adjust the initWithCreep function to the following.
- (id) initWithCreep:(Creep *)creep SpawnRate:(float)spawnrate RedCreeps:(int)redcreeps GreenCreeps: (int)greencreeps
{
NSAssert(creep!=nil, @"Invalid creep for wave.");
if( (self = [self init]) )
{
_creepType = creep;
_spawnRate = spawnrate;
_redCreeps = redcreeps;
_greenCreeps = greencreeps;
}
return self;
}
Also add your new variables as such (and remove totalCreeps variables):
@synthesize redCreeps = _redCreeps; @synthesize greenCreeps = _greenCreeps;
Whilst in wave.H replace the entire file with the following:
#import "cocos2d.h"
#import "Creep.h"
@interface Wave : CCNode {
float _spawnRate;
int _redCreeps;
int _greenCreeps;
Creep * _creepType;
}
@property (nonatomic) float spawnRate;
@property (nonatomic) int redCreeps;
@property (nonatomic) int greenCreeps;
@property (nonatomic, retain) Creep *creepType;
- (id)initWithCreep:(Creep *)creep SpawnRate:(float)spawnrate RedCreeps:
(int)redcreeps GreenCreeps:(int)greencreeps;
@end
Hold up: All that we have done here is to change the make-up of the initWithCreep function (used in addWaves) to allow us to set the amount of red and green creeps separately, instead of just a totalCreeps value. Now go back into the main file (yep we have some errors, don’t worry!) and go to the function addWaves. Here we need to change our definitions to now include our RedCreeps and GreenCreeps variables (removing the TotalCreeps variable) until we have something which looks like this.
wave = [[Wave alloc] initWithCreep:[FastRedCreep creep] SpawnRate: 0.7 RedCreeps:5 GreenCreeps:15];
Still we have some errors, no problem, this is because we were checking the TotalCreeps in a few places, however with this variable now nonexistent we need to change these checks.
in addTarget change:
if (wave.totalCreeps < 0) {
return;
}
to
if (wave.redCreeps <= 0 && wave.greenCreeps <= 0 ) {
return;
}
Hold up: Simply this means that we won’t spawn any more creeps than are in the wave, and now we have split the creeps into green and red, we need to check that both are at 0. Next up you will see something like this
wave.totalCreeps--;
remove this piece of code. This was lowering the count of creeps left to spawn in this wave, however we will now do the same thing in a different way. Below this line you will see the next section of code:
Creep *target = nil;
if ((arc4random() % 2) == 0) {
target = [FastRedCreep creep];
} else {
target = [StrongGreenCreep creep];
}
In this section we set the creep type to spawn at random, evenly between Red and Green creeps. Replace this code with the following.
Creep *target = nil;
if ((arc4random() % 2) == 0) {
if (wave.redCreeps > 0) {
target = [FastRedCreep creep];
wave.redCreeps--;
}
else if (wave.greenCreeps >0){
target = [StrongGreenCreep creep];
wave.greenCreeps--;
// NSLog(@"no more red");
}
}
else {
if (wave.greenCreeps >0) {
target = [StrongGreenCreep creep];
wave.greenCreeps--;
}
else if (wave.redCreeps >0){
target = [FastRedCreep creep];
wave.redCreeps--;
//NSLog(@"no more green");
}
}
Hold up: In the new code above we are once again choosing a creep type (red/green) at random, however we then check to see if there are any creeps of that type left to spawn in this wave. This is a bit wordy so I’ll give a little example.
If the random generator chooses a Red Creep, and there is at least 1 Red Creep left to spawn in this wave, then a Red Creep is spawned and we decrease the number of Reds left to spawn in this wave. If there are not any Red Creeps left to spawn, then we Spawn a Green Creep and decrease the number of Green Creeps left to spawn in this wave. There I hope you understood that, should be fairly simple even if I can’t really vocalize it concisely.
Oh yes, and finally one last change. Go to the update section, where we earlier implemented a check for the end of the wave and replace the if statement with the following.
Wave *wave = [self getCurrentWave];
//int alivecount = [m._targets count];
if ([m._targets count] ==0 && wave.redCreeps <= 0 && wave.greenCreeps <= 0) {
printf("Get next wave\n");
// NSLog(@"Get next wave\n");//use for debugging
[self getNextWave];
}
Hold up: Should understand this by now as it is the same general update we have been doing from wave.totalCreeps (expired) to wave.redCreeps and Wave.greenCreeps.
Run, Test, Enjoy!
Remember, here is the source code for everything we have covered within this tutorial!
Tower Defense Part 5b Download.
Thanks for Reading, Hope this helps you all. Comment for help/explanations/pointing out any “doh” moments from me! Also Comment for suggestions for where you want this series to go next.
Yours,
Aiden Fry
iPhone Game Tutorials Contributor
Aiden Fry is a recent graduate, working to get into the games industry. He is a games programmer with a special interest in audio programming. Please check out his website aidenfry.tk to see some of his work.
sending...
So great to see these tutorials updated! Keep up the great work!
Great! Is there a part 1 -4 though?
yes, here is the link to part one.
http://www.iphonegametutorials.com/2011/04/11/cocos2d-game-tutorial-how-to-build-a-tower-defense-game-for-the-iphone-part-1-creep-waves/
Thanks for continuing with the tutorial!