0

I'm trying to make a simple game in Flash. So far, I've added a bunch of objects to the stage using addChild(objName);. However, now I'm trying to remove the objects completely. I don't want to have to cycle through every object's name and I'm sure there must be a more efficient way to select each object (maybe by index on the stage) and removeChildAt(index); it. However, when I try this, Flash only removes the objects that were manually placed by me on the stage. It doesn't remove the ones that were placed through code. I've done some searching and I tried multiple methods, all of which yield the same result. The one that most people agree on is this one:

while (numChildren > 0) 
{
   removeChildAt(0);
}

Can you help me figure out why this isn't removing anything that was coded onto the stage?

Thanks in advance :D

Edit: Here is my code for the frames:

Frame 1 (Randomly generates and displays the dots):

import flash.events.MouseEvent;
import fl.motion.easing.Linear;

var dotList = new Array(); var level:int = 3; var invisoDotList = new Array();
var loop:int;
var line:Line = new Line();
line.x = 274;
line.y = 187;
addChild(line);
for(loop = 0; loop < level; loop++)
{
    var dot:Dot = new Dot();
    var invisoDot:InvisoDot = new InvisoDot();
    var tester:Boolean = true;
    var xval:int = Math.floor(Math.random()*(1+520))+14;
    var looper:int = 0;
    while(looper < dotList.length)
    {
        if(Math.abs(xval - dotList[looper].x) > 30)//minimum spacing
        {
            looper++;
        }
        else
        {
            looper = 0;
            xval = Math.floor(Math.random()*(1+520))+14;
        }
    }
    dot.x = xval;
    dot.y = 187;
    invisoDot.x = xval;
    invisoDot.y = 187;
    invisoDot.alpha = 0;
    dotList[loop] = dot;
    invisoDotList[loop] = invisoDot;
    addChild(invisoDot);
    addChild(dot);
}
//trace(dotList); test to ensure that dots are added to the array
var nb1:NextButton = new NextButton();
nb1.x = 0;
nb1.y = 0;
nb1.alpha = 0;
addChild(nb1);
nb1.addEventListener(MouseEvent.CLICK, hideDots);

function hideDots(e:MouseEvent)
{
    for(var loop:int = 0; loop < dotList.length; loop++)
    {
        dotList[loop].alpha = 0;//make dots disappear
    }
    line.alpha = 0;
    nextFrame();
}
stop();

Frame 2 (Displays further instructions and contains a couple of methods that will be used later on):

import flash.events.MouseEvent;
removeChild(nb1);
var nb2:NextButton = new NextButton();
nb2.x = 0;
nb2.y = 0;
nb2.alpha = 0;
addChild(nb2);
nb2.addEventListener(MouseEvent.CLICK, next);

function next(e:MouseEvent)
{
    nextFrame();
}
function clearStage()
{
    while (numChildren > 0) 
    {
        trace("before" + numChildren);
        removeChildAt(0);
        trace("after" + numChildren);
    }
}
stop();

Frame 3 (Makes the dots disappear when they are clicked and keeps an accuracy count):

import flash.events.MouseEvent;
import flash.utils.Timer;
line.alpha = 1;
removeChild(nb2);
//setChildIndex(line,0);
var clicks:int = -1;
var passed:int = 0;
var fromLine:Boolean = false;
//trace(dotList.length);
stage.addEventListener(MouseEvent.CLICK, clickCount);
for(var loopvar:int = 0; loopvar < dotList.length; loopvar++)
{
    //trace("loop");
    dot = dotList[loopvar];
    invisoDot = invisoDotList[loopvar];
    dot.addEventListener(MouseEvent.CLICK, onClick);
    invisoDot.addEventListener(MouseEvent.CLICK, onClick);
    //trace("event");
}
//trace(dotList.length);
function onClick(e:MouseEvent)
{
    //e.currentTarget.alpha = .5;
    for(var hitcheck:int = 0; hitcheck < dotList.length; hitcheck++)
    {
        if(dotList[hitcheck].x == e.currentTarget.x)
        {
            dotList[hitcheck].alpha = 1;
        }
    }
    //trace("check");
}
var numChanged:int = 0;
function clickCount(e:MouseEvent)
{
    clicks++;
    //trace(clicks);
    numChanged = 0;
    for(var index:int = 0; index < dotList.length; index++)//check whether the user has gotten all the dots
    {
        if(dotList[index].alpha == 1)
        {
            numChanged++;
        }
    }
    if(numChanged == level)//if the user has gotten all the dots
    {
        /*trace("next screen for sucess");
        trace(clicks);*/
        line.visible = false;
        for(loop = 0; loop < dotList.length; loop++)
        {
            dotList[loop].alpha = 0;//make dots disappear
        }
        if((clicks - level) == 1)
        {
            passed = 2
        }
        else if((clicks - level) == 0)
        {
            passed = 1;
        }
        passed = 1;
        fromLine = true;
        nextFrame();
    }
    else if((clicks - numChanged) >= 2)//this ends the session as soon as 2 mistakes are made
    {
        /*trace("next screen for failed number of clicks");
        trace(clicks);*/
        line.visible = false;
        for(loop = 0; loop < dotList.length; loop++)
        {
            dotList[loop].alpha = 0;//make dots disappear
        }
        passed = 3;
        fromLine = true;
        nextFrame();
    }
    /*else if((clicks - level) >= 2)//if the user has made too many mistakes. This ends the session after the maximum number of tries have been used
    {
        trace("next screen too many clicks");
        trace(clicks);
    }*/

}
//trace("end");
stop();

Frame 4 (Generates the results table. A sidenote: there is a bug where "Okay" is never a result because in Frame 3, the value of passed never equals 2. Not sure why though):

import flash.text.TextFormat;
import flash.text.TextField;

var failFormat:TextFormat = new TextFormat();
failFormat.color = 0xFF0000;
failFormat.font = "Arial";
failFormat.size = 18;
var passFormat:TextFormat = new TextFormat();
passFormat.color = 0x00FF00;
passFormat.font = "Arial";
passFormat.size = 18;
var okayFormat:TextFormat = new TextFormat();
okayFormat.color = 0x808000;
okayFormat.font = "Arial";
okayFormat.size = 18;
var normalFormat:TextFormat = new TextFormat();
normalFormat.color = 0x000000;
normalFormat.font = "Arial";
normalFormat.size = 18;

var lineResults = new Array();
var squareResults = new Array();
trace(passed);
if(fromLine == true)
{
    if(passed == 1)
    {
        lineResults[lineResults.length] = "Pass";
    }
    else if(passed == 2)
    {
        lineResults[lineResults.length] = "Okay";
    }
    else if(passed == 3)
    {
        lineResults[lineResults.length] = "Fail";
    }

}
fromLine = false;
lineResults = lineResults.reverse();
squareResults = squareResults.reverse();
var loopLength:int = (lineResults.length >= squareResults.length) ? lineResults.length : squareResults.length;
var loopStart:int = 0;
if(loopLength > 11)
{
    loopStart = loopLength - 12
}
var cb:CellBlock = new CellBlock();
cb.x = 283.05;
cb.y = 20.35;
addChild(cb);
var col1Head:TextField = new TextField();
col1Head.defaultTextFormat = normalFormat;
col1Head.text = "# of Dots";
col1Head.x = 114.95
col1Head.y = 8.3;
addChild(col1Head);
var col2Head:TextField = new TextField();
col2Head.defaultTextFormat = normalFormat;
col2Head.text = "Line";
col2Head.x = 259.95
col2Head.y = 8.3;
addChild(col2Head);
var col3Head:TextField = new TextField();
col3Head.defaultTextFormat = normalFormat;
col3Head.text = "Square";
col3Head.x = 381.95
col3Head.y = 8.3;
addChild(col3Head);

