GMS 2 Wave-based Enemies

Ok peeps, I've been been trying to figure this out for a while and I keep coming up empty.

I want something similar to this from Guacamelee: Youtube video

Basically, I want there to be multiple waves of enemies. When you defeat the first wave, the next wave spawns, and so on. However, I don't want random enemies or random enemy locations. Like Guacamelee, I want several specific enemy types spawning in several specific locations on each wave.

I can't seem to figure out any way to do this without hard-coding the entire thing. I my dream goal is to have a single objSpawner object that I can just reuse, inputting the values for each enemy (type, x & y spawning position, and the wave that it should spawn during) in its creation code. When all the waves are complete, the objSpawner destroys itself.

*Whew*. Big question, I know. Do you peeps have any idea where I should?
 

samspade

Member
Ok peeps, I've been been trying to figure this out for a while and I keep coming up empty.

I want something similar to this from Guacamelee: Youtube video

Basically, I want there to be multiple waves of enemies. When you defeat the first wave, the next wave spawns, and so on. However, I don't want random enemies or random enemy locations. Like Guacamelee, I want several specific enemy types spawning in several specific locations on each wave.

I can't seem to figure out any way to do this without hard-coding the entire thing. I my dream goal is to have a single objSpawner object that I can just reuse, inputting the values for each enemy (type, x & y spawning position, and the wave that it should spawn during) in its creation code. When all the waves are complete, the objSpawner destroys itself.

*Whew*. Big question, I know. Do you peeps have any idea where I should?
To some extent you're going to have to hard code things. But if you're goal is to have an object that basically has just a few variables you need to modify, that's fairly easy. The basic steps are:
  1. Create a spawner that operates in general the way you want
  2. Make all the things you want to be easy to change variables
  3. Decide how you want to change those variables - options include
    1. Duplicate objects with specific objects for rooms that have those variables set
    2. Set the object variables in the room create code
    3. Have a level or room object which creates the spawner and sets that spawner's variables
    4. Include all possible choices in the spawner itself and have it decide what to do in a switch or if statement
    5. and more I'm sure
 
I understand that I'm going to have to hard code some of it (like the enemy type and specific x/y location). But there's got to be a way to make it at least somewhat modular.

like, my dream is have to custom variables for the number of waves, number of enemies per wave, enemies types, and location.

I can envision bits and pieces of it, such as:
Code:
if instance_number(objEnemy) = 0 {currentWave += 1:}
if currentWave = waveMax {instance_destroy();
But the other stuff gets hairy....
 
Looks like you had a method for if enemies are destroyed go to wave X.

If you want specific locations...

Excuse the pseudo code.

Code:
// wave spawner code
i = 0;
globalvar waves_order,wave;
waves_order = i;
waves_order[i++] = 3; // go with wave 3 first
waves_order[i++] = 2; // go with wave 2 second
waves_order[i++] = 0; // go with wave 0 third

wave = 0;
alive = 0;

/// then use your code of if enemies destroyed wave++
if(wave >= array_length_1d(waves_order))
{
// wave system is complete!!!!!!!
instance_destroy()
exit;
}


// also in the step event
//
i = 0;
enemy_type = i; // type of enemy (object)
enemyX = i; // X pos
enemyY = i; // Y pos
// what wave are we on???
if(waves_order[wave] == 0)
{
//
enemy_type[i] = obj_bone_man;
enemyX[i] =whateveri;
enemyY[i] = whatever;
i++;
//
enemy_type[i] = obj_bone_man;
enemyX[i] =whateveri;
enemyY[i] = whatever;
i++;
//
enemy_type[i] = obj_angry_orc;
enemyX[i] =whateveri;
enemyY[i] = whatever;
i++;
//
enemy_type[i] = obj_sleepy;
enemyX[i] =whateveri;
enemyY[i] = whatever;
i++;
}else
if(waves_order[wave] == 1)
{
//
enemy_type[i] = obj_bone_man;
enemyX[i] =whateveri;
enemyY[i] = whatever;
i++;
//
enemy_type[i] = obj_bone_man;
enemyX[i] =whateveri;
enemyY[i] = whatever;
i++;
//
enemy_type[i] = obj_angry_orc;
enemyX[i] =whateveri;
enemyY[i] = whatever;
i++;
//
enemy_type[i] = obj_sleepy;
enemyX[i] =whateveri;
enemyY[i] = whatever;
i++;
}
Its pretty much the same as a shmup wave system only a shmup system comes above the room and drops down. Here is a visual representation of a time index when they should appear and where. Watch the radar, the yellow lines represent new waves. It stays halted until both enemies and gems are gone. Then it loads the next wave in using the same method from above.



If you were looking for a more visual method, you can always use persistent rooms and call upon them and drag them into the current room. That way you can use the editor to arrange your waves.
 
Last edited:
sitebender, that's more what I was thinking, thanks. I know it's pseudo code, but 'm curious about this line of code:



waves_order[i++] = 3; // go with wave 3 first
waves_order[i++] = 2; // go with wave 2 second
waves_order[i++] = 0; // go with wave 0 third


Any reason why it's 3, 2, 0 as opposed to 1,2,3 or whatever?
 

Axl Trauts

Member
@sitebender Hi, sorry for reviving this old post. I´ve been looking for a feature you show on the GIF. When you destroy an enemy formation, the last enemy in the formation drops loot. I see a wave is composed of several formations. So far I've created a spawner and I think I need to store the ids of the instances spawned by it.
 
Top