• 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!

GML needing help with a script

Wendell

Member
Hey guys, so, I'm trying to make a script which basically creates objects on a random position within a determined region of the room. The script I call with:

Code:
create_object_at_random_position(amount, object, layer);
Where the "amount" is how many instances of the "object" will be created on the specified "layer".

The script is as follows (consider 16 to the cell_size_ variable):

Code:
///@arg amount
///@arg object
///@arg layer

var _amount = argument0;
var _object = argument1;
var _layer = argument2;

for (var _i = 0; _i < _amount; _i++)
{
   if instance_number(_object) < _amount
   {
       var _min_point_x = cell_size_ * 2;
       var _min_point_y = cell_size_ * 2;
       var _max_point_x = cell_size_ * 16;
       var _max_point_y = cell_size_ * 9;
      
       do
       {
           var _point_x = irandom_range(_min_point_x, _max_point_x);
           var _point_y = irandom_range(_min_point_y, _max_point_y);
  
           var _chosen_point_x = round( _point_x / 16 ) * 16;
           var _chosen_point_y = round( _point_y / 16 ) * 16;

           var _object_in_position = instance_position(_chosen_point_x+8, _chosen_point_y+8, all);
       }

       until place_free(_chosen_point_x+8, _chosen_point_y+8) && _object_in_position == noone;       
      
       if place_free(_chosen_point_x+8, _chosen_point_y+8) && _object_in_position == noone {
       instance_create_layer(_chosen_point_x, _chosen_point_y, _layer, _object);   
       } else {
       _amount += 1;   
       }
   }
}
So, it works pretty well, but sometimes a few objects are created on top of each other. I did all the ajustments that could come to my mind with the until/do and the place_free functions, but it still sometimes creates stacked objects. I say sometimes because it is really only sometimes and I don't know a better way to check and prevent an object to be created atop of another.

Can someone give me some light?
 

obscene

Member
Personally I'd use something like collision_circle instead of place_free because you can control the size of it. Here's a similar script I use. It doesn't create objects but is just used to spread them out. It starts out with a 600 pixel radius and just keeps randomizing positions while reducing the radius. Usually works in about 2 or 3 iterations in my case, though it could theoretically fail with enough enemies and a small enough area so it's far from perfect.

Code:
/// @param xmin
/// @param xmax
/// @param ymin
/// @param ymax
var xmin=argument0;
var xmax=argument1;
var ymin=argument2;
var ymax=argument3;
var distance=600;
var too_close;
do
    {     
    // If this stays false, we are done
    too_close=false;
 
    // Check every enemy for enough distance
    with (par_character)
        {
        if (collision_circle(x,y,distance,par_character,true,true))
            {
            // Try again
            too_close=true;
            x=random_range(xmin,xmax);
            y=random_range(ymin,ymax);
            }
        }
     
    // A little more forgiving each iteration
    distance-=50;
    }
until (too_close==false);
 
Top