GM:S 1.4 [SOLVED]Instance nearest

Discussion in 'Programming' started by Andrea N, Jun 11, 2018.

  1. Andrea N

    Andrea N Member

    Joined:
    Apr 4, 2018
    Posts:
    37
    Hi all,
    I have one object enemy and more object player (multiplayer game).
    Obj_enemy have to follow the nearest player, but only if a variable of obj_player is true. For example inside obj_player variable "follow_me"= true or false.
    Now i have to check from obj_enemy step event:
    If instance_exists(obj_player){
    If (obj_player.follow_me == true){
    player_to_follow=instance_nearest(x,y,obj_player);
    move_towards_point(player_to_follow.x,player_to_follow.y,speed);}
    Else{player_to_follow=0;
    Obj_enemy.speed=0;}
    }else{player_to_follow=0;
    Obj_enemy.speed=0;}

    When obj_enemy is following obj_player, and i change the obj_player.follow_me variable, obj_enemy stops to follow obj_player, and it's ok! But if obj_player are more than one, i need to follow the other obj_player.follow_me = true; !
    How can i find the instance_nearest(x,y,obj_player.follow_me==true)???
    I hope i explained myself, thanks
     
  2. MIchael PS

    MIchael PS Member

    Joined:
    Aug 12, 2017
    Posts:
    95
    Just do that:

    Code:
    If instance_nearest(obj_player).follow_me == true
        {
            ...
        }
    EDIT: Oh I actually misunderstood what you asked for! Sorry...
     
    Last edited: Jun 11, 2018
  3. Simon Gust

    Simon Gust Member

    Joined:
    Nov 15, 2016
    Posts:
    3,174
    It's not that easy unfortunately.
    You can use a with statement to go through every player object, check if their follow variable is true, then find the nearest one.
    Code:
    var player_to_follow = noone;
    var distance = 1000000000;
    var xx = x;
    var yy = y;
    
    with (obj_player)
    {
        if (follow_me)
        {
            var my_dis = point_distance(x, y, xx, yy);
            if (my_dis < distance)
            {
                player_to_follow = id;
                distance = my_dis;
            }
        }
    }
    
    if (player_to_follow != noone)
    {
        var player_x = player_to_follow.x;
        var player_y = player_to_follow.y;
        var spd = min(point_distance(x, y, player_x, player_y), 3.0); 
        move_towards_point(player_x, player_y, spd);
    }
    
    I also advise reading this
    https://forum.yoyogames.com/index.php?threads/with-block-recipe-cards.25326/
    and this
    https://forum.yoyogames.com/index.php?threads/whats-the-difference-objects-and-instances.29005/
     
  4. Carl Nylander

    Carl Nylander Member

    Joined:
    Jul 21, 2016
    Posts:
    212
    if you ganna use instance_nearest you need to deactivate the instance in a loop.
    something like this, I'm in my phone so I'm not 100% about the syntax

    while true {
    o = instance_nearest(x,y,obj_player)
    if o == noone || o.follow_me == true {
    break
    } else {
    deactivate_instance(o)
    }
    }
    activate_all(obj_player)
    if o != noone {
    //follow
    }
     
  5. Andrea N

    Andrea N Member

    Joined:
    Apr 4, 2018
    Posts:
    37

    I tried your script and i added some changes:

    if (instance_exists(obj_player)){
    var player_to_follow = noone;
    var distance = 500;
    var xx = x;
    var yy = y;
    var enemyRoom = npcRoom;

    with (obj_player)
    {
    var my_dis = point_distance(x, y, xx, yy);

    if (enemyRoom == playerRoom)
    {
    if (my_dis > distance)
    {
    player_to_follow = noone;
    }
    else
    {
    if (my_dis < distance)
    {
    player_to_follow = id;
    //distance = my_dis;
    }
    }
    }
    }


    if (player_to_follow != noone)
    {
    var nearest_player_to_follow = instance_nearest(x,y,player_to_follow);
    //var player_x = nearest_player_to_follow.x;
    //var player_y = nearest_player_to_follow.y;
    //var spd = min(point_distance(x, y, nearest_player_to_follow.x, nearest_player_to_follow.y), 1);
    move_towards_point(nearest_player_to_follow.x, nearest_player_to_follow.y, 1);
    npcxx=x;
    npcyy=y;
    }
    else{x=npcxx;
    y=npcyy;}
    }

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    I added the line "var nearest_player_to_follow = instance_nearest(x,y,player_to_follow);" because with your script, when i have more than one player near the obj_enemy and both obj_player have "my_dis < distance",(so both obj_player have "player_to_follow = id;") ,
    if obj_enemy is following obj_player(1) and another obj_player(2) running, and the last become the nearest, obj_enemy stops to move until obj_player(1) comes back to be the nearest obj_player!

    So i thought to use "instance_nearest"! But i get an error:

    FATAL ERROR in
    action number 1
    of Step Event0
    for object obj_npc:

    Variable <unknown_object>.y(1, -2147483648) not set before reading it.
    at gml_Object_obj_npc_StepNormalEvent_1 (line 35) - move_towards_point(nearest_player_to_follow.x, nearest_player_to_follow.y, 1);

    But i use this :
    if (player_to_follow != noone)
    { .....code.....}

    So, why this error??
     
  6. Andrea N

    Andrea N Member

    Joined:
    Apr 4, 2018
    Posts:
    37
    Thanks, but i need the instances always active so i can't use this
     
  7. Andrea N

    Andrea N Member

    Joined:
    Apr 4, 2018
    Posts:
    37
    Yes i can do as you wrote, like this:

    var player_to_follow = instance_nearest(x,y,obj_player);
    if (player_to_follow.playerRoom == npcRoom){move_towards_point(player_to_follow.x, player_to_follow.y, 1);}

    BUT, if the "instance_nearest(x,y,obj_player) have variable "playerRoom != npcRoom", I have to discard it, and i have to find the nearest obj_player ONLY IF it have "playerRoom = npcRoom";

    Do you understand now?
     
    MIchael PS likes this.
  8. Carl Nylander

    Carl Nylander Member

    Joined:
    Jul 21, 2016
    Posts:
    212
    Deactivating and activate a instance in the same code wont affect the game in anyway.
    The only problem it can cause is if you do other stuff with deactivating instance which can collide with this code.
    But you can fix that by adding them to a list and then activate every instance in that list when you're done.
     
  9. Andrea N

    Andrea N Member

    Joined:
    Apr 4, 2018
    Posts:
    37
    Thanks, your solution works perfectly, but there must be another way, and i hope to find it!
     
  10. Carl Nylander

    Carl Nylander Member

    Joined:
    Jul 21, 2016
    Posts:
    212
    instance_nearest simply return the nearest instance. you can't do any other checks directly with that function. you can either (as I showed) deactivate the instance to return a new instance the next time you run the function, or move the instance away (x += 999999) to also return a new instance then move back all the found instances (X -= 999999).

    or you would have to make up your own system as @Simon Gust showed. which is probably the better choice since it only have to check each instance once. instance_nearest have to check all instances once for every time it run.
     

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