Forums

ForumsProgramming Forum

[Intermediate]Calculate Closest Enemy

Posted May 27, '14 at 1:58am

weirdlike

weirdlike

588 posts

Knight

For those of you who haven't been following along, take a peek at this demo HERE

var enemyArray:Array = new Array();

function enterFrameLoop(event):void
{
    var closestEnemy:Number = 25000000;
    for (var i:int = 0; i < enemyArray.length; i++)
    {
        var currentEnemy:Object = enemyArray[i];
        var dist:Number = Math.pow(hero.x-currentEnemy.x,2)+Math.pow(hero.y-currentEnemy.y,2);

        if (dist < closestEnemy)
        {
            closestEnemy = dist;

            //use currentEnemy for whatever you want
        }
    }
}


last edited May 28 2014 07:33 pm by weirdlike
 

Posted May 27, '14 at 6:32am

KentyBK

KentyBK

555 posts

Considering you don't really need the euclidean distance specifically, why don't you just compare dist² instead? It saves you the potentially expensive square root when you have a ton of enemies.

 

Posted May 27, '14 at 9:22am

weirdlike

weirdlike

588 posts

Knight

You've peaked my interest. Would you care to elaborate on that?

 

Posted May 27, '14 at 10:09am

KentyBK

KentyBK

555 posts

Sure, let me try.

See, for your function, you don't necessarily need to calculate the exact distance between objects. All you really need, is a value that's small for close enemies and large for enemies that are far away.

Keeping this in mind, you notice that you don't need to use the sqrt-operation, because Math.pow(hero.x-currentEnemy.x,2)+Math.pow(hero.y-currentEnemy.y,2) alone is still going to be small for close objects and big for far-away objects.

Mind you, if you need to use the exact distance for something else later on, you'd use your example. But just to test which object is closest, the square root is not needed.

 

Posted May 27, '14 at 11:20am

weirdlike

weirdlike

588 posts

Knight

tested and it does work, one thing to note tho is the max distance to check for will have to be increased in order to keep the same range.

Here are the results:

var original:Number = Math.sqrt(Math.pow(hero.x-currentEnemy.x,2)+Math.pow(hero.y-currentEnemy.y,2));

var new:Number = Math.pow(hero.x-currentEnemy.x,2)+Math.pow(hero.y-currentEnemy.y,2);

180.47636964433872 - original
32571.719999999987 - new

http://i.imgur.com/CPRuQ9v.jpg

Thanks for the tip @KentyBK I will have to do some more testing to see the full effect.

 

Posted May 27, '14 at 1:17pm

KentyBK

KentyBK

555 posts

Then I suggest using 25,000,000 as the max, i.e 5000².

I mean, if you're comparing without the square root, it only makes sense to square the range instead.

 

Posted May 28, '14 at 7:40pm

weirdlike

weirdlike

588 posts

Knight

Well it would appear that I was able to increase the max enemy amount on my game there by about 20 units by eliminating that extra bit.

Edited the original post ;)

 

Posted May 30, '14 at 11:31am

mightybob

mightybob

353 posts

Hey, this is some neat stuff!

I turned it into a function, here's an example:
http://pastebin.com/MyR90zDb

 

Posted Jun 8, '14 at 10:47am

nuwbie

nuwbie

9 posts

You can make it slightly faster by doing this and save on one iteration: (Although trivial gain)

        var currentEnemy:Object = enemyArray[i];

    var closestEnemy:Number =  Math.pow(hero.x-currentEnemy.x,2)+Math.pow(hero.y-currentEnemy.y,2);

    for (var i:int = 1; i < enemyArray.length; i++)
    {
        currentEnemy:Object = enemyArray[i];
        dist:Number = Math.pow(hero.x-currentEnemy.x,2)+Math.pow(hero.y-currentEnemy.y,2);

Although in larger scale applications where you are dealing in the thousands or even millions, you need to index and make grids on the map.

 
Reply to [Intermediate]Calculate Closest Enemy

You must be logged in to post a reply!