Simple question about stage and instance-targeting

hi all,

i’ve been searching the answer for the last couple days for this one.

my question is probably easy but i don’t have any idea what i should do for i’m new in as3. please kindly give me your guidance.

  • I have a fla. There’s only one instance on the stage. it is a small circle named “me”

  • Then i have a class within “com.myClass” folder.

here’s the script:

[AS]package com.myClass{

import flash.events.Event;
import flash.events.KeyboardEvent;

public class Character {
    var keyUP:Boolean    = false;
    var keyDOWN:Boolean  = false;
    var keyRIGHT:Boolean = false;
    var keyLEFT:Boolean  = false;
    
    var power    = 2;
    var friction = 0.7;
    var xspeed   = 0;
    
    
    public function Character() {
        trace("called");
        stage.addEventListener(KeyboardEvent.KEY_UP,   key_Up);
        stage.addEventListener(KeyboardEvent.KEY_DOWN, key_Down);
        me.addEventListener   (Event.ENTER_FRAME,      myFunction);
    }
    
    function key_Up(event:KeyboardEvent) {
        switch (event.keyCode) {
            case 37 :
                keyLEFT = false;
                break;
            case 38 :
                keyUP = false;
                break;
            case 39 :
                keyRIGHT = false;
                break;
            case 40 :
                keyDOWN = false;
        }
    }
    
    function key_Down(event:KeyboardEvent) {
        switch (event.keyCode) {
            case 37 :
                keyLEFT = true;
                break;
            case 38 :
                keyUP = true;
                break;
            case 39 :
                keyRIGHT = true;
                break;
            case 40 :
                keyDOWN = true;        
        }
    }
    
    function myFunction (e:Event) {
        if (keyUP) {
            trace("Up");
        }
        if (keyDOWN) {
            trace("Down");
        }
        if (keyLEFT) {
            xspeed -= power;
        }
        if (keyRIGHT) {
            xspeed += power;
        }
        xspeed *= friction;
        me.x += Math.round(xspeed);
        
    }
    
}        

}[/AS]

now, this script give me:

“1120: Access of undefined property stage.”
and
“1120: Access of undefined property me.”

Then i’m stuck with what to do next.

So my question is:
How do you target my instance in fla with the name me? and also the stage?

I thank you for your support in advanced.

ps.: attached is the files

There’s a few things I think you should change.

For a start, link that movieclip symbol in the library to your Character class. In other words, rename the symbol ‘Character’. Then right click on its name in the library and select Linkage. Enter ‘Character’ in the class box. Now when you create a new instance of your class, you’re creating a new instance of your symbol.

Put the following code on frame 1 of your fla:

var myChar:Character = new Character();

addChild(myChar); // put it on the stage ...

myChar.doEventListeners();  // ... before you add Event Listeners

Let me explain. I’m pretty sure that the problem you’re having with the stage is that you’re trying to reference the stage before any instance of the class has been put ON the stage. (Yes, your symbol was on the stage, but that was before you linked that symbol to your class, so flash was working its way through your class file without knowing anything about that symbol.)

There’s probably different ways of solving that problem but the simple way I’m suggesting is to add the event listeners by way of a separate function. In the code above you add your character to the stage, and then call the ‘doEventListeners’ method.

Your class file will now look like this:

import flash.events.Event;
    import flash.events.KeyboardEvent;
    **import flash.display.MovieClip;**
    
    public class Character **extends MovieClip**{
        var keyUP:Boolean    = false;
        var keyDOWN:Boolean  = false;
        var keyRIGHT:Boolean = false;
        var keyLEFT:Boolean  = false;
        
        var power    = 2;
        var friction = 0.7;
        var xspeed   = 0;
        
        
        
        public function Character() {
            trace("called");
        }
        
        **public function doEventListeners():void
        {
            stage.addEventListener(KeyboardEvent.KEY_UP,   key_Up);
            stage.addEventListener(KeyboardEvent.KEY_DOWN, key_Down);
            this.addEventListener   (Event.ENTER_FRAME,  myFunction);
        }**
        
        function key_Up(event:KeyboardEvent) {
            switch (event.keyCode) {
                case 37 :
                    keyLEFT = false;
                    break;
                case 38 :
                    keyUP = false;
                    break;
                case 39 :
                    keyRIGHT = false;
                    break;
                case 40 :
                    keyDOWN = false;
            }
        }
        
        function key_Down(event:KeyboardEvent) {
            switch (event.keyCode) {
                case 37 :
                    keyLEFT = true;
                    break;
                case 38 :
                    keyUP = true;
                    break;
                case 39 :
                    keyRIGHT = true;
                    break;
                case 40 :
                    keyDOWN = true;        
            }
        }
        
        function myFunction (e:Event) {
            if (keyUP) {
                trace("Up");
            }
            if (keyDOWN) {
                trace("Down");
            }
            if (keyLEFT) {
                xspeed -= power;
            }
            if (keyRIGHT) {
                xspeed += power;
            }
            xspeed *= friction;
            **this**.x += Math.round(xspeed);
            
        }
        
    }        
}