for(loop = loopStart; loop < loopLength; loop++)
{
    var block:CellBlock = new CellBlock();
    block.x = 283.05;
    block.y = 20.35 + (loop - loopStart + 1)*33;
    addChild(block);
    var col2:TextField = new TextField();
    var col3:TextField = new TextField();
    var col1:TextField = new TextField();
    /*col2.defaultTextFormat = passFormat;
    col3.defaultTextFormat = okayFormat;*/
    col1.defaultTextFormat = normalFormat;
    switch(lineResults[loop])
    {
        case "Pass":
        col2.defaultTextFormat = passFormat;
        break;
        case "Okay":
        col2.defaultTextFormat = okayFormat;
        break;
        case "Fail":
        col2.defaultTextFormat = failFormat;
        break;
    }
    switch(squareResults[loop])
    {
        case "Pass":
        col3.defaultTextFormat = passFormat;
        break;
        case "Okay":
        col3.defaultTextFormat = okayFormat;
        break;
        case "Fail":
        col3.defaultTextFormat = failFormat;
        break;
    }
    //col2.text = "Pass";
    col2.text = lineResults[loop];
    col2.x = 260.95;
    col2.y = block.y - 12;
    addChild(col2);
    //col3.text = "Okay";
    try
    {
        col3.text = squareResults[loop];
    }
    catch(e:Error)
    {

    }
    col3.x = 386.95;
    col3.y = block.y - 12;
    addChild(col3);
    col1.text = String(loop + 1);
    col1.x = 133.95;
    col1.y = block.y - 12;
    addChild(col1);
}
var nb4:NextButton = new NextButton();
nb4.x = 0;
nb4.y = 0;
nb4.alpha = 0;
addChild(nb4);
nb4.addEventListener(MouseEvent.CLICK, clearStage);
stop();

Frame 5 (Next frame which is a test to make sure that everything gets erased, which it doesn't):

removeChild(nb4);
stop();
8
  • 2
    The above code is right. Perhaps the container that you dynamically added the objects to is not the same container that you're trying to remove them from. Try tracing out the value of numChildren before/after the while loop to confirm. Commented Jun 1, 2013 at 3:20
  • I'll try that and see what happens. Thanks :) Commented Jun 1, 2013 at 13:48
  • I tried while (numChildren > 0) { trace("before" + numChildren); removeChildAt(0); trace("after" + numChildren); } And it seems like the traces didn't even execute. I didn't even get "after0" or "before0" or anything like that. The only output I got was this: ArgumentError: Error #1063: Argument count mismatch on Game_fla::MainTimeline/clearStage(). Expected 0, got 1. clearStage() is the method that this code is in. Commented Jun 1, 2013 at 14:24
  • I just remembered something. When I created some of the objects, I created them in a for loop using variables that get re-declared each time the loop iterates. So, they don't technically have variable names. They just remain on the stage. Does this have anything to do with why they refuse to disappear? Commented Jun 1, 2013 at 14:29
  • still trying to figure out the reason for your argument error above. But as to your other question about the variables that get redeclared: that's ok. The variables name is reused, but the objects are added as children to some container object like the stage, a MovieClip, or Sprite. So as long as your while loop above is operating on the appropriate container you can remove them. Maybe you should show the code where you add the objects, and that might help clarify how to remove them. Commented Jun 1, 2013 at 19:13

2 Answers 2

1

This error:

ArgumentError: Error #1063: Argument count mismatch on Game_fla::MainTimeline/clearStage(). Expected 0, got 1. clearStage()

Occurs because your clearStage() method has been added as the click event handler of a button. If your clearStage() function is going to be used an an event handler, it needs to accept an "event" parameter. So you should define the function like this:

function clearStage(event:Event)
{
    while (numChildren > 0) 
    {
        trace("before" + numChildren);
        removeChildAt(0);
        trace("after" + numChildren);
    }
}

As a side note, this means that if you want to also call clearStage() manually, that is use it without adding it as an event handler, that you'll need to include this event parameter... but you can just pass in a null, because your code doesn't need to actually use the event parameter:

clearStage(null);

I'm not sure I see anything else wrong. I'd start by adding that event parameter to your clearStage() function as I shown above.

I should also add I mostly worked in Flex or pure AS3, and am not super skilled in Flash CS6 and programming on the timeline :)

Sign up to request clarification or add additional context in comments.

Comments

0

From memory, I don't think Flash re-orders when you remove a child. If you remove a child at index 0, every other child is still numbered 1 to x. childAt(0) is just null now. Keep that in mind with this sort of process.

5 Comments

I thought of that and tried a for loop where I worked backwards from the highest index, but it yielded the same results :(
This is not true. When you add/remove children to a DisplayObjectContainer the indexes are always updated. So if an object has 3 children, and I remove the child at 0, the item that was at index 1 is now at index 0.
You talk about old as2 engine
@Cherniv, wow! I didn't know that about AS2, thank you for clarifying... This is one of the many reasons why Stack Overflow is awesome. I learn new things everyday :)
@SunilD. you're right , i've forgot to place this at the beginning: (at)JediKnightBoB

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.