[Editor's Note: One of our readers spoke up and decided to help us finish off this series of tutorials. Many thanks to Aiden Fry for stepping up to the plate!]
Welcome to the latest edition of the Tower Defense Tutorial. This is just the start of the long awaited renewal of the Tower Defense Tutorials. I (like many of you I am sure), have been following this particular tutorial series with interest, and was slightly downcast when I realized that part 4 was the last to be released. So hear me now, I vow to take up the challenge and by the end of these tutorials we will have a fully working game!
Yours, Aiden.
[Editor's Note: We are also very happy that Aiden has taken up the challenge as well!]
The Tower Defense Tutorial Part 5a – Multiple Waves!
A Quick Look Back:
I will assume that all of you have been following the tutorial series found here – part 1, part 2, part 3, part 4 – and are mostly OK with what has gone before, however it is good just to mention a few key things about what has already taken place.
- We have some creeps that go around a set path.
- We can place towers around the path.
- Towers fire at the nearest Creep.
- Creeps have Hp, and when HP is 0 (due to tower projectiles) the creeps “die” and are removed from the game.
- At the moment there is only one “Wave” of Creeps.
Aims of this Tutorial:
- Creating Multiple waves of Creeps.
- Defining how many Creeps of each type (red/green) per wave.
Source code after the break…
Here is the source code: Tower Defense Part 5a. Once again, we’re using the Cocos2d framework which you can download here!
To create multiple waves, first we must define multiple waves, this is done in addWaves in TutorialScene.m, originally it should look like this.
-(void)addWaves {
DataModel *m = [DataModel getModel];
Wave *wave = nil;
wave = [[Wave alloc] initWithCreep:[FastRedCreep creep] SpawnRate: 0.3 TotalCreeps:50];
[m._waves addObject:wave];
wave = nil;
wave = [[Wave alloc] initWithCreep:[StrongGreenCreep creep] SpawnRate:1.0 TotalCreeps:5];
[m._waves addObject:wave];
wave = nil;!
}
Hold up: The above means that there are two waves defined, the first wave has a total of 50 creeps, and spawns a knew one at 0.3 creeps per second. The initWithCreep[fastred] or [stronggreem] actually means nil to zilch at the moment (as we are defining which creep type to spawn at random in addTarget) therefore I will be “init-ing” with fast red creep from now on to avoid confusion.
After we define our wave, we add it to an array for storage/call back later and initialize our wave variable to nil. Adding our own waves: Yep you guessed it, to define our own waves all we need to do is to add more lines to the addWaves function, and just adjust the spawn rate and totalcreeps (if you so wish). I chose to create 5 waves, that will increase in difficulty as we progress.
-(void)addWaves {
DataModel *m = [DataModel getModel];
Wave *wave = nil;
wave = [[Wave alloc] initWithCreep:[FastRedCreep creep] SpawnRate: 1.0 TotalCreeps:10];
[m._waves addObject:wave];
wave = nil;
wave = [[Wave alloc] initWithCreep:[FastRedCreep creep] SpawnRate: 0.7 TotalCreeps:20];
[m._waves addObject:wave];
wave = nil;!
wave = [[Wave alloc] initWithCreep:[FastRedCreep creep] SpawnRate: 0.5 TotalCreeps:50];
[m._waves addObject:wave];
wave = nil;
wave = [[Wave alloc] initWithCreep:[FastRedCreep creep] SpawnRate: 0.3 TotalCreeps:70];
[m._waves addObject:wave];
wave = nil;
wave = [[Wave alloc] initWithCreep:[FastRedCreep creep] SpawnRate: 0.2 TotalCreeps:100];
[m._waves addObject:wave];
wave = nil;
}
One thing to mention here is that if we wish to spawn our creeps as faster than one per second, we must change our scheduler call to gameLogic. Go to Tutorial.m and find the init function. Here you will see a call to game logic such as:
[self schedule:@selector(gameLogic:) interval:1.0];
The gameLogic function looks at the spawn rate and compares it with the time that has passed since the last spawn. Therefor if we wanted a spawn rate of 0.1 and the gameLogic is scheduled at 1.0 when running the game the actual spawn rate will be 1.0. Therefor we must make sure that the gameLogic interval is a division of all the spawn rates.
I have set the gamescheduler to:
[self schedule:@selector(gameLogic:) interval:0.1];
As 0.1 is a divisible factor of all my spawn rates, and therefor the creeps will spawn at the rate that i set them.
Note: be aware that making the gameLogic interval smaller we are increasing the processing overhead.
Spawning our waves: The next thing to do is to spawn the next wave once the current wave has been defeated., This is fairly simple. In the update function (right at the end of the update) add in the following code.
Wave *wave = [self getCurrentWave];
if ([m._targets count] ==0 && wave.totalCreeps <= 0) {
// NSLog(@"Get next wave\n");//use for debugging
[self getNextWave];
}
Hold up: Simply what this piece of code does is to: get the current wave from m._waves array where we saved our waves to in addWaves, then check to see if there are any creeps currently on screen, and check to see that all the creeps have been spawned from the current wave. If these checks are correct, its means that we are at the end of the current wave and its time to load the next wave. There is one last thing to do before we test out our new wave system. Within getNextWave we check to see if we are at the end of our waves. So you will need to adjust this check for the amount of waves that you have included. For me this is 5 waves, however remember that it will count from 0 (unless you specify other wise).
if (self.currentLevel >= 5){
//self.currentLevel = 0;
NSLog(@"you have reached the end of the game!");
}
There you have it, multiple programmable waves! Run, Test, Have Fun.
Part B will be released soon, I promise – The source code for up until this point can be downloaded here.
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...
n1 man im also programming my tower defense and startet with the tutorials on this side…
i have already solved the stuff u mentioned here but im happy that u continue with it and maybe i can get sth from this… i will continue reading for sure^^
thx for ur tutor