A Flash Developer Resource Site

Results 1 to 11 of 11

Thread: Why a movieclip has to be already in the first frame to be targetable by script?

  1. #1
    Junior Member
    Join Date
    Apr 2010
    Posts
    17

    Why a movieclip has to be already in the first frame to be targetable by script?

    My document class adds a movie clip, and then fires gotoAndStop(2) at him. I have a button in the movie clip, and a command command targeting this button. Now, if the button exists in the second frame only, the command does not work. If it exists since the first frame, it works. Why is that?

  2. #2
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    Because if the button doesn't exist when the script referencing it executes, you'll get a nullpointer (1009) error. You cannot act on something unless you have a reference to that thing.

  3. #3
    Junior Member
    Join Date
    Apr 2010
    Posts
    17
    Yeah, but it should exist already in the second frame. The command for the movie clip to go to the second frame is before the command that references the button in this movie clip.

  4. #4
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    Do you mean that you have code similar to the following?

    Code:
    someClip.gotoAndStop(2);
    someClip.someButton.doSomething();
    If that's the case, then the actual transition to the second frame does not take place immediately, and someButton still does not exist when the second line is executed. You must wait approximately one frame for someClip to change frames.

    If that's not what you mean, then post some code.

  5. #5
    Junior Member
    Join Date
    Apr 2010
    Posts
    17
    That is what I mean. I did not know that, thanks. So, what is the most elegant way to wait that frame? The command I have are in a "loadLevelSelectionMenu" function. Here it is:

    Actionscript Code:
    public function loadLevelSelectionMenu () // ------------------------------------------------- LOAD LEVEL SELECTION MENU
        {
       
        trace("Loading Level Selection screen");
       
        levelSelectionScreen = new LevelSelectionScreen;
        addChild(levelSelectionScreen);
        levelSelectionScreen.x = stage.stageWidth / 2;
        levelSelectionScreen.y = stage.stageHeight / 2;
       
        levelSelectionScreen.gotoAndStop (Variables.levelsUnlocked + 1);
       
        if ( levelSelectionScreen.level2_btn != null)
        {
        levelSelectionScreen.level1_btn.addEventListener (MouseEvent.CLICK, onLevel1Click);
        }
       
        if ( levelSelectionScreen.level2_btn != null)
        {
             levelSelectionScreen.level2_btn.addEventListener (MouseEvent.CLICK, onLevel2Click);
           
        }
       
       
        if ( levelSelectionScreen.level3_btn != null)
        {
             levelSelectionScreen.level3_btn.addEventListener (MouseEvent.CLICK, onLevel3Click);
           
        }

               
                trace("Level Selection screen loaded");
               
            }

  6. #6
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    You're testing for level2_btn twice. It looks like the first one should be level1_btn.

    I don't know about the most elegant way, but you could add an enter_frame listener which handles the processing, then removes itself. More elegant than that would be to avoid using frames on your levelSelectionScreen, and instead just add and remove items.

    If you wanted to use the enter_frame technique, this is more or less how to approach it:
    Code:
    public function loadLevelSelectionMenu():void { //------------------------------- LOAD LEVEL SELECTION MENU
        trace("Loading Level Selection screen");
       
        levelSelectionScreen = new LevelSelectionScreen();
        addChild(levelSelectionScreen);
        levelSelectionScreen.x = stage.stageWidth / 2;
        levelSelectionScreen.y = stage.stageHeight / 2;
       
        levelSelectionScreen.addEventListener(Event.ENTER_FRAME, processLevelSelection);
        levelSelectionScreen.gotoAndStop (Variables.levelsUnlocked + 1);
        trace("Level Selection screen loaded");
    }
    
    private function processLevelSelection(e:Event):void{
       var levelSelectionScreen:LevelSelectionScreen = LevelSelectionScreen(e.currentTarget);
       levelSelectionScreen.removeEventListener(Event.ENTER_FRAME, processLevelSelection);
       if ( levelSelectionScreen.level1_btn != null){
          levelSelectionScreen.level1_btn.addEventListener (MouseEvent.CLICK, onLevel1Click);
       }
      
       if ( levelSelectionScreen.level2_btn != null){
             levelSelectionScreen.level2_btn.addEventListener (MouseEvent.CLICK, onLevel2Click);
       }
       
       if ( levelSelectionScreen.level3_btn != null){
             levelSelectionScreen.level3_btn.addEventListener (MouseEvent.CLICK, onLevel3Click);
       }
    }

  7. #7
    Junior Member
    Join Date
    Apr 2010
    Posts
    17
    Quote Originally Posted by 5TonsOfFlax View Post
    You're testing for level2_btn twice.
    Oh yeah, thanks.

    Quote Originally Posted by 5TonsOfFlax View Post
    More elegant than that would be to avoid using frames on your levelSelectionScreen
    Yeah, but doing it in frames is much more comfortable, if I will get it to work.

    I'm trying to implement your code now, does not work yet...

  8. #8
    Junior Member
    Join Date
    Apr 2010
    Posts
    17
    Hmm, level2_btn still registers as null, even with your function...

  9. #9
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    I didn't get to test it because I don't have flash here. I'm not sure why it wouldn't work, but I'm not all that familiar with the gotchas involved with frame scripting.

    You could put your code inside your level selection clip (or in the class associated with it), and dispatch an event from the buttons in there. Then your outer class would just need to listen for that event.

  10. #10
    Junior Member
    Join Date
    Apr 2010
    Posts
    17
    That sounds promising, I'll learn more about events.

  11. #11
    Junior Member
    Join Date
    Apr 2010
    Posts
    17
    Yeah, it worked! Each frame in the movie clip contains ->

    Actionscript Code:
    dispatchEvent(new Event("level screen ready"));

    which fires processLevelSelection function. Thanks!

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