I need some help to do a code that returns me the nearest enemy in the screen. The enemeis are stored in an array, and i need to check in realtime who is the nearest from the hero.
I did a code but i am prety sure that there is a much better (read fast =]) method to do this.
The code:
Code:
function getNearestEnemy(hero:Object){
var tempArray = new Array();
for(var i=0;i<enemiesArray.length;i++){
var a = Math.abs(hero.x - enemiesArray[i].x)
var b = Math.abs(hero.y - enemiesArray[i].y)
var hip = Math.ceil(Math.sqrt((a*a)+(b*b)))
tempArray[hip] = enemiesArray[i]
}
tempArray.sortOn("", Array.NUMERIC);
return tempArray[0].id
}
basically it creates a new array, calculates the distance and sort the array so the first value is the smaller one. Then it returns the id of the object.
i would apreciate if someone could give me a light, because this function is REALLY painfull for flash, it slowdown a lot the movie when called =P
function getNearestEnemy(hero:Object) {
var nearestDist = 9999999;
var nearest = undefined;
for (var i = 0; i<enemiesArray.length; i++) {
var a = Math.abs(hero.x-enemiesArray[i].x);
var b = Math.abs(hero.y-enemiesArray[i].y);
var hip = Math.ceil(Math.sqrt((a*a)+(b*b)));
if (hip<nearestDist) {
nearestDist = hip;
nearest = enemiesArray[i];
}
}
return nearest;
}
Just starts the nearest distance as a very large number, then if an enemy is found to be nearer it sets that distance as the nearestDist and marks the enemy as nearest. Once the loop is done, whichever enemy is marked as nearest is the closest one.
Classic optimisation - get rid of the square root function if you don't care what the distance is, just which is closest. You don't really need any of the Math functions to be honest, certainly don't need the Math.abs. Don't forget also, if you can get away with it, you might want to try updating this every few frames instead of every frame. Even better, spread it over several frames, instead of all at once every several frames (spread the load). One last one - if you could make sure you keep/cache the array sorted (not throw it away) then future sorts might be faster.
I second jonmack, losing the sqrt call is a huge performance increase and costs you nothing. Additionally, you can use this distance check as the first part of your collision detection check. Just assume both the origin and the destination point have a radius, add their radius' together and then square the results. Then, if distance is less then the new number, they are close enough for hit test (or they are touching directly, depends on your radius size). This is the trick I use in the little open source game I've been building in stages.