Chetan
Chetan

Reputation: 9

MovieClip button In Class

Tried this,

package {
    import flash.display.MovieClip;
    import flash.events.*;

    public class test extends MovieClip {
        public function test() {
            addEventListener(Event.ADDED_TO_STAGE, registerBtn);
        }

        private function registerBtn(e:Event):void {
            this.parent["Homebtn"].addEventListener(MouseEvent.CLICK, myButtonClick);
        }

        private function myButtonClick(e:MouseEvent):void {
            trace("CLICKED");
        }
    }
}

Image

And the same code on frame 1, And there's a MovieClip Button on stage having Instance name "Homebtn".

Upvotes: 1

Views: 261

Answers (1)

Atriace
Atriace

Reputation: 2558

Imports

import flash.events.*;

Importing all classes from a package that originates in flash has zero impact on compile size because they're already present in the Flash Player runtime environment. It's pure monotony that you're required to explicitly declare these imports, but good practice when dealing with third party packages.

Stage Relationship

Document code (i.e., code in the Flash IDE timelines) have a direct relationship to MainTimeline, whereas class files do not. If you want to add button1.addEventListener(MouseEvent.CLICK, myButtonClick); to your class, you're not going to be able to do so unless you:

A: Pass a pointer to the button/stage/root to the class when instantiating your test class:

var myObj:test = new test(root)

B: Wait to add the event listener until after you've given the test object a parent relationship to the stage from which to traverse to the button:

addChild(test);

inside your class...

public function test() {
    // constructor code
    addEventListener(Event.ADDED_TO_STAGE, registerBtn)
}

private function registerBtn():void {
    this.parent.button1.addEventListener(MouseEvent.CLICK, myButtonClick);
}

Turn on Debugging

To find the cause of your bugs, you need to debug your code. If you're using Flash IDE CS6, then you can enable this by going to your publish settings and enabling "Permit Debugging". This will take your ambiguous error...

null object reference at myDocument/doSomething()

...to a much clearer...

null object reference at myDocument/doSomething() package\myClass.as:20

...which now denotes which line in your code to look for your issue.

enter image description here

Use the Debug Console

Use the debugging compile mode to bring up the Debug Console. This will provide you with an immediate look at the line of code in question, as well as the Call Stack, and the state of all available Variables. No programmer should be without it.

Run by going to the menu "Debug > Debug Movie > Debug", or use the keyboard combo CONTROL+SHIFT+ENTER.

enter image description here


Now that you're armed with the know-how to do this on your own, I'll cover what you'd encounter, and how you'd fix it (since you're new).

First, it's flash.events with an "s". So we'll change that.

Next, compiling it we get the following errors:

enter image description here

So we see on line 7 of our test.as class: you've placed the timeline code into the class.

var myObj:test = new test(root);
addChild(test);

You don't want to instantiate you class from within itself as it'll never get instantiated. Think of your code as a railroad. The train starts with your timeline code, and only runs on the rails set before it. Your class is floating off to the side, ready with all its interesting turns and zigzags, but you have to add it to the rails for it to be actually run. That's instantiation; we're copying that path onto the current track, and the train runs on it.

So, we get rid of lines 6 & 7, and we're left with Access of possibly undefined property Homebtn. Calling this.parent is actually a getter function, and it returns a DisplayObjectContainer. Because AS3 is a strongly datatyped language, the compiler will know that there is no such property "Homebtn" on DisplayObjectContainers (silly compiler). But of course, you know it's there (or at least it will be by the time this code runs). A simple way of getting around that is by making it evaluate the reference at run-time.

this.parent["Homebtn"].addEventListener(MouseEvent.CLICK, myButtonClick);

By encapsulating the button name as a string and within brackets, we've done that.

Now we recompile again, and get the following:

enter image description here

This is because all event listeners receive one argument: an event object. You may not use it, but not having a variable to hold it is a no-no.

private function registerBtn(e:Event):void {

As a final point. All class functions need to be denoted as to what namespace they exist in. myButtonClick needs one, so we'll add it as private since no external (ie., non-class based) functions need access to it.

Here's your revised code:

test.as

package {
    import flash.display.MovieClip;
    import flash.events.*;

    public class test extends MovieClip {
        public function test() {
            addEventListener(Event.ADDED_TO_STAGE, registerBtn);
        }

        private function registerBtn(e:Event):void {
            this.parent["Homebtn"].addEventListener(MouseEvent.CLICK, myButtonClick);
        }

        private function myButtonClick(e:MouseEvent):void {
            trace("CLICKED");
        }
    }
}

test.fla (timeline code on frame 1)

import test;

var Homebtn:MovieClip = new MovieClip();
Homebtn.graphics.beginFill(0xFF0000, 1);
Homebtn.graphics.drawRect(0, 0, 150, 25);
Homebtn.graphics.endFill();
addChild(Homebtn);

var testObj:test = new test();
addChild(testObj);

Upvotes: 2

Related Questions