PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197

PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197

PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197

PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197
[RESOLVED] Remove children error
A Flash Developer Resource Site

Results 1 to 11 of 11

Thread: [RESOLVED] Remove children error

  1. #1
    Member
    Join Date
    Nov 2009
    Posts
    33

    resolved [RESOLVED] Remove children error

    Hey Everyone,

    I'm trying to remove a child of a Sprite in actionscript, where each of the children are stored in arrays as well as holder sprite, as that seemed to easiest way to go about things. The arrays are then looped through for each of the children.

    However, often while testing my game, I get an error:
    ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller.
    at flash.display::DisplayObjectContainer/removeChild()
    at TowerDefence_fla::MainTimeline/moveBullets()
    at TowerDefence_fla::MainTimeline/everyFrame()


    my moveBullets function is:
    Actionscript Code:
    function moveBullets():void {
        for each (var bullet in bulletArray) {
            //if (bullet.bulletType = ...)
            bullet.y += bullet.ySpeed;
            bullet.x += bullet.xSpeed;
            bullet.stageTime += 1;
            for each (var enemy in enemyArray) {
                if (bullet.hitTestObject(enemy)) {
                    enemy.health -= bullet.damage;
                    if (enemy.health <= 0) {
                        enemyHolder.removeChild(enemy); //error here :C
                        enemyArray.splice(enemyArray.indexOf(enemy), 1);       
                    }
                    bulletHolder.removeChild(bullet);
                    bulletArray.splice(bulletArray.indexOf(bullet), 1);
                }
            }
            if (bullet.stageTime > bullet.range / bullet.speed) {
                bulletHolder.removeChild(bullet);
                bulletArray.splice(bulletArray.indexOf(bullet), 1);
            }
        }
    }

    I can't figure out why this happens. When it does happen, the Array is spliced fine because the enemy stops moving.

    Another problem I have had is that when I remove the child like that, the loop runs for 1 less time then it should, so sometime the enemies or bullets pause for a frame. What's the best way to get around this. It's possible the problems are related.

    Any help would be appreciated. Thank you!

  2. #2
    Junior Member
    Join Date
    Dec 2010
    Posts
    18
    I think you should work with an e.target instead of having it removeChild(enemy) since you have more then just 1 I guess?

    I'm not really pro at this stuff and I suggest you to wait for some usefull post XD, but if you can make such a thing I guess you understand what I mean with the target.

  3. #3
    ___________________
    Join Date
    May 2004
    Posts
    3,174
    you've got a few problems there. to start, you're removing the bullet a bunch of times - once for each enemy in the inner loop, then once more in the outer loop. and, after it's removed the first time, you're going to get that error since it doesn't exist in the caller's display list after that, despite multiple calls to removeChild. the easy fix is just to test to make sure it's in the display list before attempting to remove it:

    PHP Code:
    if(parentElement.contains(childElement)) parentElement.removeChild(childElement); 
    that said, i'd make some other changes as well. not sure why you have need the arrays at all - but assuming there is a valid reason, instead of trying to manipulate them in the loop (which is going to cause problems - the array you're iterating through is potentially being changed during each iteration - it's quite likely you're going to 'miss' some elements). i'd reconstruct the array based on the child population, outside the loop.

    PHP Code:
    function moveBullets():void {

        for 
    each (var bullet in bulletArray) {
        
            
    bullet.+= bullet.ySpeed;
            
    bullet.+= bullet.xSpeed;
            
    bullet.stageTime += 1;
            
            for 
    each (var enemy in enemyArray) {
                if (
    bullet.hitTestObject(enemy)) {
                    
    enemy.health -= bullet.damage;
                    if (
    enemy.health <= 0) {
                        if(
    enemyHolder.contains(enemy)) enemyHolder.removeChild(enemy);      
                    }
                    if(
    bulletHolder.contains(bullet)) bulletHolder.removeChild(bullet);
                }
            }
            
            if (
    bullet.stageTime bullet.range bullet.speed) {
                if(
    bulletHolder.contains(bullet)) bulletHolder.removeChild(bullet);
            }
            
        }

        
    // iterator...
        
    var i:int;

        
    // rebuild the enemyArray based on whatever hasn't been removed
        
    enemyArray = [];
        for(
    i=0;i<enemyHolder.numChildren;i++){
            
    enemyArray[i] = enemyHolder.getChildAt(i);
        }

        
    // rebuild the bulletArray based on whatever hasn't been removed
        
    bulletArray = [];
        for(
    i=0;i<bulletHolder.numChildren;i++){
            
    bulletArray[i] = bulletHolder.getChildAt(i);
        }


    that's assuming you need the arrays at all - from what's posted, there's no need - you can just run through the children of bulletHolder and enemyHolder.

    hth
    Last edited by moagrius; 12-09-2010 at 11:11 AM.

  4. #4
    Member
    Join Date
    Nov 2009
    Posts
    33
    Ok, I can see why the error is occuring. I guess could also just try breaking the from the loop after it's removed the first time.

    Also, when I was posting I felt kinda silly explaining how I was using Arrays, and when I thought about it, I didn't really need them. I'll probably get rid of them.

    So, when I'm looping through the Sprites, I guess I should use something like:
    Actionscript Code:
    var i:int = 0;
    for(i=0;i<enemyHolder.numChildren;i++){
    seeing as I'll be removing those children inside the loop?

    I think I tried something like that once while trying to fix the problem, but I was unsure if it was really a good way to go about things.


    Anyway, thanks! I kinda felt like there were some major problems with what I was doing. It's good to finally have an idea of how to fix it. C:

  5. #5
    ___________________
    Join Date
    May 2004
    Posts
    3,174
    actually, you may want to keep the arrays and just rebuild as i demo'ed...

    the problem with this:

    PHP Code:
    for(var i:int=0;i<container.numChildren;i++){
      if(
    someConditioncontainer.removeChild(container.getChildAt(i));

    is that the removed children will affect where the next child is, as well as numChildren. say that there were 5 children total, and the loop qualified to remove the child at 2... so the child at position 3 would then move down to position 2, but the next loop iteration would still be i=3, so it'd actually 'skip' that child. there are ways to get around it (pass the children qualified to be removed to an local ('temporary') array by reference (rather than index), then loop through that local array and remove all those that qualified. or, you could just keep your arrays and make sure not to modify them until you're done processing them, as shown above.

    hth

  6. #6
    Member
    Join Date
    Nov 2009
    Posts
    33
    Ok yeah.

    Just one last question:

    With the above situation, would something like:
    Actionscript Code:
    for(var i:int=container.numChildren ;i>0;i-=1){
      if(someCondition) container.removeChild(container.getChildAt(i));
    }
    work, or would the positions of the children mean it would still skip some of them?

  7. #7
    Member
    Join Date
    Nov 2009
    Posts
    33
    ...or what about
    Actionscript Code:
    for(var i:int=0;i<container.numChildren;i++){
      if(someCondition) {
        container.removeChild(container.getChildAt(i));
        i -= 1;
      }
    }

  8. #8
    ___________________
    Join Date
    May 2004
    Posts
    3,174
    the first one wouldn't, but the second one might - give it a try on something simple first and see what happens

  9. #9
    Member
    Join Date
    Nov 2009
    Posts
    33
    Ok, I'll stop asking you questions now.

    Thanks for all your help. C:

  10. #10
    ___________________
    Join Date
    May 2004
    Posts
    3,174
    sorry - didn't mean to be short - i'm just slammed this week with pre-holiday deadlines... i'll check back on those when i get a minute, maybe this weekend

  11. #11
    Member
    Join Date
    Nov 2009
    Posts
    33
    don't worry, I was just kinda thinking that I'm making you do all the testing for stuff that I could do myself.

    I was just interested in asking you in case you already knew.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center