Tower defense enemy intervals

well, I am working on a tower defense, and some other people on this forum have made tower defense’s

so my question, how should I determine how many enemies whould com when and what type of enemies. I hope I am being clear enough…

thx in advance,
h3ckboy

You will probably have all the diff types of enemies predetermined so you should be able to make an EnemyWave class that stores a list of enemies in the order they will spawn and a spawn delay for the timer between units being added to the map. You will probably also want an EnemyWaveManager class to store a list of EnemyWave objects and the time between waves spawning. Both would store internal timers that would be updated each tick and you can also use those to determine where to draw the info for a time line if you want that. You could also add stuff like having the EnemyWaveManager wave timer just finish when the image on the time line is clicked if you want that. Hope this helps.

hmm that is a pretty good idea.

it might take me a little bit of time to fully form the idea.

but that doesnt fully solve the issue however.

I was wondering also like how do I decide what type of units to put, like the first enemy secodn or so on, and how many to put. 1,2,3…

I hope I explained myself better.

thx,
h3ckboy

I’m not totally sure what you mean so hopefully some of this is relevant. To load the enemies from file you could just associate each enemy type with a character then create a text file where each line is a wave of enemies. So a simple level where p is a peon and f is a fast enemy could look like:


pppppppppp
pppppppppff

this level would be 2 waves of 10 creeps the first wave is all peons, the second is 8 peons then 2 fast enemies. The EnemyWave class could read a line in and fill an Enemy array(or linked list or whatever) then they just spawn in the same order.
something like this untested code sample:


public class EnemyWave{
   Map map;
   Enemy[] enemies;
   int currentEnemy = 0;
   int spawnTimer;
   int timer = 0;

   public EnemyWave(Map map, String wave, int spawnTimer){
      this.map = map;
      this.spawnTimer = spawnTimer;
      enemies = new Enemy[ wave.length() ];
      for(int i = 0; i < wave.length(); i++)
         enemies[i] = createEnemy( wave.charAt(i) );
   } 

   public void update(long time){
      if( waveFinished() )
         return; 
      timer += time;
      if(timer >= spawnTimer){
         map.addEnemy( enemies[currentEnemy] ); 
         currentEnemy++;
         timer -= spawnTimer;
      }
   }

   public boolean waveFinished(){
      return currentEnemy >= enemies.length;
   }

   // this simple Enemy class takes 2 paramenters, hp and speed.
   static Enemy createEnemy(char enemy){
      if(enemy == 'p')
         return new Enemy(1, 1); // peon
      if(enemy == 'f')
         return new Enemy(1, 3); // fast enemy
      return null;
   }
}

If you are talking about the level design then a good way to go at that might be to try and figure out what type of enemies you will have and what the player will have to counter them. Start the game off slow with just the simplest enemy and weapon, each level add a new enemy and weapon. Try to design the wave to use all the available enemy types in some kind of strategic way.

that is a good idea, but it has to go on forver, so it is not generated from a file, but generated

Beyond a certain point you can just loop it. I assume that you have a geometric increase in toughness multiplier, so you don’t need to increase the number of creeps for the difficulty to go up wave after wave.

Are you asking how to randomly generate waves of increasing difficulty then?

YES!!! that is it exactly taps nose

sry, for not phrasing it like that… but YES, that is exactly what I am talking about.

This is probably very game specific, and how you implement it would be based on what type of behavior you want. I’m not sure what type of enemies and weapons you will have but there will probably be weapons you will want for certain creeps like a stun or slow type tower for the fast creeps.
Here is a more generic version of the code above it will handle spawning the waves you will just need to worry about how to create the enemy array.


public class EnemyWave{
   Map map;
   Enemy[] enemies;
   int currentEnemy = 0;
   int spawnTimer;
   int timer = 0;

   public EnemyWave(Map map, Enemy[] enemies, int spawnTimer){
      this.map = map;
      this.spawnTimer = spawnTimer;
      this.enemies = enemies;
   } 

   public void update(long time){
      if( waveFinished() )
         return; 
      timer += time;
      if(timer >= spawnTimer){
         map.addEnemy( enemies[currentEnemy] ); 
         currentEnemy++;
         timer -= spawnTimer;
      }
   }

   public boolean waveFinished(){
      return currentEnemy >= enemies.length;
   }
}

To create the Enemy[] I would still recommend trying to make different predefined wave type but just let them have more hp and stuff based on the type of creep and the level like say fast creeps speed might be 1.5 * the map.level and peon creeps might have .75 or .50 * map.level. Then you can create methods to pick a type of predefined wave change small parts of it like the type. The Enemy[] creating method could be setup similar to this:
Create an interface so its easier to add new wave types later on.


public interface EnemyWaveType {
   public Enemy[] createWave();
}

Heres an example wave you could implement


public class  EasyEnemyWave implements EnemyWaveType {
   Map map;

   public EasyEnemyWave(Map map){
      this.map = map;
   }
   public Enemy[] createWave(){
      // create an easy enemy wave, you have access to the map do get the level or any other info the function should need
      // maybe use a range for the amount of enemies and make them slightly tougher if there is less of them
      int amount = 10; // change this how you want
      float difficulty = map.level; // or make this more complex if you want 
      Enemy[] enemies = new Enemy[amount];

      // probably just use a case statement or if statement to create an easy wave however you want
      // I'm making all peons to keep the example simple
      for(int i=0;i<amount;i++){
         enemies[i] = new Enemy();
         enemies[i].setMaxHp(difficulty * 1);
         enemies[i].setMaxSpeed(difficulty * 1);
      }
      return enemies;
   }
}

Just change these to fit what you want to happen. By using an interface like that the map can just have a member variable of type EnemyWaveType and you can implement as many different wave types as you want fairly easily and self contained.

Having the game level not capped you might not want to cap the amount of upgrades players can do or have some other type of system to make sure the levels don’t just become unbeatable. Having no end and the level uncapped might also make the game repetitive in the later levels because you only have a predefined amount of new enemy types and weapons you can introduce.

Without knowing what types of things are in your game its impossible to give advice on balancing wave size and makeup so I hope this is helpful.