Wave spawning system!

Mar 05, 2019 22:12· 707 words · 4 minutes read

Some of you were interested in how I spawn monsters in my game, so in today’s post I will be explaining my method, it might not be the most effective, but it does what I need it to do.


For this tutorial you are going to need a basic project containing atleast 2 monsters and a Player.

Everything in the wave system is managed by an object named obj_orchestrator, which contains the monsters it needs to spawn for each wave and monitors the Player‘s kills, number of monsters alive, etc. reacting accordingly by creating new monsters and activating wave change animations.

The create event of the object orchestrator contains all the wave information inside 2 arrays:

  • wave_monsters
  • wave_monsters_numbers

And here’s an example of the code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
wave_monsters[0] = "obj_monster1,obj_monster2"
wave_monsters[1] = "obj_monster1,obj_monster2"
wave_monsters[2] = "obj_monster1,obj_monster2"
wave_monsters[3] = "obj_monster1"
wave_monsters[4] = "obj_monster1"
wave_monsters[5] = "obj_monster1"
wave_monsters[6] = "obj_monster1"

wave_monsters_number[0] = "25,10"
wave_monsters_number[1] = "40,10"
wave_monsters_number[2] = "70,30"
wave_monsters_number[3] = "200"
wave_monsters_number[4] = "400"
wave_monsters_number[5] = "800"
wave_monsters_number[6] = "1600"

In the code pasted below I keep track of all the monsters currently alive by going through the list of monsters I spawned (wave_monsters[wave]), checking how many of them are alive by using instance_number(current_monster) and spawning monsters if needed.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
if(pause) //IF THE GAME IS PAUSED DON'T DO ANYTHING
{
return
}

if(not active) //IF THIS OBJECT IS NOT ACTIVE DON'T DO ANYTHING
{
return
}

x = obj_player.x
y = obj_player.y

var enemy_counter = 0

var monster_counter = 0

var monster_number_split = split_string(wave_monsters_number[(wave-1)], ",")
var monster_split = split_string(wave_monsters[(wave-1)], ",")

var monster_total_number = 0

for(a = 0; a < array_length_1d(monster_number_split); a++)
{
monster_total_number += real(monster_number_split[a])
}

for(a = 0; a < array_length_1d(monster_split); a++)
{
var current_monster = asset_get_index(monster_split[a])
monster_counter += instance_number(current_monster)
}

if ((monster_counter + wave_kills) < monster_total_number)
{

var randomizer = choose(1,2)
if(randomizer == 1)
{
var _rand_x = choose(random_range(0,400),random_range(0,-400))
var _rand_y = choose(random_range(300,400),random_range(-300,-400))
}
if(randomizer == 2)
{
var _rand_x = choose(random_range(300,400),random_range(-300,-400))
var _rand_y = choose(random_range(0,400),random_range(0,-400))
}

for(a = 0; a < array_length_1d(monster_split); a++)
{
var current_monster_total = real(monster_number_split[a])
var current_monster = asset_get_index(monster_split[a])
if(instance_number(current_monster) < current_monster_total)
{
instance_create_depth(x+_rand_x,y+_rand_y,0, current_monster)
}
}
}

When the number of monsters alive reaches 0, the wave variable is updated and an alert that starts the next wave after 10 seconds is launched. When I implement a HQ system (which the monsters will target) this time will be incremented to 30 seconds which the Player will be able to use for stat/skill upgrades.

Code:

1
2
3
4
5
6
7
8
9
10
11
12
13
if (wave_kills >= monster_total_number)
{
wave += 1
active = false

obj_wave_counter.scale_modifier = 2
obj_wave_counter.x_modifier = global.MonitorW/2 - 50
obj_wave_counter.y_modifier = global.MonitorH/2
obj_wave_counter.active = true

wave_kills = 0
alarm[0] = room_speed*10
}

In the video you can see that I have a number incicating the wave in the user interface, to do that I created a new object that does all the animating and image changing. I will not include the animation code in this post because it’s not as optimized (readable) as it should be.

Draw event:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var current_wave = obj_orchestrator.wave

if(active)
{
alarm[0] = room_speed*2
active = false
}

if(current_wave < 10)
{
num_0 = 0
num_1 = current_wave
}
else
{
var num_1 = current_wave % 10
var num_0 = floor(current_wave / 10)
}

var sprite_0 = asset_get_index("spr_number_" + string(num_0))
var sprite_1 = asset_get_index("spr_number_" + string(num_1))

draw_sprite_ext(sprite_0,0,current_x, current_y,scale_modifier,scale_modifier,0,c_white,1.0)
draw_sprite_ext(sprite_1,0,current_x + 50*scale_modifier, current_y,scale_modifier,scale_modifier,0,c_white,1.0)

Create:

1
2
3
current_x = obj_camera.view_x
current_y = obj_camera.view_y
active = false

Alarm:

1
2
3
scale_modifier = 1
x_modifier = 50
y_modifier = 50

After all this work you should have a working wave system as seen in the video on top and if I missed anything or would like me to add anything, please do contact me at main.fearless@gmail.com.

That’s it for today! Enjoy!