Legacy GM [SOLVED] Find the nearest object to the left/right

Hello!

I'm trying to figure out a way to find the nearest enemy (obj_enemy), but only in the direction you are facing. (This is a 2D sidescroller for context).

If you are facing right, all the enemies to the left of you may as well not exist. The code only needs to find the nearest instance that also exists to the right, even if the enemy is above or below you vertically. (And vice-versa for the left).


I've searched the forums, but a lot of the solutions are for 360 games.
Any ideas?
 
Well, any time you want to do some sort of comparison of all objects of a specific type, that's a good time to use the "with()" function.

You first would need some variables you can use inside of the with. Set these up as "var"s so that they work in and out of the with statement.
Code:
var _x = x; //your current position.
var _y = y;
var _facing = 1; //1 for right, -1 for left.
var _closest = noone //this will hold the ID of the object that ends up being the closest.
var _closest_dist = 100000 // the distance we will use to compare each object to.  If it's closer to the player than this, it will replace this value with its distance.
Then just do the with statement.

Code:
with(obj_enemy)
{
   var _dir = sign(_x-x); //subtract my x from the player's x and get the sign of that value, which will be a 1 or -1 (most likely)
   if(sign == _facing) //Check to see if it's in the direction the player is facing.
   {  //If so, let's check the distance.
      var _dist = point_distance(x,y,_x,_y);
      if(_dist < closest_dist)
      {
          _closest = id;
          _closest_dist=_dist;
      }
   }
}

if(closest != noone)
{
   //do something with the closest enemy in the given direction
}
Disclaimer... I didn't test this code. So it might not work perfectly. You could also use other.x and other.y instead of the vars to get to your object's x and y position from with in the with statement. If you aren't familiar with with statements, look them up in the manual.
 
J

JFitch

Guest
Code:
target=noone
target_dist=(some very large number)
with obj_enemy{
if point_distance(x,y,other.x,other.y)<other.target_dist && sign(x-other.x)=other.facing
{
other.target=id
other.target_dist=point_distance(x,y,other.x,other.y)
}
}
This assumes that "facing" is a variable that's set to 1 for facing right and -1 for facing left.
 
Code:
target=noone
target_dist=(some very large number)
with obj_enemy{
if point_distance(x,y,other.x,other.y)<other.target_dist && sign(x-other.x)=other.facing
{
other.target=id
other.target_dist=point_distance(x,y,other.x,other.y)
}
}
This assumes that "facing" is a variable that's set to 1 for facing right and -1 for facing left.
JFitch, I just tried this and it works perfectly. Thank you!


Well, any time you want to do some sort of comparison of all objects of a specific type, that's a good time to use the "with()" function.

You first would need some variables you can use inside of the with. Set these up as "var"s so that they work in and out of the with statement.
Code:
var _x = x; //your current position.
var _y = y;
var _facing = 1; //1 for right, -1 for left.
var _closest = noone //this will hold the ID of the object that ends up being the closest.
var _closest_dist = 100000 // the distance we will use to compare each object to.  If it's closer to the player than this, it will replace this value with its distance.
Then just do the with statement.

Code:
with(obj_enemy)
{
   var _dir = sign(_x-x); //subtract my x from the player's x and get the sign of that value, which will be a 1 or -1 (most likely)
   if(sign == _facing) //Check to see if it's in the direction the player is facing.
   {  //If so, let's check the distance.
      var _dist = point_distance(x,y,_x,_y);
      if(_dist < closest_dist)
      {
          _closest = id;
          _closest_dist=_dist;
      }
   }
}

if(closest != noone)
{
   //do something with the closest enemy in the given direction
}
Disclaimer... I didn't test this code. So it might not work perfectly. You could also use other.x and other.y instead of the vars to get to your object's x and y position from with in the with statement. If you aren't familiar with with statements, look them up in the manual.
Pixelated_Pope, I did get to briefly try this code. It did have some errors and I had almost sorted through them when JFitch posted his solution. Thank you none the less!
 
Well, any time you want to do some sort of comparison of all objects of a specific type, that's a good time to use the "with()" function.

You first would need some variables you can use inside of the with. Set these up as "var"s so that they work in and out of the with statement.
Code:
var _x = x; //your current position.
var _y = y;
var _facing = 1; //1 for right, -1 for left.
var _closest = noone //this will hold the ID of the object that ends up being the closest.
var _closest_dist = 100000 // the distance we will use to compare each object to.  If it's closer to the player than this, it will replace this value with its distance.
Then just do the with statement.

Code:
with(obj_enemy)
{
   var _dir = sign(_x-x); //subtract my x from the player's x and get the sign of that value, which will be a 1 or -1 (most likely)
   if(sign == _facing) //Check to see if it's in the direction the player is facing.
   {  //If so, let's check the distance.
      var _dist = point_distance(x,y,_x,_y);
      if(_dist < closest_dist)
      {
          _closest = id;
          _closest_dist=_dist;
      }
   }
}

if(closest != noone)
{
   //do something with the closest enemy in the given direction
}
Disclaimer... I didn't test this code. So it might not work perfectly. You could also use other.x and other.y instead of the vars to get to your object's x and y position from with in the with statement. If you aren't familiar with with statements, look them up in the manual.
--------------------------------------------------------------------
Hi Pixelated Pope. I know you replied to this thread a long time ago, but I wondered if you (or someone else) could explain to me why this code works (I'm still a relative beginner at coding, especially when it comes to "with" statements).

I used the code Pixelated Pope posted (the only bug, I THINK, was that he wrote "if(sign == _facing)" instead of "if(_dir == facing)") and it worked for my game. Basically I am making a puzzle where you can move pieces around the screen, and pressing left or right selects the nearest piece in that direction (if any). As I said, I got this code working for me, but I don't understand WHY it's working. I get that you're checking if a given instance's distance is less than some huge number (_closest_dist = 100000) but how does this code determine which instance is actually the closest? For example, why does only the closest instance pass the check for "is my distance from the player less than this huge number" and not other instances that are also less than the huge number? Can you understand my question?

Hope to hear from someone!
 

NightFrost

Member
For example, why does only the closest instance pass the check for "is my distance from the player less than this huge number" and not other instances that are also less than the huge number? Can you understand my question?
What the with() loop does is go through all the instances of the given object and compare their relative distance with the current closest_dist. So, every time an instance that is closer is found, it replaces the information, and once every instance has been checked, you will have the one that is the closest.
 
Thank you @NightFrost for explaining it to me :) I'm going to try to figure out now, why this code works when I'm selecting puzzle pieces to the right, but not when I'm selecting them to the left (it skips to the farthest one, rather than selecting the closest one).
 
Top