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

instance_nearest() same objects solution?[SOLVED]

C

CROmartin

Guest
Good day folks!
While programing I stumbled on this problem which is that instance_nearest() takes in count object that runs code. I use this function in content of collision solving, but that dosen't matter. I have in mind few solutions but they are not best and fast to write, so I thought why not ask you folks do you have any bypass solution for instance_nearest() ignoring obj that runs code?
Yeah I know, I am lazy :p ...
Thanks in forward!
 

Simon Gust

Member
As you suspected, you have to write your own function.
You loop through all instances and compare their distance.
Code:
var max_distance = 0;
var farthest = id;

with (object_index)
{
    var distance = point_distance(other.x, other.y, x, y);
    if (distance > max_distance)
    {
        max_distance = distance;
        farthest = id;
    }
}

if (farthest != id)
{
   // rest of the code here
   
}
Now, the variable farthest holds the id for the farthest away instance of the same object.
 
C

CROmartin

Guest
Hi again Simon Gust!
I am taking a grasp of it, but still I don't understand fully how code behaves in with function, so code runs between with brackets as much as there are other object_index in room? If it is like that and if it other functions in that way that only take value of other object_index in room then I think I have solution for closest object, check it out :

var min_distance = 5000; /// Object cant be further then this number
var closest = id;

with(object_index)
{
var distance = point_distance(other.x,other.y,x,y);
if (distance < min_distance)
{
min_distance = distance;
closest = other.id;
}

}
What do you think will it work? Did I miss understand with function?
Sir thank you on help!
 
Last edited:

Simon Gust

Member
A with function goes into every instance of the object (provided with object_index here) and it will act like the code block is actually in that instance. That means you can just access the instance's variable all you like.
If a put an "other" before a variable it takes it from where the code is actually in (the instance that performs the check in the first place).
However, temporary variables (the ones made with var) are a different scope and can be accessed just like that.

Now to the code:
you first set a distance to as close as possible (minimum distance) and any instance farther than minimum distance is the farthest away until another instance proves the previous instance wrong by being even farther away.
This works both way with far and near. Except you have to make a large starting number (like you did).
The only mistake now is that you are setting closest to other.id, meaning you set closest to the same instance running the code.
Just use id since you are in that instance (because with loop).
 
J

JFitch

Guest
What if you change the instance to something else using instance_change, then run instance_nearest, then use instance_change to change it back?
 

Surgeon_

