Nearest instance?

0 favourites
  • When I mention an object in another object's field (e.g. move towards object), if there are multiple instances of the second object, it does not pick the nearest instance but a seemingly random one.

    Why does this happen? Could a feature be implemented to make the nearest instance be chosen (since I am sure that 99% of the time people would want this).

    If this is unavoidable, what can I do to make the object choose the nearest instance?

    thanks, sqiddster

  • I agree, that would be a very useful function. Seems strange that it's not already available, got used to that in Game Maker <img src="smileys/smiley17.gif" border="0" align="middle" /> quite easy to implement as a plugin but would be better to be in the main built-in System object.

  • There was an option in CC "Pick closest", in C2 it's not yet added (hope it will).

    You can do it in many ways. Ie. add a instance variable "pick" or whatever and them compare that value to what you want to do.

  • Picking the nearest object would slow down games a lot - instead of taking the first picked (which seems to you to be random), it would have to check every single instance measuring its distance. If you have 100 object instances, that's 100 times as much work, and it affects every single condition!

    You can add a for-each loop yourself to test each individual instance's distance. I'll see if I can add a 'pick closest' for the next build.

  • Picking the nearest object would slow down games a lot - instead of taking the first picked (which seems to you to be random), it would have to check every single instance measuring its distance. If you have 100 object instances, that's 100 times as much work, and it affects every single condition!

    You can add a for-each loop yourself to test each individual instance's distance. I'll see if I can add a 'pick closest' for the next build.

    Damn iterations!! An idea I might use is to have some kind of list/array of all specified objects and an associated distance to whatever target then use min(a,b,c...) to find the the smallest distance or max(a,b,c...) to find the largest distance or maybe an array/list which sorts itself as objects are added from smallest to highest then you can pick the first for nearest and last for furthest. Each has its pros and cons but there's a few ways to do it whilst trying to keep away from the iterations... <img src="smileys/smiley5.gif" border="0" align="middle" />

    I tend to think of the most complicated way of doing something so there's probably simpler methods.

  • Yes, there must be simpler way to pick the closest instance! I caertainly need this and there is quite a lot of instances, too. hmm...

  • Have a collision mask a moderate distance around the player object, if any of the other objects overlap it do a for loop of those objects only. That means that even if a level has 100 objects, it may only pick 5 of them.

    However, if none of the objects overlap that object then a full for loop is probably needed =/

  • A couple of subevents makes it fairly easy. You don't need an array - just two values for 'closest so far' and 'closest UID'. Local variables would be good for those. The algorithm works like this:

    1. Set 'closest so far' to a large number e.g. 999999, and 'closest UID' to -1.

    2. For each object:

    ---a) if the distance to this object is less than 'closest so far':

    -----> set 'closest so far' to the distance to this object

    -----> set 'closest UID' to this object's UID

    3. Pick object with UID = 'closest UID'

    ---> do something with this instance - it's the closest

  • Would a loop going from a point out on both sides be quicker than 0 to w/h?

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • I thought about a box slowly expanding from the center and checking if x and y coordinates of other objects are within that box. The downside is if the nearest object is far away. Either way, you have to iterate.

  • A couple of subevents makes it fairly easy. You don't need an array - just two values for 'closest so far' and 'closest UID'. Local variables would be good for those. The algorithm works like this:

    1. Set 'closest so far' to a large number e.g. 999999, and 'closest UID' to -1.

    2. For each object:

    ---a) if the distance to this object is less than 'closest so far':

    -----> set 'closest so far' to the distance to this object

    -----> set 'closest UID' to this object's UID

    3. Pick object with UID = 'closest UID'

    ---> do something with this instance - it's the closest

    Combine this with jayjay's idea of having a large invisible square/circle object (collision mask) so you pick only the objects within it/overlapping it, then you wouldn't have to worry about having lots of objects to iterate through. Unless you needed the range to be really big then this would be pointless as you would have to iterate through all objects anyway.

  • No, the range is relatively small.

    However, this UID and looping is part of what is confusing to me about construct. SO what am I to do? A large invisible circle around the object? I am still a bit confused.

  • I think the best way (since so many people would need this) would be for the function to be built into the program and able to be optionally used.

  • No, the range is relatively small.

    However, this UID and looping is part of what is confusing to me about construct. SO what am I to do? A large invisible circle around the object? I am still a bit confused.

    Every object has unique ID (UID) in Construct and is used to select a specific object (no two objects have the same UID). Of all the ways to do it you will still have to loop through all objects you want to test the distance to. To optimise this and make it faster you would need to make sure you do the bare minimum with events to each object only focusing on the objects that matter. So:

    Use paint or whatever to draw a square say 320x320 pixels in size (or whatever the largest distance is you want to check) fill it pink or whatever (doesn't matter), set this as a new object call it rangeCollisionBox or whatever, set opacity to 80 just so you can see whats through it. Set this objects visibility to "invisible" you don't want to see it when you run the program. Setup the events so that every "tick" the rangeCollisionBox is positioned at the players position or do this every time you want to check the nearest object.

    Next, do a "for each" on every object you're checking the distance to then add a sub event underneath this which checks whether the objects are overlapping the rangeCollisionBox. If they are then perform Ashley's algorithm on each of these.

    I'm not 100% sure this is right and 100% sure it makes sense as I can't test at the moment. I hope it helps <img src="smileys/smiley5.gif" border="0" align="middle" /> I'll see if I can knock up a capx tonight.

    Edit: If Ashley made the nearest function and it used his method you could still use a collision box to filter the objects.

  • A .capx would be nice... they are always very informative!

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)