Faster way to tell if a sprite is near another sprite? - actionscript-3

When one of my sprites is being dragged (moved around), I'm cycling through other sprites on the canvas, checking whether they are in range, and if they are, I set a background glow on them. Here is how I'm doing it now:
//Sprite is made somewhere else
public var circle:Sprite;
//Array of 25 sprites
public var sprites:Array;
public function init():void {
circle.addEventListener(MouseEvent.MOUSE_DOWN, startDrag);
}
private function startDrag(event:MouseEvent):void {
stage.addEventListener(MouseEvent.MOUSE_MOVE, glowNearbySprites);
stage.addEventListener(MouseEvent.MOUSE_UP, stopDrag);
circle.startDrag();
}
private function stopDrag(event:MouseEvent):void {
stage.removeEventListener(MouseEvent.MOUSE_MOVE, glowNearbySprites);
stage.removeEventListener(MouseEvent.MOUSE_UP, stopDrag);
circle.stopDrag();
}
private function glowNearbySprites(event:MouseEvent):void {
for (var i = 0; i < sprites.length; i++) {
var tSprite = sprites.getItemAt(i) as Sprite;
if (Math.abs(tSprite.x - circle.x) < 30 &&
Math.abs(tSprite.y - circle.y) < 30) {
tSprite.filters = [new GlowFilter(0xFFFFFF)];
}
else {
tSprite.filters = null;
}
}
}
Basically I'm cycling through each sprite every time a MOUSE_MOVE event is triggered. This works fine, but the lag when dragging the sprite around is pretty noticeable. Is there a way to do this that is more efficient, with no or less lag?

Well, depending on the size of the amount of sprites you have, it may be trivial. However, if you're dealing with over 1k sprites -- use a data structure to help you reduce the amount of checks. Look at this QuadTree Demo
Basically you have to create indexes for all the sprites, so that you're not checking against ALL of them. Since your threshold is 30, when a sprite moves, you could place it into a row/column index of int(x / 30), int(y / 30). Then you can check just the sprites that exist in 9 columns around the row/column index of the mouse position.
While this would seem more cumbersome, it actually it way more efficient if you have more items -- the number of checks stays consistent even as you add more sprites. With this method I'm assuming you could run 10k sprites without any hiccup.
Other performance optimizations would be:
use an vector/array of sprites rather than getChildAt
preincrement i (++i)
store a static single instance glowfilter, so it's only one array, rather creating a separate filter for all the sprites.
GlowFilter is pretty CPU intensive. Might make sense to draw all the sprites together in one shot, and then apply GlowFilter once to it -- (this of course depends on how you have things set up -- might even be more cumbersome to blit your own bitmap).
Make your variable declaration var sprite:Sprite = .... If you're not hard typing it, it has to do the "filters" variable lookup by string, and not by the much faster getlex opcode.

I'd incorporate all the improvements that The_asMan suggested. Additionally, this line:
tSprite.filters = [new GlowFilter(0xFFFFFF)];
is probably really bad, since you're just creating the same GlowFilter over and over again, and creating new objects is always expensive (and you're doing this in a for loop every time a mouse_move fires!). Instead create it once when you create this class and assign it to a variable:
var whiteGlow:GlowFilter = new GlowFilter(0xFFFFFF);
...
tSprite.filters = [whiteGlow];
If you're still having performance issues after this, consider only checking half (or even less) of the objects every time you call glowNearbySprites (set some type of flag that will let it know where to continue on the next call (first half of array or second half). You probably won't notice any difference visually, and you should be able to almost double performance.

Attempting to compile the suggestions by others into a solution based on your original code, so far I've created the GlowFilter only once and re-used, secondly I've changed the loop to use a for each instead of the iterant based loop, third I've updated to use ENTER_FRAME event instead of MOUSE_MOVE. The only thing I've left out that's been suggested so far that I see is using a Vector, my knowledge there is pretty much nil so I'm not going to suggest it or attempt until I do some self education. Another Edit
Just changed the declaration of sprites to type Vector no code here for how it's populated but article below says you can basically treat like an Array as it has all the same method implemented but has a couple of caveats you should be aware of, namely that you cannot have empty spots in a Vector and so if that is a possibility you have to declare it with a size. Given it knows the type of the object this probably gets a performance gain from being able to compute the exact position of any element in the array in constant time (sizeOfObject*index + baseOffset = offset of item). The exact performance implications aren't entirely clear but it would seem this will always result in at least as good as Array times if not better.
http://www.mikechambers.com/blog/2008/08/19/using-vectors-in-actionscript-3-and-flash-player-10/
//Array of 25 sprites
public var sprites:Vector.<Sprite>;
private var theGlowFilterArray:Array;
public function init():void
{
theGlowFilterArray = [new GlowFilter(0xFFFFFF)];
circle.addEventListener(MouseEvent.MOUSE_DOWN, startDrag);
}
private function startDrag(event:MouseEvent):void
{
stage.addEventListener(MouseEvent.MOUSE_UP, stopDrag);
addEventListener(Event.ENTER_FRAME, glowNearbySprites);
circle.startDrag();
}
private function stopDrag(event:MouseEvent):void
{
stage.removeEventListener(MouseEvent.MOUSE_UP, stopDrag);
removeEventListener(Event.ENTER_FRAME, glowNearbySprites);
circle.stopDrag();
}
private function glowNearbySprites(event:Event):void
{
var circleX:Number = circle.x;
var circleY:Number = circle.y;
for each(var tSprite:Sprite in sprites) {
if (Math.abs(tSprite.x - circleX) < 30 && Math.abs(tSprite.y - circleY) < 30)
tSprite.filters = theGlowFilterArray;
else
tSprite.filters = null;
}
}

You problem is that making calculations that are at least linear O(n) on every mouse change event is terribly inefficient.
One simple heuristic to bring down the amount of times that you make your calculations is to save the distance to the closest sprite and only after mouse moved that distance would you recalculate the potential crash. This can be calculated in constant time O(1).
Notice that this works only when one sprite moves at a time.

Related

as3 - How to sort display objects that constantly switch depths?

I have a 2.5D game (2D game that acts like a 3D game) where you constantly switch depths, where the player displays on top of an object when it walks in front of it and when it walks behind it, the object displays on top of the player. Like when the player's y is less than the object's y, the player would be going behind the object and vice versa.
I tried to use a code like this:
if (player.y < block.y)
{
setChildIndex(block, numChildren - 5);
}
else if (player.y > block.y)
{
setChildIndex(block, numChildren - 10);
}
However, I see if I do it this way with multiple times, I would need tons of codes and the display list would get mixed up and sort the wrong depths in the wrong orders. Would anyone please show an organized depth changer with minimal code?
Use a z-index stack sorting, (also refered as z-buffer in the 3D graphics literature) the same used to create the 3D depth effect using just 2D techniques.
In other words assign to each object a zIndex and at regular intervals (e.g onEnterFrame event) run a zsort routine which sorts (the order of) display objects based on their zIndex value. Or, alternatively, you can run zsort routine manualy each time a change of zIndex happens on objects.
Then in your code you simply assign zIndex values to display objects to simulate an object passing in-front or behind another object and zsort takes care of the rest.
A trick here is to have appropriate gaps (i.e not necessarily next zIndex+1) in the values of zIndex assigned on objects, so that objects can be placed between these gaps to simulate passing in front or behind other objects, without having to adjust more than one zIndex value each time, i.e you adjust only one zIndex value of the object passing in-front or behind another object, and not the zIndex of that other object.
The amount of gap between successive zIndexes can be estimated from the maximum number of (other) objects which at any given time might be between these objects (so for example, if, at maximum, 3 objects might at some time move between, in-front or behind any given object, then a gap value for successive zIndexes would be 3 so that all the objects can be accomodated)
here is a very simple zsorter routine which runs periodicaly onEnterFrame event and does the necessary depth sorting for you (from reference 1. below)
package {
import flash.display.*;
import flash.events.*;
public class DepthSortSpace extends MovieClip {
public function DepthSortSpace() {
super();
this.addEventListener( Event.ADDED_TO_STAGE, this.addedToStage, false, 0, true );
}
private function addedToStage( e:Event ) {
this.stage.addEventListener( Event.ENTER_FRAME, this.enterFrame, false, 0, true );
}
private function sortDisplayList():void {
var len:uint = numChildren;
var i,j;
for( i=0; i < len-1; i++ )
for (j=i+1; j < len; j++)
if ( getChildAt(i).y > getChildAt(j).y ) this.swapChildrenAt( i, j );
}
private function enterFrame(e:Event) {
this.sortDisplayList();
}
}
}
The zsorter above is in-fact a movieClip which acts as a scene container, in that you add your display objects to the zsorter movieClip and this takes care to sort them accordingly, but one can just take the zsort routine and apply it to any DisplayObjectContainer or Scene object instance.
Note, the zsorter above uses a bubbleSort sorting algorithm, which has a O(n^2) complexity, but one can use another sorting algorithm (e.g mergeSort with O(n lgn) complexity)
examples and references
http://nephilim.blogspot.gr/2010/06/easy-depth-sorting-in-actionscript-3.html
http://www.actionscript.org/forums/actionscript-3-0-a/169035-sorting-technique.html
http://www.simppa.fi/blog/the-fastest-way-to-z-sort-and-handle-objects-in-as3/

need AS3 movieclip parent child related functions

hi i've taken on a new coding technique and its leaving me a little stranded, alot of concepts ive previously applied now take new syntax and sometimes create unforseen problems.
OK, so i make multiplayer flash games. In order to cut down on clutter i no longer use multiple class.as files, instead, i have my stage, and one library object called triggers, which i place just out of sight in the upper left of the stage. i then make a class.as file for this one movieclip object, and from there i instantiate everything else in my program - so far a login splash-screen movieclip, a game-window movieclip, a lobby movieclip, and finally the game-instance movieclip. these come in and out of .visible appropriately, and when not in use they are stored at off screen x and y values, they progress sequentially based on userinput. additionally i have public arrays which store importantMessages[], myplayerarray[], myArrowsarray[], myenemyarray[]
now my biggest issue at the moment is i'll recieve in from the server the variables i need to build a new arrow and monster unit -- so ill do like movieclip orc, with orc.speed, orc.xstartlocation orc.hp and so on, and ill have a similar arrow movieclip with arrow.speed, arrow.gravity, and so on. both of these movieclips, with added properties, are then pushed onto the appropriate public arrays, and not added to the stage, but instead, are added to the stage.add(gamewindow:Movieclip) (the reasoning behind this is so that later if i want to move everything on the stage at once, they are already oriented on a single cohesive movieclip, then i can just move this movieclip)
ok now onto the problem stuff, when i have two gamewindow.movieclips collide, like an arrow versus an orc (lets say arrow13 hittest orc42 == true) i remove the arrow movieclip object from the gamewindow:movieclip and splice it from its myarrowarray, however, even though the graphic dissapears, it continues to move its current trajectory and hit everything else on its way. I believe the reasoning behind this is because during the creation of the movieclip with its variables, i include an eventlistener on enterframe, i think its removing the clip but not the event listener (see very bottom for instantiated arrow Movieclip class)
so this brings me to my concise question:
QUESTION ONE:
is it possible to not only gamewindow.removeChild(arrow13) but also gamewindow.removeChild(arrow13[and all variables and eventlisteners at once])
QUESTIONTWO:
my second question is a bit easier: since switching to movieclip() instead of object() ive been using brute force, what would be a 1 line piece of code to do all of the following:
var newarrow:MovieClip = new playerarrow();
newarrow.theowner = username
newarrow.thespeed = speed
newarrow.thegravity = gravity
newarrow.thepower = power
newarrow.arrownumber = arrowid
and my third question goes back to my splashscreen movieclips idea, im having trouble playing around with thier z-values
basically when i call the importantmessage() its creates a new movieclip in the lower left, which alpha fades to 0 and it removes itself, however i have a problem where my new movieclip windows will overwrite these messages since they were added a split second after, the example in my program is i will have 2 messages spit out stage.add "attempting to connect to server" "connected" then the next major function is invoked and it instantiates the loginsplash:movieclip = new loginwindow -- i've tried taking this new stage.addchild(loginsplash) and do setChildIndex(loginsplash, 0) as well as -1 and 1. both 1's are out of bounds and 0 produces : The supplied DisplayObject must be a child of the caller.
QUESTION THREE:
so if i have gamemsg z = 0 gamemsg2 z = 1 and loginsplash z = (0?), how can i get the game messages to always lay on top ( i think its more of a referenceing problem then anything else
========================================
connection.addMessageHandler("newarrow",
function(m:Message, username, speed, gravity, power, arrowid)
{
var newarrow:MovieClip = new playerarrow();
newarrow.theowner = username
newarrow.thespeed = speed
newarrow.thegravity = gravity
newarrow.thepower = power
newarrow.arrownumber = arrowid
for each(var p in myplayerarray)
if (p.mpname == username){
newarrow.x = p.theanimation.x + 100
newarrow.y = p.theanimation.y + 100
}
myarrowarray.push(newarrow)
gw.addChild(newarrow)
newarrow.addEventListener(Event.ENTER_FRAME, arrowenterframe)
function arrowenterframe(e:Event){
newarrow.thegravity = 0 //+=.6
speed = 5
newarrow.x = newarrow.x+speed
newarrow.y = newarrow.y + newarrow.thegravity
//ROTATE FUNCTION
newarrow.rotation = Math.atan(newarrow.thegravity / speed ) /(Math.PI/180)
if (speed < 0) {newarrow.rotation +=180}
for each(var d in myenemyarray){
if (newarrow.hitTestObject(d.orcicon)){
connection.send("arrowhitmonster", newarrow.arrownumber, d.monsternumber)
trace("hitting monster")
}
}
if(newarrow.hitTestObject(gw.theground)){
}
}
})
Q1 ... is possible, but not with a single command. I would recommend you use the casalib (which I tend to recommend often) If you use CasaMovieClip instead of MovieClip, it extends it by adding some additional functions that deal with these issues like removeEventListeners() and removeAllChildrenAndDestroy()(which removes listeners). With the event listeners, just be aware that it destroys only events that this object is listening to, and not the listeners that other objects have to this mc. Instead of trying to convert assets to use CasaMovieClip, you could also just look at the code and implement it over top of your classes/MCs
Another alternative to dealing with event listeners is to switch to using signals by Robert Penner. It's a much more elegant way of working with event notifications, and by the sounds of your setup (relying on few classes with big reach), it might work better when all communication between objects is happening through a single channel rather than being handled by every object individually.
Q2 - you could create a factory function.
public function createMC($mc:MovieClip,$owner:String,$speed:int,...etc):MovieClip{
$mc.theowner = $owner;
// etc.
return $mc;
}
or
public function createMC($mc:MovieClip,$properties:Object):MovieClip{
$mc.theowner = $owner;
for (var $property:String in $properties)
if ($mc.hasOwnProperty($property))
$mc[$property] = $properties[$property];
return $mc;
}
where you call the function like this var newarrow:MovieClip = createMC(new playerarrow(), { theowner:username});
but I'm not sure why you would want to really
Q3 - the way I deal with these is set up movie clip holders. The critical messages will always be on top, the game menu bellow, the game background always on bottom. In the main view I would have a gameholder MC and above the menu and above that the criticalMessage holder, any objects that are added and removed are only within the appropriate holder.

move in move out tween animation for group of movieclips using as3

I have set of 6 movieclips as array_0 and another set of 6 movieclips as array_1. It is like two choices for different screens. Both these arrays are nested in another array as all_array. all 12 movieclips are positioned to a same x and y at initial load and that is outside the visible stage. I would like to use two different global variables for indexing. for example, cCat_Sel which ranges from 0-5 and another cScr_Sel ranges from 0-1. cCat_Sel will be changed on a click event of six buttons separate objects on stage (each button for each category).
so it will show the content for each category as per the value of cScr_Sel. if cScr_Sel is 0 then it will use all_array[0][cCat_Sel] to access the current target and similarly respective array for value of 1 as all_array[1][cCat_Sel]
I have done all the work including all tween animations to move current target and make it visible. But the tween does not bring the second set of mcs to visible area. I have two functions one for movein and one for move out by using tween animation for mc.x property. every relevant click event; I have to move current mc out and make alpha 0 and once that is finished, move in new current target and make alpha 1.
Somehow I have to combine these two tweens in one function. This is the part that I am stuck. or may be putting these mcs in two different arrays not a correct approach. I can easily achieve what I want on Enter Frame event of the root to check for cCat_Sel and cScr_Sel variables and do both animations one after the other but it seems like enter frame uses too much of cpu and makes it slower and probably not preferable.
willing to try anybody's suggestions or guidance. Thanks in advance.
I do not have any formal or informal programming education at all but I make things work by reading and trying out few things as per stackoverflow question and answers and sometime google. because most of my answers I have found from stack overflow.
Update:
function fnSlideInOut(cMc:Object, pMc:Object){
var HideX:Number =650;
var ShowX:Number = 0;
if(cMc != null){
if(cMc.x != ShowX){
//cMc.alpha = 1;
var SlideMcIn:Tween = new Tween(cMc, "x", Strong.easeOut, 650, ShowX, 0.5, true);
SlideMcIn.addEventListener(TweenEvent.MOTION_FINISH, fnSlideInFinish);
SlideMcIn.start();
}
}
if(pMc != null){
if(pMc.x != HideX){
//pMc.alpha = 1;
var SlideMcOut:Tween = new Tween(pMc, "x", Strong.easeOut, 0, HideX, 0.5, true);
SlideMcOut.addEventListener(TweenEvent.MOTION_FINISH, fnSlideOutFinish);
SlideMcOut.start();
}
}
function fnSlideOutFinish(e:TweenEvent){
//SlideMcOut.obj.alpha = 0;
SlideMcOut.removeEventListener(TweenEvent.MOTION_FINISH, fnSlideOutFinish);
}
function fnSlideInFinish(e:TweenEvent){
//SlideMcIn.obj.alpha = 1;
SlideMcIn.removeEventListener(TweenEvent.MOTION_FINISH, fnSlideInFinish);
}
}//End Function
fnSlideInOut(cScr_Sel, pScr_Sel);
I would like expert like you to comment on any kind of errors for the above code. It works 99 times but 1 time the movieclip either does not reach the destination or current and previous both targets showing and that too not where they are suppose to. This only happens when button click event happens in a quick succession. Thanks again
A option could be to use a third party library like TweenLite. It will then make it easy for you to run your second animation right after the first one is complete:
private function startAnimation():void
{
var mcToHide:MovieClip = all_array[cScr_Sel][cCat_Sel];
TweenLite.to(mcToHide, 1, {x: HIDDEN_X_POSITION, y:HIDDEN_Y_POSITION, alpha:0, onComplete:finishAnimation});
}
private function finishAnimation():void
{
var mcToShow:MovieClip = all_array[(cScr_Sel + 1) % 2][cCat_Sel];
TweenLite.to(mcToShow, 1, {x: VISIBLE_X_POSITION, y:VISIBLE_Y_POSITION, alpha:1});
}
You can then call startAnimation() on a relevant mouse click event and after having set cScr_Sel and cCat_Sel accordingly to your needs.

How can I optimise this method?

I have been working on creating an assets class that can generate dynamic TextureAtlas objects whenever I need them. The specific method is Assets.generateTextureAtlas() and I am trying to optimise it as much as possible as I quite frequently need to regenerate texture atlas's and was hoping to get a better time than my 53ms average.
53ms is currently costing me about 3 frames which can add up quickly the more items I need to pack inside my texture atlas and the frequency I need to generate them. So an answer to all the pitfalls within my code would be great.
The entire class code is available here in a github gist.
The RectanglePacker class is simply used to pack rectangles as close together as possible (similar to Texture Packer) and can be found here.
For reference, here is the method:
public static function generateTextureAtlas(folder:String):void
{
if (!_initialised) throw new Error("Assets class not initialised.");
if (_renderTextureAtlases[folder] != null)
{
(_renderTextureAtlases[folder] as TextureAtlas).dispose();
}
var i:int;
var image:Image = new Image(_blankTexture);
var itemName:String;
var itemNames:Vector.<String> = Assets.getNames(folder + "/");
var itemsTexture:RenderTexture;
var itemTexture:Texture;
var itemTextures:Vector.<Texture> = Assets.getTextures(folder + "/");
var noOfRectangles:int;
var rect:Rectangle;
var rectanglePacker:RectanglePacker = new RectanglePacker();
var texture:Texture;
noOfRectangles = itemTextures.length;
if (noOfRectangles == 0)
{
return;
}
for (i = 0; i < noOfRectangles; i++)
{
rectanglePacker.insertRectangle(Math.round(itemTextures[i].width), Math.round(itemTextures[i].height), i);
}
rectanglePacker.packRectangles();
if (rectanglePacker.rectangleCount != noOfRectangles)
{
throw new Error("Only " + rectanglePacker.rectangleCount + " out of " + noOfRectangles + " rectangles packed for folder: " + folder);
}
itemsTexture = new RenderTexture(rectanglePacker.width, rectanglePacker.height);
itemsTexture.drawBundled(function():void
{
for (i = 0; i < noOfRectangles; i++)
{
itemTexture = itemTextures[rectanglePacker.getRectangleId(i)];
rect = rectanglePacker.getRectangle(i, rect);
image.texture = itemTexture;
image.readjustSize();
image.x = rect.x + itemTexture.frame.x;
image.y = rect.y + itemTexture.frame.y;
itemsTexture.draw(image);
}
});
_renderTextureAtlases[folder] = new TextureAtlas(itemsTexture);
for (i = 0; i < noOfRectangles; i++)
{
itemName = itemNames[rectanglePacker.getRectangleId(i)];
itemTexture = itemTextures[rectanglePacker.getRectangleId(i)];
rect = rectanglePacker.getRectangle(i);
(_renderTextureAtlases[folder] as TextureAtlas).addRegion(itemName, rect, itemTexture.frame);
}
}
Well reading the project & finding what all can be optimized would sure take time.
Start by removing multiple calls to rectanglePacker.getRectangle(i) inside loops.
For example :
itemName = itemNames[rectanglePacker.getRectangleId(i)];
itemTexture = itemTextures[rectanglePacker.getRectangleId(i)];
rect = rectanglePacker.getRectangle(i);
perhaps, could have been:
rect = rectanglePacker.getRectangle(i);
itemName = itemNames[rect];
itemTexture = itemTextures[rect];
If getRectangle does indeed just 'get a rectangle' & not set anything.
I think the bigger issue at hand is this, why oh why do you HAVE to do this during run-time, in a situation when this can't take more time? This IS an expansive operation, no matter how much you optimize this you will probably end up with it taking about 40ms or similar when done in AS3.
This is why these kind of operations should be done during compile time or during "loading screens" or other "transitions" when frame-rate is not critical and when you can afford it.
Alternatively create another system in c++ or some other language which can actually handle the number-crunching that gives you the finished result.
Also, when it comes to checking performance, yes the entire function takes 53ms, BUT, where are those milliseconds used? 53ms says nothing and is only the "overhead profiling thing" where you found the culprit, you need to break it down into smaller chunks to gather some reliable information about what it is that ACTUALLY takes time, inside that function.
I mean, inside that function, you have 3 for loops, several calls to other classes, casts, deletes, creations. It's not like you are doing one thing, that function probably results in ~500 lines of code and a bazillion cpu operations. And, you have no idea where it is used. I would guess that it is the rectanglePacker.packRectangles(); that takes 60% of that time, but without profiling, you and we don't know on what to optimize, we simply don't have sufficient data.
If you HAVE to do this during run-time in AS3, I would recommend doing this spread out during several frames and distributing workload evenly during 10 frames or so. You could also doing it with help of another thread and workers. But most of all, this seems like a design error since this could probably be done at another time. And if not, then in another language which is better at these kind of operations.
The easiest way to profile this is to add a couple of timestamps similar to:
var timestamps:Array = [];
And then push getTimer() at different places in code, and then print them out when function is done
As others said, it's unlikely that the reason of bad performance is non-optimized AS code. Output from the profiler (Scout, for example) wold be very helpful. However, if your purpose is just adding new textures, I can suggest several optimizations:
Why would you need to re-generate the whole atlas every time (calling Assets.getTextures() and creating new render texture)? Why don't you just add new items to the existing atlas? Creation of a new RenderTexture (and, thus, a new texture in GPU memory) is very costly operation, because it requires sync between CPU and GPU. On the other hand, drawing into RenderTexture is carried out entirely inside GPU, so it takes much less time.
If you place every item on a grid, then you can avoid using RectanglePacker as all of your rectangles can have the same dimensions matching the dimensions of a grid.
Edit:
To clarify, some time ago I had a similar problem: I had to add new items to the existing atlas on a regular basis. And the performance of this operation was quite acceptable (about 8ms on iPad3 using 1024x1024 dynamic texture). But I used the same RenderTexture and the same Sprite object that contained my dynamic atlas items. When I need to add a new item, I just create new Image with desired texture (stand-alone or from another static atlas), then place it inside the Sprite container, and then redraw this container to the RenderTexture. Similarly with deletion/modification of an item.

Splicing elements out of a Vector in a loop which goes through the same Vector (ActionScript 3)

I'm making a simple game and have a Vector full of enemies in order to do hit-checking on them from my "laser" object (it's a space shmup). Every laser loops through the Vector and checks if it's occluding the hit circle. The problem lies in when one laser destroys an enemy, the rest of the lasers try to also check the same Vector, only to go out of bounds since the enemy's already been spliced out and it's changed the size of the Vector.
for each (var enemy:Enemy in enemies){
var distanceX = this.x - enemy.x;
var distanceY = this.y - enemy.y;
var distance = Math.sqrt( (distanceX*distanceX) + (distanceY*distanceY) );
if (distance <= enemy.hitRadius) {
enemy.removeEnemy();
enemies.splice(enemies.indexOf(enemy),enemies.indexOf(enemy));
}
}
How would I go about collecting the index of individual elements in the Vector to be deleted, then only deleting them when every Laser object is finished its checking?
edit: here's my removeEnemy() function from my Enemy class, just in case:
public function removeEnemy(){
removeEventListener(Event.ENTER_FRAME, move);
parent.removeChild(this);
trace("removed Enemy", enemies.indexOf(this));
}
edit edit: I'm also getting a null reference pointer error to "parent" in my removeEnemy() function... but only sometimes. I have a feeling that if I fix one of these two problems, the other will also be fixed but I'm not sure.
I fixed it! The problem was actually in how I used the "splice()" method. Turns out that the second parameter isn't the end index of where to stop splicing, it's the number of elements to be spliced. So when I was trying to splice element 0, I wasn't splicing anything, and when I was trying to splice element 3, I was also splicing 4 and 5. I feel like such a dunce for not reading the API right and wasting a couple hours on this. Thanks to everyone who commented-- you guys helped me rule out what I thought the problem was.