Note that nowhere in the Character class is there any mention of the specific instance names (no ‘me_mc’ or ‘myChar’). The class needs to be a set of general instructions that can be applied to ANY instance.

Finally, delete the instance of the symbol that you currently have on stage. The code on frame 1 of your fla is going to create an instance for you.

Hope this works for you. Let us know if it doesn’t.

[quote=DiamondDog;2349403]There’s a few things I think you should change.

For a start, link that movieclip symbol in the library to your Character class. In other words, rename the symbol ‘Character’. Then right click on its name in the library and select Linkage. Enter ‘Character’ in the class box. Now when you create a new instance of your class, you’re creating a new instance of your symbol.

Put the following code on frame 1 of your fla:

var myChar:Character = new Character();

addChild(myChar); // put it on the stage ...

myChar.doEventListeners();  // ... before you add Event Listeners

Let me explain. I’m pretty sure that the problem you’re having with the stage is that you’re trying to reference the stage before any instance of the class has been put ON the stage. (Yes, your symbol was on the stage, but that was before you linked that symbol to your class, so flash was working its way through your class file without knowing anything about that symbol.)

There’s probably different ways of solving that problem but the simple way I’m suggesting is to add the event listeners by way of a separate function. In the code above you add your character to the stage, and then call the ‘doEventListeners’ method.

Your class file will now look like this:

import flash.events.Event;
    import flash.events.KeyboardEvent;
    **import flash.display.MovieClip;**
    
    public class Character **extends MovieClip**{
        var keyUP:Boolean    = false;
        var keyDOWN:Boolean  = false;
        var keyRIGHT:Boolean = false;
        var keyLEFT:Boolean  = false;
        
        var power    = 2;
        var friction = 0.7;
        var xspeed   = 0;
        
        
        
        public function Character() {
            trace("called");
        }
        
        **public function doEventListeners():void
        {
            stage.addEventListener(KeyboardEvent.KEY_UP,   key_Up);
            stage.addEventListener(KeyboardEvent.KEY_DOWN, key_Down);
            this.addEventListener   (Event.ENTER_FRAME,  myFunction);
        }**
        
        function key_Up(event:KeyboardEvent) {
            switch (event.keyCode) {
                case 37 :
                    keyLEFT = false;
                    break;
                case 38 :
                    keyUP = false;
                    break;
                case 39 :
                    keyRIGHT = false;
                    break;
                case 40 :
                    keyDOWN = false;
            }
        }
        
        function key_Down(event:KeyboardEvent) {
            switch (event.keyCode) {
                case 37 :
                    keyLEFT = true;
                    break;
                case 38 :
                    keyUP = true;
                    break;
                case 39 :
                    keyRIGHT = true;
                    break;
                case 40 :
                    keyDOWN = true;        
            }
        }
        
        function myFunction (e:Event) {
            if (keyUP) {
                trace("Up");
            }
            if (keyDOWN) {
                trace("Down");
            }
            if (keyLEFT) {
                xspeed -= power;
            }
            if (keyRIGHT) {
                xspeed += power;
            }
            xspeed *= friction;
            **this**.x += Math.round(xspeed);
            
        }
        
    }        
}

Note that nowhere in the Character class is there any mention of the specific instance names (no ‘me_mc’ or ‘myChar’). The class needs to be a set of general instructions that can be applied to ANY instance.

Finally, delete the instance of the symbol that you currently have on stage. The code on frame 1 of your fla is going to create an instance for you.

Hope this works for you. Let us know if it doesn’t.[/quote]

Works like a charm!!! But hey, i need to ask you some question.

is it the only way? i mean…

  1. what if i want to use the script in a class, without filling in the linkage properties in library? how to target my symbol on the stage?

  2. is using “addchild” a must?

if its possible, i want all my symbols to be put on stage. So i don’t want to use addChild

Ah, right, I see what you mean.

One of the things I’m learning about Flash is that there’s always another way of doing things. =)

OK, so in my library I have a movieclip symbol called ‘blob’. It’s not linked to any class, just a library symbol. (It’s the grey circle with black outline that you had.) On the stage I have an instance of blob, called ‘me’.

I want to control that with the Character class. So in the first frame of my .fla file, I create a new instance of the Character class, passing in ‘me’ as the parameter.

var myCharacter:Character = new Character(me);

and then my Character class looks like this

