1. Hello Guest! It's with a heavy heart that we must announce the removal of the Legacy GMC Archive. If you wish to save anything from it, now's the time! Please see this topic for more information.
    Dismiss Notice

instance_nearest() same objects solution?[SOLVED]

Discussion in 'Programming' started by CROmartin, Jan 13, 2018.

  1. CROmartin

    CROmartin Member

    Joined:
    Jul 17, 2016
    Posts:
    83
    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!
     
  2. Simon Gust

    Simon Gust Member

    Joined:
    Nov 15, 2016
    Posts:
    3,221
    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.
     
    CROmartin likes this.
  3. CROmartin

    CROmartin Member

    Joined:
    Jul 17, 2016
    Posts:
    83
    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: Jan 13, 2018
  4. Simon Gust

    Simon Gust Member

    Joined:
    Nov 15, 2016
    Posts:
    3,221
    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).
     
    CROmartin likes this.
  5. JFitch

    JFitch Member

    Joined:
    Sep 28, 2016
    Posts:
    428
    What if you change the instance to something else using instance_change, then run instance_nearest, then use instance_change to change it back?
     
  6. Surgeon_

    Surgeon_ Symbian Curator

    Joined:
    Jun 22, 2016
    Posts:
    248
    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).
     
    CROmartin likes this.
  7. JFitch

    JFitch Member

    Joined:
    Sep 28, 2016
    Posts:
    428
    I like your idea better than mine.
     
    CROmartin likes this.
  8. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    7,142
    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.
     
    CROmartin likes this.
  9. CROmartin

    CROmartin Member

    Joined:
    Jul 17, 2016
    Posts:
    83
    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!

     
  10. BattleRifle BR55

    BattleRifle BR55 Member

    Joined:
    Jun 24, 2016
    Posts:
    996
    Yes, it would. You only move the calling instance.

    Code:
    x += 10000;
    var nearest = instance_nearest(x-10000,y,object);
    x -= 10000;
     
  11. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    7,142

    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: Jan 14, 2018
    CROmartin likes this.
  12. CROmartin

    CROmartin Member

    Joined:
    Jul 17, 2016
    Posts:
    83
    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.
     
  13. BattleRifle BR55

    BattleRifle BR55 Member

    Joined:
    Jun 24, 2016
    Posts:
    996
    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.
     
  14. CROmartin

    CROmartin Member

    Joined:
    Jul 17, 2016
    Posts:
    83
    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?
     
  15. BattleRifle BR55

    BattleRifle BR55 Member

    Joined:
    Jun 24, 2016
    Posts:
    996
    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.
     
    CROmartin and Surgeon_ like this.
  16. CROmartin

    CROmartin Member

    Joined:
    Jul 17, 2016
    Posts:
    83
    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.
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice