GameMaker Create a object away from others

Roalinn

Member
I want to create a object on random position then create other but minimum distance between first and second is 64 pixel. then create other object .minimum distance between first and third, second and third is 64 pixel.
how i check a distance between object and all objects.
 

Attachments

C

Captain_ArrowWound

Guest
A way to this would be to make to objects. Maybe something like object circle spawner none and object circle spawner there, just names. Place both of them into your world. Object circle spawner none would check if there are no circles placed down, if there are none then it would randomly spawn a circle. Your next object, object circle spawner there would check if any circles are placed down. If there are circles placed down it will spawn a circle at least 64 pixels away from any other circles.
 

FrostyCat

Redemption Seeker
If they are all the same object type or share the same parent, combine instance_nearest() with point_distance().
Code:
var xx, yy, inst_nearest;
do {
  xx = irandom(room_width);
  yy = irandom(room_height);
  inst_nearest = instance_nearest(xx, yy, object);
} until (inst_nearest == noone || point_distance(xx, yy, inst_nearest.x, inst_nearest.y) >= 64)
instance_create_layer(xx, yy, layer, object);
 

Slyddar

Member
This will work, even though it's kind of brute force.
Code:
var xx, yy, num, attempts = 0, list = ds_list_create();
var accuracy = 10000;    //how many iterations, to ensure coverage
var dis = 64;            //gap between objects
var obj = o_object;      //object to create

xx = random(room_width);
yy = random(room_height);
var inst = instance_create_depth(xx, yy, depth, obj);

do {
    with(inst) {
        //check for a collision within a circular distance
        num = collision_circle_list(x, y, dis, obj, false, true, list, false);

        if num > 0 {
            //collision found, so try another location
            x = random(room_width);
            y = random(room_height);
            attempts++;
        } else {
            //no collision, create another and reset count
            var inst = instance_create_depth(x, y, depth, obj);
            attempts = 0;
        }
    }
} until attempts > accuracy;

//destroy last one, as it didn't find a spot
instance_destroy(inst);
ds_list_destroy(list);
 
Last edited:

Slyddar

Member
If you want to get technical, google about poisson-disc sampling.
That poisson-disc sampling(pds) is really interesting, and was something I was toying with when writing my first solution, although I didn't know the name of it, I had thought of the concept. So going back and reworking it more like pds, this method is more efficient then what I posted above. It creates an object, and then checks the min distance in a circle all around it, creating objects where it can, then removes itself from further checks. This is repeated a few times, depending on room size until no more spots are available. I also tried doing it with ds_queues, so we don't loop through excluded objects, but in the end, using with() was more efficient according to time checks.

Code:
var xx, yy, dis, num, list = ds_list_create(), iterations, obj = o_object, inst, start;
dis = 64;            //gap between objects
xx = room_width/2;
yy = room_height/2;
inst = instance_create_depth(xx, yy, depth, obj);
inst.include = true;
iterations = ceil((sqrt(sqr(room_width/2) + sqr(room_height/2)))/dis)*2;
repeat(iterations) {
    with(obj) {
        if include {
            start = random(360);
            for (var i = 0; i < 360; i+=3) {
                xx = x + lengthdir_x(dis, start + i);
                yy = y + lengthdir_y(dis, start + i);

                //check for a collision within a circular distance
                num = collision_circle_list(xx, yy, dis, obj, false, true, list, false);
                if num == 0 and xx > 0 and xx < room_width and yy > 0 and yy < room_height {
                    //no collision, create another
                    inst = instance_create_depth(xx, yy, depth, obj);
                    inst.include = true;
                }
            }
            include = false;        //remove this object from further checks    
        }
    }
}
ds_list_destroy(list);
 
Last edited:
Top