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.