Legacy GM How to activate one object in room from many others?

E

Eugene Shepherd

Guest
Little backstory:
I have an idea to make enemy spawner - box, which gonna identify where to place the 'enemy' on the floor.
It is an object that I can see in room editor, so I can stretch it and thus its code will allow to register all the floor it touches and make a random desicion, where to place enemy by the width of itself.

So I have another object, that will, as I think, choose, what spawner will activate at a time, because if I write a code to spawn an enemy to the spawner it basically will make every spawner in room create its own enemy at once (on every floor I place it).

Question:
How do I refer to one object from many objects of the same type? Also how to make it that I refer to the object in view, on screen, so it won`t do anything on the other side of the room, out of sight?
Lastly, if it is possible, do anybody have a code to spawn enemies? I haven`t done it before, so I can`t understand the basics behind it.
 

Slyddar

Member
To spawn enemies in 1.4, you can create an object with instance_create.

Each object in a room is called an 'instance' of that object. Each instance is identified by the variable 'id'. Now how you refer to it depends on what you want to happen in your game. When you say how to refer to one object, well there are many ways, depending on what you require. Some ways you can use to identify particular instances are;
instance_furthest
instance_nearest
instance_place
instance_position

Once you have identified the instance you want you can store it's id, say as 'enemy_id', and access it by using the with function. e.g.
Code:
with(enemy_id)
{
  //any code you run in here will be run within that particular enemy only
}

Another way you can do it, is you can assign an id to the enemy yourself when they spawn. This code spawns 5 enemies using a for loop, each with their own enemy_id from 0 to 4.
Code:
var enemies_to_spawn = 5;
(for i = 0; i < enemies_to_spawn; i++) {
  var inst = instance_create(x, y, o_enemy);
  inst.enemy_id = i;
}
You can then use that to pick a particular one if needed. Use with again to cycle through every enemy, but say we are only interested in the enemy with enemy_id = 2;
Code:
with(o_enemy)
{
  if enemy_id == 2 {
    //do whatever you need

    //quit looking at all the enemies as we found the one we needed
    break;
  }
}
This is all just an overview, but maybe it will help you start. Try them out and ask questions about your specific requirements if needed.

Good luck!
 
Last edited:

Simon Gust

Member
I recommend doing it like this:
- make a ds_list
- call every spawner object using a with statement
- call rectangle_in_rectangle with the view arguments to see if the object is inside the view
- add it to the list if it is in the view
- pick a random entry from that list, the object chosen will spawn your enemies.
Code:
var list = ds_list_create();
with (obj_spawner)
{
   if (rectangle_in_rectangle(bbox_left, bbox_top, bbox_right, bbox_bottom, view_xview, view_yview, view_xview + view_wview, view_yview + view_hview))
   {
      ds_list_add(list, id);
   }
}

var spawner = noone;
var size = ds_list_size(list);
if (size > 0)
{
    var spawner = ds_list_find_value(list, irandom(size-1));
}

with (spawner)
{
   var xx = irandom_range(bbox_left, bbox_right);
   var yy = irandom_range(bbox_top, bbox_bottom);
   var enemy = instance_create(xx, yy, obj_enemy);
}
 
E

Eugene Shepherd

Guest
Guys, thank you for your support. Especially - Simon Gust.
Basically I did not get what is ds_list (haven`t got to it by tutorials), instead I used instance_id.
Thanks to the tutorial from channel "Gamemaker Game Programming Course":
and to the answer from Simon Gust in this post:
https://forum.yoyogames.com/index.p...ating-specific-objects-within-a-region.30095/

I used a code to register "spawner" on screen and once it is out of view - it stops working.
Step event:
Code:
///Id enemy spawn

//Enemy spawn clock
if alarm[0] = -1
{
  alarm[0] = room_speed * random_range(2,20)  //reset alarm randomly to spawn next enemy
}

//Find how many enemies are in room
enemies_left = instance_number(oEnemy);   //counting enemies in room so they wont go futher the maximum amount of "enemies_roommax" in create event (example: enemies_roommax = 5)

//Find how many enemy spawners are in room
ensp = instance_number(oEnemySpawner);

// resurrect oEnemySpawner
instance_activate_object(oEnemySpawner);

// list all instances of oEnemySpawn in sight
for (var i = 0; i < ensp; i++)
{
 var inst = instance_find(oEnemySpawner, i);
 if (!point_in_rectangle(inst.x, inst.y, view_xview, view_yview, view_xview+view_wview, view_yview+view_hview))
 {
  instance_deactivate_object(inst);
 }
}

//Pick random spawner
pick = irandom_range(0,ensp-1);  //say 0-4 for 5 monsters

//Find that spawners id
spawnerid = instance_find(oEnemySpawner, pick);

//Then you can spawn your enemy with picked id
// with 'Spawner' {...} in Alarm event
That way spawners within the screen view will be randomly chosen after alarm is off.

Alarm event:
Code:
///Create enemy
if (enemies_left < enemies_roommax)
{
    with spawnerid
    {
    instance_create(x,y-oSolid.sprite_height/2,oEnemySpawn);
    }
}
Still dont know how code "// list all instances of oEnemySpawn in sight" works, but it does :)
The only thing left is to make "spawner box" register the ground (obj_Solid) under itself, so it could randomly spawn an enemy within the width of itself.
 
Top