• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

SOLVED How to create multiple new instances of objects using an alarm

G

Grillied

Guest
Title isn't worded greatly, but basically I have objects that are deleted upon collision with the player. I need the objects to respawn after a set amount of time, so I'm using an alarm to do that. The problem is if I collide with multiple objects, only the last one I collided with respawns. I know this is because the alarm resets on every collision, but I can't think or find any way around that. I think it would work fine if I could have the alarm triggered on the object being deleted, so it is separate, but I don't think I can since it is deleted immediately. Sorry if this is unclear.

Player Collision Code:
xpos = other.x;
ypos = other.y;
if (alarm[0] == -1) {
alarm[0] = 3*room_speed;
}

Alarm Code:
instance_create_layer(xpos, ypos, "Instances", oWall);
 

FrostyCat

Redemption Seeker
Always think about kicking things off to workers in situations like this.

Collision code:
GML:
instance_create_layer(other.x, other.y, "Instances", oWallRespawn);
oWallRespawn Create:
GML:
alarm[0] = 3*room_speed;
oWallRespawn Alarm 0:
GML:
instance_create_layer(x, y, "Instances", oWall);
instance_destroy();
 
Create a ds_list:

Player Create Event:
Code:
spawn_list = ds_list_create();
Then add the instance to the list when you collide with it:

Player Collision Event:
Code:
var _xpos = other.x;
var _ypos = other.y;
ds_list_add(spawn_list,[_xpos,_ypos]); // Add the position as an array to the list
Now we'll set up a check in the Step Event that triggers the alarm if the list has any entries:

Player Step Event:
Code:
if (ds_list_size(spawn_list) > 0) {
   if (alarm[0] <= -1) {
      alarm[0] = 3*room_speed;
   }
}
Finally, we'll create the instances in the alarm:

Alarm[0] Event:
Code:
var _inst_pos = spawn_list[| 0]; // Grab the first position added to the list
var _xpos = _inst_pos[0]; // Pull the x and y out of the array we added to the list, if you are using 2.3 you can do this a bit differently, but whatever
var _ypos = _inst_pos[1];
instance_create_layer(_xpos,_ypos,"Instances",oWall);
ds_list_delete(spawn_list,0);
EDIT: Sniped, but frosty is more right, using a controller object for respawn is more typical. Using a list for queuing multiple things is a good thing to learn though.
 
G

Grillied

Guest
Create a ds_list:

Player Create Event:
Code:
spawn_list = ds_list_create();
Then add the instance to the list when you collide with it:

Player Collision Event:
Code:
var _xpos = other.x;
var _ypos = other.y;
ds_list_add(spawn_list,[_xpos,_ypos]); // Add the position as an array to the list
Now we'll set up a check in the Step Event that triggers the alarm if the list has any entries:

Player Step Event:
Code:
if (ds_list_size(spawn_list) > 0) {
   if (alarm[0] <= -1) {
      alarm[0] = 3*room_speed;
   }
}
Finally, we'll create the instances in the alarm:

Alarm[0] Event:
Code:
var _inst_pos = spawn_list[| 0]; // Grab the first position added to the list
var _xpos = _inst_pos[0]; // Pull the x and y out of the array we added to the list, if you are using 2.3 you can do this a bit differently, but whatever
var _ypos = _inst_pos[1];
instance_create_layer(_xpos,_ypos,"Instances",oWall);
ds_list_delete(spawn_list,0);
EDIT: Sniped, but frosty is more right, using a controller object for respawn is more typical. Using a list for queuing multiple things is a good thing to learn though.
Thanks for the help!
 
G

Grillied

Guest
Always think about kicking things off to workers in situations like this.

Collision code:
GML:
instance_create_layer(other.x, other.y, "Instances", oWallRespawn);
oWallRespawn Create:
GML:
alarm[0] = 3*room_speed;
oWallRespawn Alarm 0:
GML:
instance_create_layer(x, y, "Instances", oWall);
instance_destroy();
Thanks!
 

chamaeleon

Member
Title isn't worded greatly, but basically I have objects that are deleted upon collision with the player. I need the objects to respawn after a set amount of time, so I'm using an alarm to do that. The problem is if I collide with multiple objects, only the last one I collided with respawns. I know this is because the alarm resets on every collision, but I can't think or find any way around that. I think it would work fine if I could have the alarm triggered on the object being deleted, so it is separate, but I don't think I can since it is deleted immediately. Sorry if this is unclear.

Player Collision Code:
xpos = other.x;
ypos = other.y;
if (alarm[0] == -1) {
alarm[0] = 3*room_speed;
}

Alarm Code:
instance_create_layer(xpos, ypos, "Instances", oWall);
You could experiment with queues holding instances to create.
Create Event
GML:
q = ds_queue_create();

ds_queue_enqueue(q, {x: 1, y: 2, t: get_timer() + 1*1000000}); // Activate after 1 second
ds_queue_enqueue(q, {x: 2, y: 3, t: get_timer() + 2*1000000}); // Activate after 2 seconds
Step Event
GML:
while (!ds_queue_empty(q)) {
    var thing = ds_queue_head(q);
    if (thing.t < get_timer()) {
        show_debug_message("Thing " + string(thing.x) + ", " + string(thing.y));
        ds_queue_dequeue(q);
    } else {
        break;
    }
}
Code:
Thing 1, 2
Thing 2, 3
In your case, use a single ds_queue_enqueue() call in the collision event, and store the x and y coordinates with the amount time you wish to wait until an instance is created, and in the step event for the instance holding the queue create a wall instance instead of or in addition to the show_debug_message().

I used two calls to enqueue two things and two different offsets to get some spacing in time between the show_debug_message() calls (as the create event adds both approximately the same time so if I used the same time offset I'd get the output of both at the same time more or less). In your case, you'd presumably just use a single fixed offset that is the same for every instance you wish to recreate.
 
Top