package{

    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.display.MovieClip;
    
    public class Character extends MovieClip{
        var keyUP:Boolean    = false;
        var keyDOWN:Boolean  = false;
        var keyRIGHT:Boolean = false;
        var keyLEFT:Boolean  = false;
        
        var power    = 2;
        var friction = 0.7;
        var xspeed   = 0;
        
        **var characterClip:MovieClip;**
        
        **public function Character(who:MovieClip) {
            ****characterClip = who;
            trace(characterClip.name + " is now a Character");
            ****characterClip.stage.addEventListener(KeyboardEvent.KEY_UP,   key_Up);
            charcterClip.stage.addEventListener(KeyboardEvent.KEY_DOWN, key_Down);
            characterClip.addEventListener (Event.ENTER_FRAME,  myFunction);
        }**
        
        
        function key_Up(event:KeyboardEvent) {
            switch (event.keyCode) {
                case 37 :
                    keyLEFT = false;
                    break;
                case 38 :
                    keyUP = false;
                    break;
                case 39 :
                    keyRIGHT = false;
                    break;
                case 40 :
                    keyDOWN = false;
            }
        }
        
        function key_Down(event:KeyboardEvent) {
            switch (event.keyCode) {
                case 37 :
                    keyLEFT = true;
                    break;
                case 38 :
                    keyUP = true;
                    break;
                case 39 :
                    keyRIGHT = true;
                    break;
                case 40 :
                    keyDOWN = true;        
            }
        }
        
        function myFunction (e:Event) {
            if (keyUP) {
                trace("Up");
            }
            if (keyDOWN) {
                trace("Down");
            }
            if (keyLEFT) {
                xspeed -= power;
            }
            if (keyRIGHT) {
                xspeed += power;
            }
            xspeed *= friction;
            **characterClip**.x += Math.round(xspeed);
            
        }
        
    }        
}

Couple of things to notice. First, my package doesn’t have a name. (I just put my .fla and .as files in the same directory.) But I think your package had a name. Secondly, this time the ‘me’ clip is on stage right from the start, so we can access it’s stage property to add the event listeners. Don’t need a separate function to do that.

MyChar.fla and Character.as files attached.

Let me know if any of this doesn’t work for you.

[quote=DiamondDog;2350066]Ah, right, I see what you mean.

One of the things I’m learning about Flash is that there’s always another way of doing things. =)

OK, so in my library I have a movieclip symbol called ‘blob’. It’s not linked to any class, just a library symbol. (It’s the grey circle with black outline that you had.) On the stage I have an instance of blob, called ‘me’.

I want to control that with the Character class. So in the first frame of my .fla file, I create a new instance of the Character class, passing in ‘me’ as the parameter.

var myCharacter:Character = new Character(me);

and then my Character class looks like this

package{

    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.display.MovieClip;
    
    public class Character extends MovieClip{
        var keyUP:Boolean    = false;
        var keyDOWN:Boolean  = false;
        var keyRIGHT:Boolean = false;
        var keyLEFT:Boolean  = false;
        
        var power    = 2;
        var friction = 0.7;
        var xspeed   = 0;
        
        **var characterClip:MovieClip;**
        
        **public function Character(who:MovieClip) {
            ****characterClip = who;
            trace(characterClip.name + " is now a Character");
            ****characterClip.stage.addEventListener(KeyboardEvent.KEY_UP,   key_Up);
            charcterClip.stage.addEventListener(KeyboardEvent.KEY_DOWN, key_Down);
            characterClip.addEventListener (Event.ENTER_FRAME,  myFunction);
        }**
        
        
        function key_Up(event:KeyboardEvent) {
            switch (event.keyCode) {
                case 37 :
                    keyLEFT = false;
                    break;
                case 38 :
                    keyUP = false;
                    break;
                case 39 :
                    keyRIGHT = false;
                    break;
                case 40 :
                    keyDOWN = false;
            }
        }
        
        function key_Down(event:KeyboardEvent) {
            switch (event.keyCode) {
                case 37 :
                    keyLEFT = true;
                    break;
                case 38 :
                    keyUP = true;
                    break;
                case 39 :
                    keyRIGHT = true;
                    break;
                case 40 :
                    keyDOWN = true;        
            }
        }
        
        function myFunction (e:Event) {
            if (keyUP) {
                trace("Up");
            }
            if (keyDOWN) {
                trace("Down");
            }
            if (keyLEFT) {
                xspeed -= power;
            }
            if (keyRIGHT) {
                xspeed += power;
            }
            xspeed *= friction;
            **characterClip**.x += Math.round(xspeed);
            
        }
        
    }        
}

Couple of things to notice. First, my package doesn’t have a name. (I just put my .fla and .as files in the same directory.) But I think your package had a name. Secondly, this time the ‘me’ clip is on stage right from the start, so we can access it’s stage property to add the event listeners. Don’t need a separate function to do that.

MyChar.fla and Character.as files attached.

Let me know if any of this doesn’t work for you.[/quote]

Wow thanks a lot DiamondDog… this is just what i need. <3