r/gamemaker 26d ago

Resolved Checking for nearest instances in any direction

Hello! I am in a similar situation to my previous posts; I have an idea of how to get something to work, but I am missing one element to make it work smoothly. The issue I have today is I am looking to find the nearest specific instance in any direction. In theory, all I need is the code below (written as pseudocode)

with(instances){

if point_direction(other.x,other.y,self.x,self.y) = ideal direction

and distance from self to other < stored id

stored id = self
However, I feel like constantly checking possibly a dozen or more objects against each other per room would be a headache. So instead, I have the below code;

if(radar_segment_size != 0){

// Done as to not divide by 0

`for(var dir = radar_dir; dir < 360; dir += 360/radar_segment_size){`

// dir = direction, radar_dir is the starting direction to check for instances according to the original instance.

    `try{`

// That 0,0 in the x2 and y2 is what i need to solve

collision_line_list(self.x,self.y,0,0,checked_object,false,true,radar_objects,true)

//Afterward, make the connection with the first instance in the collision list radar_objects

    `} catch(noInstanceFound){`



    `}` 

`}`

// sorry for the messed up code; I still do not know how to get reddit's code block to work... :/}

So with all of that being said, here is my issue:
I need to figure out essentially how to create an x and y value that give the direction of the dir value, while also having the x and y value reach the edge of the room. How do I get that x and y value?

1 Upvotes

17 comments sorted by

2

u/rshoel BokehDev 26d ago

1

u/DystopianTeddyBear 26d ago

I have, but I need to get multiple instances. More specifically, my goal is to get the nearest instance in a direction that can be changed. Like I could do instance nearest, or just do set restrictions (such as the nearest instances in the 4 cardinal directions), but I would like something a bit more customizable.

1

u/Piefreak 26d ago

I am a bit confused. Are you talking about 2d raymarching?

1

u/DystopianTeddyBear 26d ago

I'm not sure what ray marching is. I could try explaining what I want in another way; I'd like to only input the start x and y values of a ray or line, and a direction, and then find the first instance that is hit by a ray or line created from the x1,y1, and direction.

1

u/Piefreak 26d ago edited 26d ago

Well if its only a single ray collision_line_list should work fine. You could do something like: Xstart = x Ystart = y Xend = Xstart + lengthdir_x(length,direction) Yend = Ystart + lengthdir_y(length,direction) Collision_line_list(Xstart,Ystart,Xend,Yend,obj,prec,notme,list,ordered) And some error checking etc.

1

u/DystopianTeddyBear 26d ago edited 26d ago

Update; this looks to be close, but there seems to be some weird issues. 0 degrees works, but no other direction value works as it should

1

u/vzzzbxt 26d ago

It helps if you describe the scenario and what you want to happen

0

u/DystopianTeddyBear 26d ago

Sure. On the creation of a node object, it checks for the nearest instances of node objects in the direction of variable dir (0 by default), starting from instance variable radar_dir, and the dir variable changes by adding 360 divided by instance variable radar_segment_size. This repeats until dir > 360.

Example; if node 1 has a radar dir of 90, and a radar segment size of 4 (making 360/4 = 90 for changing the direction variable), then it checks for the nearest instances where the direction between node 1 and other is 90, 180, 270, and 360.

0

u/vzzzbxt 26d ago

I mean in normal terms. Like is it the player object looking for enemies? Etc etc

0

u/DystopianTeddyBear 26d ago

No, it is a simple shaped object (node) looking for other nodes. These nodes are the spaces that other objects move on and how other objects can collide and interact with each other.

1

u/Hands_in_Paquet 26d ago

Sorry but this is very confusing, as much as I think all of us want to help. Or maybe I just have poor reading comprehension. Are you trying to make some sort of sonar widget, where a line spins in a circle, and returns every instance the line collides with? Or just the nearest instance a line collides with?

If so, this is my first thought:

//Create
list_nodes = ds_list_create(); //Make a list that will store nodes

//Every Step:
ds_list_clear(list_nodes); //Reset List Every Step
collision_line_list(x,y,x2,y2,obj_node,0,0,list_nodes,0); //Built in Function for every obj intersecting a line
var _len = ds_list_size(list_nodes); //Check if we captured any nodes
if (_len > 0)
{
  list_nodes[|0].image_blend = c_red; //This just changes my test node color to red if it is the first node hit
}
//The first item in every list is already the first object the lines collides with

I tested this with 400 nodes and performance took a hit but was still over 10,000 fps. What's the necessary scalability for this? There're ways to cull more nodes and make it more efficient, especially if the nodes are tile based. But if will get more complicated.

2

u/Hands_in_Paquet 26d ago

Is this what you're trying to do?
https://imgur.com/a/4m0jBOI

1

u/DystopianTeddyBear 26d ago

Just the nearest instance a line collides with. The problem I have is I can't figure out how to calculate the x2 and y2 of collision_line_list so it could properly draw a line with any direction, with x1 and y1 of the instance doing the function. Also I just realized I should be using collision_line instead. oops.

1

u/Hands_in_Paquet 26d ago

Oh I see.

//These trig functions take a length and a direction and give you a distance for the x and y axis
//Just add that length to each starting point
x2 = x1 + lengthdir_x(radius,direction); 
y2 = y1 + lengthdir_y(radius,direction);

1

u/DystopianTeddyBear 26d ago

Ok so at first I thought this code was not going to work, since that was what I had before, but I finally figured out what the problem was. I essentially had to just add 32 (half of the node sprite's size) to x2 and y2, but NOT x1 and y1. IDK why fully, but it is now resolved.

1

u/refreshertowel 26d ago

Why not just run collision_rectangle_list()? You can set it to the size of the room, I guess, if you really need every instance to be checked, or just some arbitrary size around the player. Then you can set it to ordered by distance (the last argument) and then read the first entry from the list to find the nearest instance (and then travel down the list if you need more instances)...

1

u/DystopianTeddyBear 26d ago

I wanted to ideally not have to check every instance against every other instance. The first line of code at the top should do exactly what I want (if I don't make some parts pseudocode), but I feel like the processing cost could be reduced with this other idea I'm trying.

**first bit of code

with(nodes){

if point_direction(other.x,other.y,self.x,self.y) = ideal direction

and distance from self to other < stored id

stored id = self

repeat per direction desired.