Windows Enemy Spawner Logic

D

DarthTenebris

Guest
Hello everyone,

Currently working on an idea that I have and it involves spawners as a method to bring in enemies. However I don't seem to be able to work out the logic on how to do so.

Create Event:
Code:
ros = room_speed * 5;

minRange = 64 * 2;
maxRange = 64 * 4;

minSpawn = 1;
maxSpawn = 4;
maxEnt = 8;

alarm[0] = ros;
Alarm[0] Event:
Code:
var count = irandom_range(minSpawn, maxSpawn);
var spawn = false;

if (instance_exists(obj_enemy)) { // if enemy exists
    var ent = 0;
  
    for(var i = 0; i < instance_number(obj_enemy) - 1; i++) { // loop through all enemies
        var enemy = instance_find(obj_enemy, i)
        if (point_in_circle(enemy.x, enemy.y, x, y, maxRange)) { // check if enemy is too close
            ent++; // count enemies that are too close
        }
    }
  
    if ((ent + count) < maxEnt) {
        spawn = true; // allow to spawn only if spawning the enemy doesnt cause to blow the limit
    }
} else {
    spawn = true; // if no enemy exists then obviously its fine to spawn
}

if (spawn) {
    repeat(count) {
        do { // keep trying to find free space
            var dis = random_range(minRange, maxRange); // pick a random distance
            var dir = random_range(0, 360); // pick a random angle
      
            // convert polar (distance, angle) to cartesian (x, y) relative to spawner
            var xspawn = lengthdir_x(dis, dir);
            var yspawn = lengthdir_y(dis, dir);
        } until ((!place_meeting(xspawn, yspawn, obj_wall)) // until it finds free space obviously
            && ((xspawn > 0) && (xspawn < room_width))
            && ((yspawn > 0) && (yspawn < room_height))) // and also isnt outside the room
      
        instance_create_layer(x + xspawn, y + yspawn, "Instances", obj_enemy_kamikaze);
    }
}

alarm[0] = ros;
The problem is the enemies seem to keep spawning in the walls or outside the room, I can't quite tell. Also for some reason only the top left corner spawner is able to spawn anything. When an enemy is created it simply tries to move in a straight line to get to the target, which is the blue box in the center. When an enemy dies, a particle effect is generated with a random size and color.
upload_2019-6-14_13-18-9.png
Note: The green circles are bullets from the player, no problem with that. Just happened to get caught in the screenshot.

Hopefully I've commented my code adequately to explain my thought train. Any idea what I'm doing wrong?

Thank you for your time.
 
Last edited by a moderator:
D

DarthTenebris

Guest
Before going any further.... Shouldn't that be -dsin(dir)? :rolleyes:
A quick google search reveals the fornula has no negatives... Unless it's different for programmers because our cartesian plane is upside down?

Thank you for your time.
 

TheouAegis

Member
You are using place_meeting(), so your spawner needs to have the exact same size sprite as the entity that it is trying to spawn. Otherwise, you should be creating the entity and then having the entity move itself out of the collision.
 
Last edited:
D

DarthTenebris

Guest
You are using place_meeting(), so your spawner needs to have the exact same size as bright as the entity that it is trying to spawn. Otherwise, you should be creating the entity and then having the entity move itself out of the collision.
Currently all objects have the same size, 64x64, with the exception of the player bullet of 16x16. However I do prefer to be able to spawn any size of an enemy I want regardless of the spawner size, so are there any other methods that would work, without having to have the enemy push itself out of the walls (the spawner is non solid, it's just there as a visual thing, nothing is to be colliding with it)?

Thank you for your time.
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
A quick google search reveals the fornula has no negatives... Unless it's different for programmers because our cartesian plane is upside down?
Ummm... If you are trying to spawn in a circle around an area, I'm absolutely certain that it's:

var xspawn = dis * dcos(dir);
var yspawn = dis * -dsin(dir);
I mean, I don't use these functions for this kind ogf thing and prefer the lengthdir_x/y functions, but I've ALWAYS figured those to be:

lengthdir_x( dist, angle ) = dist * dcos( angle )
lengthdir_y( dist, angle ) = dist * -dsin( angle )
Which is why I'm saying your maths are off. Have you tested it?
 
D

DarthTenebris

Guest
Ummm... If you are trying to spawn in a circle around an area, I'm absolutely certain that it's:



I mean, I don't use these functions for this kind ogf thing and prefer the lengthdir_x/y functions, but I've ALWAYS figured those to be:



Which is why I'm saying your maths are off. Have you tested it?
Overengineering :)
Regardless I'll pick up the lengthdir functions as well instead of making my own converter... However my main issue is yet to be resolved. Still only spawns from the top left spawner, and a lot of times the enemies spawn in the wall. Any ideas?

Thank you for your time.


EDIT: https://www.mathsisfun.com/polar-cartesian-coordinates.html
 
Last edited by a moderator:
D

DarthTenebris

Guest
Thread bump, still need help working out why the spawner keeps spawning enemies in the wall when I tried to do the exact opposite.
 

TheouAegis

Member
Does your spawner object actually have a sprite sprite a to it? Your reply to that wasn't super clear. If the spawner has no sprite assigned to itself, you cannot use place_meeting() like you are doing. If you assign your spawner the same sprite as that of the entity it is trying to spawn, your code should work.

Also, this:
} until ((!place_meeting(xspawn, yspawn, obj_wall))
should be:
} until ((!place_meeting(x+xspawn, y+yspawn, obj_wall))
 
D

DarthTenebris

Guest
Does your spawner object actually have a sprite sprite a to it? Your reply to that wasn't super clear. If the spawner has no sprite assigned to itself, you cannot use place_meeting() like you are doing. If you assign your spawner the same sprite as that of the entity it is trying to spawn, your code should work.

Also, this:
} until ((!place_meeting(xspawn, yspawn, obj_wall))
should be:
} until ((!place_meeting(x+xspawn, y+yspawn, obj_wall))
There's my problem, thank you very much :)

Yes the spawner has a sprite, not the same one as the entity it's spawning but it is the same size. How would I adapt if it wasn't the same size though?

Thank you for your time.
 
Top