Form Circle with Objects

king javo

Member
I'm trying to think of the best way to have all of my player objects (11) form a circle from a top-down view perspective. I'm planning to move them towards a point and I can either calculate each (x,y) around that point or do something else.

Here's an example of what I want but from a top-down view.
upload_2017-7-19_14-29-13.png
 
You will need a center point, a distance from the center point, and then a direction from the center point for each object.

Then you calculate their new x and y using lengthdir_x/y like this:

Code:
x = center_point_x+lengthdir_x(distance,my_direction);
y = center_point_y+lengthdir_y(distance,my_direction);
 

king javo

Member
You will need a center point, a distance from the center point, and then a direction from the center point for each object.

Then you calculate their new x and y using lengthdir_x/y like this:

Code:
x = center_point_x+lengthdir_x(distance,my_direction);
y = center_point_y+lengthdir_y(distance,my_direction);
Thanks for the quick help! :)

Ok, so I have the center point, a distance from center is just 30 for now, but the direction from the center is where I think I'm missing the boat. I'm using point_direction(x,y,center_point_x,center_point_y) and my player objects just overlap across the same point.
 
Well, yeah. If you want them in a circle you need to give them a UNIQUE position.

Say you have 5 objects.

Take 360 divide it by 5. You get 72.

So you have guys 0-4 (5 guys) and you multiply their "index" by 72.
0*72 = 0
1*72=72
2*72=144
etc

Set that as their direction from center point, and this will space them out perfectly in a circle.
 

king javo

Member
Well, yeah. If you want them in a circle you need to give them a UNIQUE position.

Say you have 5 objects.

Take 360 divide it by 5. You get 72.

So you have guys 0-4 (5 guys) and you multiply their "index" by 72.
0*72 = 0
1*72=72
2*72=144
etc

Set that as their direction from center point, and this will space them out perfectly in a circle.
This sounds like an easy question to answer, but for some reason I can't figure out the easiest/least expensive way to get an object's instance number. So for my example, the Player object has 3 instances (0,1,2)... is there a simple command to get the instance index number?

I was thinking I could use instance_find() or id, but those just return the instance id and not the position in the instances array (if there is such a thing). Sorry if this is a dumb question, but I can't find it ANYWHERE!
 

king javo

Member
This is what I'm using now and it seems odd I need to loop through all instances to get the index...
Code:
for(var i = 0; i < instance_count; i++;)
{
    if (instance_id[i] == id)
    {
        my_index = i;
        show_debug_message(i);
        break;
    }
}
 

FrostyCat

Redemption Seeker
You really need to read my article on objects and instances.

Here is the immediately relevant part of the article:
Finding the right instance

As long as multiple instances of an object exists, referencing with an object ID alone will cease to work, so you must learn to find the one instance ID you want to work with. Here are some common situations.

...

Created or copied instance. instance_create() (GMS 1.x and legacy) / instance_create_layer() (GMS 2.x) and instance_copy() return the ID of the created or copied instance. NEVER use instance_nearest() to establish this relationship --- something else could be closer by.

Subsidiary instance(s). Same as created or copied instance. If the subsidiary instance needs to reference its creator, the creator should assign its instance ID to an instance variable in the subsidiary instance. Conversely, if the creator needs to reference its subsidiary (or subsidiaries), it must store the return value of instance_create() immediately. NEVER use instance_nearest() to establish or maintain this relationship --- being the closest does NOT imply being the most relevant, especially in close quarters.
According to the underlined parts, you need to remember the new instances as they are created. Since you have multiple subsidiary instances, store them in a multi-entry format such as an array.
Code:
var n = 11,
    radius = 50,
    dir = 0;
for (var i = 0; i < n; i++) {
  dir = i/n*360;
  orbiting_instances[i] = instance_create(x+lengthdir_x(radius, dir), y+lengthdir_y(radius, dir), obj_orbiting);
}
 

king javo

Member
You really need to read my article on objects and instances.

Here is the immediately relevant part of the article:


According to the underlined parts, you need to remember the new instances as they are created. Since you have multiple subsidiary instances, store them in a multi-entry format such as an array.
Code:
var n = 11,
    radius = 50,
    dir = 0;
for (var i = 0; i < n; i++) {
  dir = i/n*360;
  orbiting_instances[i] = instance_create(x+lengthdir_x(radius, dir), y+lengthdir_y(radius, dir));
}
Funny I just read your article while searching the forums. I'll review this now to see what I missed. Thanks!
 

king javo

Member
You really need to read my article on objects and instances.

Here is the immediately relevant part of the article:


According to the underlined parts, you need to remember the new instances as they are created. Since you have multiple subsidiary instances, store them in a multi-entry format such as an array.
Code:
var n = 11,
    radius = 50,
    dir = 0;
for (var i = 0; i < n; i++) {
  dir = i/n*360;
  orbiting_instances[i] = instance_create(x+lengthdir_x(radius, dir), y+lengthdir_y(radius, dir), obj_orbiting);
}
Makes sense, guess I just thought there was a built-in variable or function we could use inside GMS. Okay, this makes sense.
 
I would have done this, assuming this code would be in a different object from the ones forming the circle.

Code:
var _id=0;
var _inc = 360 / instance_number(obj_orbiters);
var _center_x= 50;
var _center_y=50;
var _radius = 20;
with(obj_orbiters)
{
  var _dir = _id*_inc;
  x= _center_x+lengthdir_x(_radius,_dir);
  y= _center_y+lengthdir_y(_radius,_dir);
  _id++;
}
 

king javo

Member
I would have done this, assuming this code would be in a different object from the ones forming the circle.

Code:
var _id=0;
var _inc = 360 / instance_number(obj_orbiters);
var _center_x= 50;
var _center_y=50;
var _radius = 20;
with(obj_orbiters)
{
  var _dir = _id*_inc;
  x= _center_x+lengthdir_x(_radius,_dir);
  y= _center_y+lengthdir_y(_radius,_dir);
  _id++;
}
I like it. Not sure why, but I'm having an issue moving my players towards their appropriate (x,y) coords in the circle. I'm using an if statement to check if distance <= speed and then move_towards_point, but it's not working right and the players don't move properly.

How would you guys move objects to a point and then stop?
 
I would use the "approach" script.

Code:
///approach(start, end, shift);

if (argument0 < argument1)
    return min(argument0 + argument2, argument1); 
else
    return max(argument0 - argument2, argument1);
Code:
x=approach(x,target_x,speed);
y=approach(y,target_y,speed);
 

king javo

Member
I would use the "approach" script.

Code:
///approach(start, end, shift);

if (argument0 < argument1)
    return min(argument0 + argument2, argument1);
else
    return max(argument0 - argument2, argument1);
Code:
x=approach(x,target_x,speed);
y=approach(y,target_y,speed);
I appreciate the help... So I have it working using your code for now. The one thing I want to improve is the players overlapping one another. I'm working with mp_potential_step_object but the players are hitting each other and never getting to their target spots. Anyone know of an easier function to collide and keep moving quickly towards spot or motion plan to avoid each other altogether?
 
Top