Symbian Curator
What if you change the instance to something else using instance_change, then run instance_nearest, then use instance_change to change it back?
Even easier, you can just set the x and y coordinates to something really far away before the check and restore them afterwards (you'll need to to check the returned id though, if the instance running the code is alone, it will be selected regardless).
 
J

JFitch

Guest
Even easier, you can just set the x and y coordinates to something really far away before the check and restore them afterwards (you'll need to to check the returned id though, if the instance running the code is alone, it will be selected regardless).
I like your idea better than mine.
 

TheouAegis

Member
Can't remember if it works, but store x and y in local vars, deactivate the calling instance, then find the nearest. Reactivate the calling instance and carry on, my wayward son.
 
C

CROmartin

Guest
Surgeon_ that would mean you will you teleport all instance obj_enemy and on the end it would not work.
JFitch you just changed obj_enemy in something else that means that they wont find them self.
TheouAegis it shouldnt work because you deactivated object wont run code, it would work if we make other object that spawns with obj_enemy and follows his coordinates then when obj_enemy is deactivated it stores instance_nearest and then activates obj_enemy and sends stored var.

Guys thank on help but this is already solved by Simon Gust(I needed to change it little bit because still didn't store well id, but logic was fine), I forgot to mark it as solved.

Guys thanks on help once again!

 

TheouAegis

Member
TheouAegis it shouldnt work because you deactivated object wont run code, it would work if we make other object that spawns with obj_enemy and follows his coordinates then when obj_enemy is deactivated it stores instance_nearest and then activates obj_enemy and sends stored var.

Actually it does work. You're forgetting the one fundamental rule of Game Maker: all code is run until the end of the event. I hadn't forgotten, but I wasn't too sure about it with deactivation.

Code:
show_message(instance_nearest(x,y,all));
show_message(id);
That will show the same value both times.

Code:
instance_deactivate_object(id);
show_message(instance_nearest(x,y,all));
instance_activate_object(id);
show_message(id);
That will show a different value each time.

Just because an object has been deactivated, it doesn't mean it doesn't exist. It just means any function which inherently checks if an object has been deactivated will fail. The difference between a destroyed object and a deactivated object is the destroyed object has its variables cleared, so you can't read from a destroyed object; a deactivated object keeps all its variables and is in fact still accessible even outside the current event. The instance_nearest() call will check if the instance has been deactivated; the deactivation state will not be checked again until the next event runs.

You can even access a deactivated instance's variables as long as you know the id of the instance. But you still couldn't bypass the inherent checks. So instance_nearest(x,y,id) would return -4 if you deactivated the calling instance first. However, this code would work:

Code:
var inst = instance_nearest(x,y,object1);
instance_deactivate_object(object1);
with all x+=32;
inst.x += 8;
instance_activate_object(object1);
That will move the nearest instance of object1 because the id is prefixed rather than the object_index.

As far as which is faster, I dunno. Compared to Simon's, the second code here (sans show_message() calls) should be faster.
 
Last edited:
C

CROmartin

Guest
Yes, it would. You only move the calling instance.

Code:
x += 10000;
var nearest = instance_nearest(x-10000,y,object);
x -= 10000;
Yes but I call every obj_enemy because every need nearest enemy, code will execute in same time in every obj_enemy so none of them will be on place.. do I missing something here?

TheouAegis yep good job, you prove it. I always thought that deactivation exit events, my bad. Well I learned something new thanks.
 
Yes but I call every obj_enemy because every need nearest enemy, code will execute in same time in every obj_enemy so none of them will be on place.. do I missing something here?.
How would code all execute at the same time? Anything made in GameMaker would be utter chaos during execution if events could be interrupted as you seem to think may happen by association.
 
C

CROmartin

Guest
How would code all execute at the same time? Anything made in GameMaker would be utter chaos during execution if events could be interrupted as you seem to think may happen by association.
Listen your code says to teleport obj_enemy for 1000 pixels and then to check instance_nearest for obj_enemy on the position before teleporting, but in that moment every obj_enemy isnt on their true position. That means none of them will get true instance_nearest but rather instance_nearest on "fake" positions. Is it clear now?
 
Listen your code says to teleport obj_enemy for 1000 pixels and then to check instance_nearest for obj_enemy on the position before teleporting, but in that moment every obj_enemy isnt on their true position. That means none of them will get true instance_nearest but rather instance_nearest on "fake" positions. Is it clear now?
What? You are completely misinterpreting what is going on. This is what the code actually does:

The calling instance moves away 10,000 pixels to the right.
instance_nearest() checks the position the instance was just at (x-10,000) to see which instance of the same object type is closest to this old position.
The calling instance moves 10,000 pixels to the left, back to its original position.

instance_nearest() merely checks for the closest given instance to a specific set of coordinates. If you don't want the calling instance to be involved, you must ensure it is by far not the closest by temporarily moving it vastly out of the game field. That is all these three lines are doing. I don't know where you're getting the idea that every enemy is being moved and stuff is being checked before teleporting. Only the calling instance moves and the check is after the teleportation.
 
C

CROmartin

Guest
BattleRifle BR55 I thought your code wont work because when you run game maker program it seems that everything happens in same time but firstly created objects have advantage, I totally forgot on that. Thanks on help.
 

huenix

Member
Hi again Simon Gust!
I am taking a grasp of it, but still I don't understand fully how code behaves in with function, so code runs between with brackets as much as there are other object_index in room? If it is like that and if it other functions in that way that only take value of other object_index in room then I think I have solution for closest object, check it out :

var min_distance = 5000; /// Object cant be further then this number
var closest = id;

with(object_index)
{
var distance = point_distance(other.x,other.y,x,y);
if (distance < min_distance)
{
min_distance = distance;
closest = other.id;
}

}
What do you think will it work? Did I miss understand with function?
Sir thank you on help!

did you ever get this to work???
 
C

CROmartin

Guest
did you ever get this to work???
@huenix yes I did, most simple solution is to save x and y in var then set x and y out of collision range( basically just a high number), second you write down instance_nearest function with x and y coordinates that you prestored in local variable, third you again set x and y coordinates to value you stored local variables.
GML:
var xx,yy;
xx = x;
yy = y;
x = x+10000;
y = y+10000;

instance_nearest(xx,yy,objectName);
x = xx;
y = yy;
If you want me to explain you this specific case that @Simon Gust wrote down I can also do that, but code up there will serve the purpose.
 
Top