A Flash Developer Resource Site

Results 1 to 9 of 9

Thread: Parameter Child must be Non Null - Scope problem?

  1. #1
    Confounded Flash User
    Join Date
    Apr 2001
    Location
    Chicago
    Posts
    39

    Parameter Child must be Non Null - Scope problem?

    I'm working on a sliding gallery like Hulu.com. Got some help here in setting it up and the sliding slides in and out is working fine. However, I need to add and then remove a button to each slide as it comes in and goes out. (I initially tried including the button on each slide, a mc, but this proved problematic for the event listeners).

    So when the file loads up, I add a mc to the first slide of the group like so (features[] is an array of movie clips - my slides):

    Code:
    var goBtn:MovieClip = new FeatureButton();
    features[0].addChild(goBtn);
    goBtn.x = 350;
    goBtn.y = 230;
    So I add the button/mc to the first slide - works just fine.

    So there are two handlers, next and previous. So I started with the next handler. The first thing I have to do is kill the button on the panel that is sliding out, so I do that like so:

    Code:
    features[featureCount].removeChild(goBtn);
    goBtn = null;
    (featureCount is a counter keeping track of the slides). This works fine. I click the next button, and the button on the slide disappears and we move to the next slide - perfect.

    So then I add the following next - exactly like I did in the beginning:

    Code:
    var goBtn:MovieClip = new FeatureButton();
    features[featureCount].addChild(goBtn);
    goBtn.x = 350;
    goBtn.y = 230;
    This time adding it to the current slide coming in - but this generates the following error:

    Code:
    TypeError: Error #2007: Parameter child must be non-null.
    	at flash.display::DisplayObjectContainer/removeChild()
    	at featuregallery_fla::MainTimeline/nextFeature()
    Confusing - not sure how I'm getting an error on the removeChild() when that is already gone. I assume "parameter child" means goBtn - yes it is null because it's been removed. But I'm not trying to do something with that.

    I can only guess this is a variable scoping issue with goBtn - but I'm not seeing how to resolve it. Flash file attached.
    Attached Files Attached Files

  2. #2
    AS3 Mod
    Join Date
    Sep 2007
    Location
    O-H-I-O
    Posts
    2,385
    Did you attach the wrong file? I don't see any of this code you mention in the file attached.

  3. #3
    Confounded Flash User
    Join Date
    Apr 2001
    Location
    Chicago
    Posts
    39
    Shoot, yes I did - sorry about that. Someone at the office helped me solve it, but I'm not sure I completely understand the scope issue.

    We changed the new creation of the button after deleting the old one to this:

    Code:
    goBtn = new FeatureButton();
    features[featureCount].addChild(goBtn);
    And it works fine.

    I don't quite understand why. I'm not sure if "global" variables is a legit concept in AS3, but is goBtn a global because it was instantiated initially outside the function? So it conflicts with that if I try to recreate it?

    Proper .fla can be grabbed here:

    http://www.pixelmech.com/rev/featuregallery.zip

  4. #4
    AS3 Mod
    Join Date
    Sep 2007
    Location
    O-H-I-O
    Posts
    2,385
    I have a few suggestions for your coding in this one. You should attempt to use more 'dynamic' code every chance you can. There is a ton of code in there I took out and added in a couple of your loops. Check this out:
    PHP Code:
    import fl.transitions.Tween;
    import fl.transitions.easing.*;

    stop();
    stage.frameRate 31;

    var 
    startX:int 110;
    var 
    beginX:int 740;
    var 
    endX:int 110;
    var 
    tweenDuration:int 1.5;
    var 
    featureCount:int 0;
    var 
    features:Array = new Array(new feature1(), new feature2(), new feature3(), new feature4(), new feature5());
    // create array of indicators. loop and turn all off, then turn on indicator that matches count #
    var indicators:Array = new Array(indicator1indicator2indicator3indicator4indicator5);

    // add feature clips to the stage, starting with 1 in proper position and throwing the rest off in order off stage.
    // in the button functions, they will be moved to the proper spot and tweened.
    for(var 0features.lengthi++) 
    {
        
    features[i].startX;
        
    addChild(features[i]);
        
        
    // add in button on first slide
        
    var goBtn:MovieClip = new FeatureButton();
        
    goBtn.340;
        
    goBtn.230;
        
    features[i].addChild(goBtn);
        
        
    indicators[i].idx i;
        
    indicators[i].buttonMode true;
        
    indicators[i].useHandCursor true;
        
    indicators[i].addEventListener(MouseEvent.CLICKdirectNav);
        
        
    startX += 700;
    }

    function 
    setIndicator() 
    {
        for(var 
    0indicators.lengthi++)
        {
            
    indicators[i].gotoAndStop(1);
        }
        if(
    indicators[featureCount] != undefined) {
            
    indicators[featureCount].gotoAndStop(2);
        }
    }

    setChildIndex(btn_next,numChildren 1);
    setChildIndex(btn_previous,numChildren 1);

    btn_next.addEventListener(MouseEvent.CLICKnextFeature);
    btn_previous.addEventListener(MouseEvent.CLICKprevFeature);

    // initilization items
    setIndicator();

    // gallery functions
    function directNav(e:MouseEvent):void
    {
        
    // Tween out the active slide
        
    var galleryTweenOut:Tween = new Tween(features[featureCount], "x"Strong.easeInOutendX, -beginXtweenDurationtrue);
        
        
    // set the feature array to the proper slot
        
    var indicator:MovieClip e.target as MovieClip;
        
    featureCount indicator.idx;
        
        
    // tween in the selected slide and play
        
    var galleryTweenIn:Tween = new Tween(features[featureCount], "x"Strong.easeInOutbeginXendXtweenDurationtrue);
        
    features[featureCount].gotoAndPlay(1);
        
    setIndicator();
    }

    function 
    nextFeature(e:MouseEvent):void
    {    
        
    // Tween out the active slide
        
    var galleryTweenOut:Tween = new Tween(features[featureCount], "x"Strong.easeInOutendX, -beginXtweenDurationtrue);
        
    trace(featureCount);
        
    // If the counter reaches the end of the slides then reset it to 0
        
    featureCount++;
        if(
    featureCount >= features.lengthfeatureCount 0;
        
        
    // Tween in the next slide and play
        
    var galleryTweenIn:Tween = new Tween(features[featureCount], "x"Strong.easeInOutbeginXendXtweenDurationtrue);
        
    features[featureCount].gotoAndPlay(1);
        
        
    setIndicator();
    }

    function 
    prevFeature(e:MouseEvent):void
    {
        
    // Tween out the active slide
        
    var galleryTweenOut:Tween = new Tween(features[featureCount], "x"Strong.easeInOutendXbeginXtweenDurationtrue);
        
        
    // If the counter reaches the end of the slides then reset it to length of the array
        
    featureCount--;
        if(
    featureCount 0featureCount features.length-1;
        
        
    // Tween in the next slide
        
    var galleryTweenIn:Tween = new Tween(features[featureCount], "x"Strong.easeInOut, -beginXendXtweenDurationtrue);
        
    features[featureCount].gotoAndPlay(1);
        
        
    setIndicator();

    I would also replace those Tweens with TweenLite

  5. #5
    Confounded Flash User
    Join Date
    Apr 2001
    Location
    Chicago
    Posts
    39
    Great! Thanks for the help. I knew the code was a bit messy, this was just the sort of suggestion I was looking for to clean it up - plus I'm learning, which is great. Really appreciate your help on this project, it's been invaluable

  6. #6

  7. #7
    Confounded Flash User
    Join Date
    Apr 2001
    Location
    Chicago
    Posts
    39
    Well you guys rock, I'm glad you're here! Okay, I have made some updates and I have a couple other questions, I don't think anything major. I think I have understood everything you did. Current .fla is here:

    http://www.pixelmech.com/flash/featuregallery-2.zip

    Okay first - this block:

    Code:
    for(var i = 0; i < features.length; i++)
    {
    	// add in each feature
        features[i].x = startX;
        addChild(features[i]);
    
        // add in go now buttons on each feature
        var goBtn:MovieClip = new FeatureButton();
        goBtn.x = 340;
        goBtn.y = 230;
        features[i].addChild(goBtn);
        // will this cause a memory issue here?
        goBtn.addEventListener(MouseEvent.CLICK, featureClick);
    
        // make indicators act as buttons and provide handler
        indicators[i].idx = i;
        indicators[i].buttonMode = true;
        indicators[i].useHandCursor = true;
        indicators[i].addEventListener(MouseEvent.CLICK, directNav);
    
    	// make sure next slide is not showing in the viewport
        startX += 700;
    }
    Questions in bold - I've added the event listener on the button here. Will this cause any memory issues? I'm assuming no, since there are 5 of them added to the feature MCs, and they aren't being recreated over and over, but I just wanted to check it made sense to put them there.

    For the .idx - am I correct in guessing that you are just setting a property called idx to the index position of the FOR loop, so you have a reference point for the indicator array?

    Next, in the setIndicator() function:

    Code:
    function setIndicator()
    {
        for(var i = 0; i < indicators.length; i++)
        {
            indicators[i].gotoAndStop(1);
        }
        if(indicators[featureCount] != undefined) {
            indicators[featureCount].gotoAndStop(2);
        }
    }
    I don't get the bold part. Why are we checking for it not being equal to undefined? My guess is we are setting the current indicator, I'm just unclear on the undefined part.

    I added this part in after consulting with a guy here at the office:

    Code:
    // declare tweens here to avoid "sticky" slides due to variable scope issues
    var galleryTweenIn:Tween;
    var galleryTweenOut:Tween;
    Quite often a slide would "stick" it would still show halfway off the screen. The guy here said it was a garbage collection issue because it was trying to collect it before it finished tweening. Declaring it outside the functions seems to have fixed this - and it seems to be smoother. Is this what you would have done? Of course the tween calls now in the functions are galleryTweenIn = new Tween(etc).

    Lastly, for my featureClick function when the user clicks on the go now button - I had initially tested it with a urlRequest just pointing to the HTML page, like so:

    Code:
    navigateToURL(new URLRequest("/somePage.html"));
    But it seemed to keep opening it in a new window/tab. How do you avoid that and open it in the same window?

    Oh, and one more thing, you mentioned Tween Lite - is that just a smaller tween package?

    Thanks again for all the great tips.

  8. #8
    AS3 Mod
    Join Date
    Sep 2007
    Location
    O-H-I-O
    Posts
    2,385
    1) Adding event listener here is perfectly fine, no memory issues

    2) Yes I am only setting an index as a reference point (this elimated your static switch case).

    3) Here we just check and make sure the indicator exists before trying to call it, in case for some reason you create a slide and forget to place the indicator. This way you would not see any errors. You could also handle that error here.

    4) The tween outside is probably a better idea than what was in there before. The garbage collection is sketchy sometimes in AS3

    5) Try: navigateToURL(urlrequest,"_self");// _self indicates open link in 'current' window

    TweenLite is an optimized tween class written to replace the Flash tween class. It is loads faster and much more efficient with multiple tweens.

  9. #9
    Confounded Flash User
    Join Date
    Apr 2001
    Location
    Chicago
    Posts
    39
    Great, awesome, a thousand thanks once again I'm going to give the TweenLite a shot.

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