A few years ago, I released an AS2 version of ProximityManager class, which allows you to efficiently track the proximity of large numbers of sprites. You can read a full description of the approach and uses here.
In the last month a couple of people have left comments indicating that they were having difficulty porting it to AS3. This prompted me to port it and do some significant optimizations. The new class runs a lot faster than the original, and is worth taking a quick look at in comparison with the AS2 version even if you don't use it in a project.
Optimizations:
- removed two-dimensional arrays (which are very inefficient, especially in AS3) in favor of using a single array using an aggregate x/y index. The aggregate index is assembled with bit operators to make it even more efficient.
- added a simple caching mechanism, so that subsequent calls to getNeighbor for the same grid position do not need to recalculate the results
- used a Dictionary instance to hold managed items, which makes it much more efficient to remove objects on the fly.
- took full advantage of types and casting
- other minor tweaks
I thought I would recreate the same demo as in my original post to see how it performed. It has five times as many sprites (600 vs 120), and ten times as many connections (~2800 vs ~280), despite the main bottleneck in this demo being the graphics performance. I benchmarked it without graphics, and it seems handle a couple thousand sprites quite easily.
You can grab the source code for the demo and the ProximityManager class here.
Comments (12)
The second link isn't working. misspelled href!
Posted by: Tim at January 4, 2008 02:54 PMURL:
Very cool though
Posted by: Tim at January 4, 2008 02:58 PMURL:
Fixed. Thanks for the heads up Tim!
Posted by: Grant Skinner at January 4, 2008 03:08 PMURL: http://gskinner.com/blog/
Great work Grant. I just ported over your AS2 version to AS3 only a couple days ago. I'm glad to see the update and that this new class is more optimized than the previous version.
Thanks again for the release!
Posted by: Seth at January 4, 2008 08:38 PMURL:
[quote]Fixed. Thanks for the heads up Tim![/quote]
um... not quite!
Posted by: dAN at January 5, 2008 02:04 AMURL:
You absolute legend! I've been waiting for an upgrade to this class for ages. This class is going to be so useful! Thanks!
Posted by: Vyper at January 5, 2008 05:30 AMURL: http://www.fatal-exception.co.uk
Thank you! Thank you! Thank you!
-t.
Posted by: Timbot at January 5, 2008 08:54 AMURL:
dAN / Tim - fixed for sure this time. Not sure why Moveable Type didn't publish the change the first time. *shrug*
All - glad people are finding this useful. I'd love to see what it gets used for. Cheers.
Posted by: Grant Skinner at January 5, 2008 02:51 PMURL: http://gskinner.com/blog/
I was looking for something like that. Thanks.
Posted by: Simon at January 24, 2008 05:05 PMURL:
It would be nice to see an example that combines this and hittesting. For example, when in proximity, hittest between neighbors to see if they're touching (for odd shapes sprites/movieclips). I tried something like:
if (neighbor.y > sprite.y) {
if (sprite.hitTestPoint(neighbor.x, neighbor.y, true)){ }
}
But this didn't seem to work correctly.
Posted by: Seth at February 1, 2008 12:37 PMURL: http://ssandler.wordpress.com
Great job. In the sample you could add some alpha channel when the sprites are farer away and the alpha gets smaller when they are closer. This would give a nice effect. And gravity or springing between the sprites would be great too. I think it is calld "i don't know more who's" garden
Posted by: Pedro at March 5, 2008 07:51 AMURL:
If this is as useful as it appears then: THANK YOU VERY MUCH :D
I was just grimacing at the idea of tracking collisions for all these items but convinced myself it was worth looking for ideas online. I don't usually use other peoples' code outright, fear of not knowing what's going on I suppose, but I think this warrants it.
If you're ever in Sheffield, UK and feel thirsty, give me a shout :)
Posted by: Martin Lyne at August 10, 2008 03:56 PMURL: