As a few of you have requested, I will write another tutorial on creating a custom tower type. In this tutorial I will show you how to create a tower the makes the enemies move slower when they are hit with a bullet, and hopefully by the end of this tutorial you will see how easy it is to extend the tower class to make all sorts of different towers!
For simplicities sake, I am only going to show you the changes needed to create the new tower class and not include any details about adding a new button or changing the player AddTower method (If you need help on this see Tutorial 12). However I will provide some placeholder textures that you can use for the slow tower :
So let’s begin, the first thing we are going to do is add a few new fields and properties to the Enemy class :
private float speedModifier;
private float modifierDuration;
private float modiferCurrentTime;
/// <summary>
/// Alters the speed of the enemy.
/// </summary>
public float SpeedModifier
{
get { return speedModifier; }
set { speedModifier = value; }
}
/// <summary>
/// Defines how long the speed modification will last.
/// </summary>
public float ModifierDuration
{
get { return modifierDuration; }
set
{
modifierDuration = value;
modiferCurrentTime = 0;
}
}
Vector2 direction = waypoints.Peek() - position;
direction.Normalize();
// Store the original speed.
float temporarySpeed = speed;
// If the modifier has finished,
if (modiferCurrentTime > modifierDuration)
{
// reset the modifier.
speedModifier = 0;
modiferCurrentTime = 0;
}
if (speedModifier != 0 && modiferCurrentTime <= modifierDuration)
{
// Modify the speed of the enemy.
temporarySpeed *= speedModifier;
// Update the modifier timer.
modiferCurrentTime += (float)gameTime.ElapsedGameTime.TotalSeconds;
}
velocity = Vector2.Multiply(direction, temporarySpeed);
position += velocity;
// Defines how fast an enemy will move when hit.
private float speedModifier;
// Defines how long this effect will last.
private float modifierDuration;
We also need to initialize these fields in the SlowTower constructor :
this.speedModifier = 0.6f;
this.modifierDuration = 2.0f;
Next go down to the SlowTower’s Update method and find where we check if a bullet has hit the target :
if (target != null && Vector2.Distance(bullet.Center, target.Center) < 12)
And just under what is inside the if statement, add this :
// Apply our speed modifier if it is better than
// the one currently affecting the target :
if (target.SpeedModifier <= speedModifier)
{
target.SpeedModifier = speedModifier;
target.ModifierDuration = modifierDuration;
}
We will only allow an enemy to have one speed modifier acting on it – the modifier will only be applied to the enemy if it is better than the current one.
And voilĂ , we have a new type of tower, it really is that simple! There is a lot more that you could change / add to this tower :
- This tower costs exactly the same as the arrow tower and does the same damage.
- Maybe you think the enemy should move even slower when hit by this tower or maybe it should move slow for longer?
- What if when an enemy is hit by this tower it is tinted a different colour to show that it has been slowed?
- Maybe this tower should only target enemies that are moving at normal speed for maximum efficiency?
- Or perhaps it could target more than one enemy at a time, or have a kind of “Splash” effect!
Maybe you could see how many of the above you could add to the tower to test your skills? If you have some trouble creating a button for this class, I will upload working source that shows you how to do this.
Very nice tutorial again !
ReplyDeleteThank you very much !
I can't seem to get it to add money and take lives depending on you killing the enemy or the enemy running through the end... It won't let me create a reference of the Player class to use player.Lives or player.Money, I've created the set{} variables on each though :P
ReplyDeleteAny ideas?
VERY NICE TUTORIAL btw
Hey, I plan on writing a short tutorial soon on this. This was something I overlooked when creating the player class... xD
ReplyDeleteYou need to do a tutorial for the game ending. And maybe a menu screen.
ReplyDeleteI was wondering, with the slow tower, you might get some enemies pass other enemies, or, if you eventually have enemies that are faster than others in the same wave.
ReplyDeleteHow can you set up the towers to target whichever enemy is closest to the end?
Hi Sean, you will need to override the GetClosestEnemy method in the SlowTower class, something like this would probably work :
ReplyDeletepublic override void GetClosestEnemy(List enemies)
{
target = null;
float smallestRange = float.MaxValue;
foreach (Enemy enemy in enemies)
{
if (IsInRange(enemy.Center) == false)
{
continue;
}
float distance = enemy.WaypointCount + (enemy.DistanceToDestination / 32.0f);
if (distance < smallestRange)
{
smallestRange = distance;
target = enemy;
}
}
}
I have a question about the slow tower you have the code:
ReplyDelete// Apply our speed modifier if it is better than
// the one currently affecting the target :
if (target.SpeedModifier <= speedModifier){
target.SpeedModifier = speedModifier;
}
Shouldn't this be the other way around, because the modifier is a factor, the smaller the better. I read this as a .6 modifier being replaced by a .9
Hey FireFly,
ReplyDeleteI follow all of your tutos'. They're awesome. I was looking for something like this. So a big thank you ;)
And why don't you implement the slowing effect with a Buff list ?
Well I did it with a buff list, and this is great ;p
Do you think you'll have the time to make more tutos? I hope so. Especially on the network multiplayer system, or how to manage titlescreen, gamescreen, and others screen ( like victory screen, etc.. ).
Hope you'll see this comment, you didn't post since a long time..
J.