AS3 - How to solve this access of undefined property error? - actionscript-3

I need to call a MovieClip that gets added from the library but I get this error:
1120: Access of undefined property light.
This is my code:
var btn:Btnselect;
btn = new Btnselect();
con.addChild(btn);
btn.name = "light"
light.box.visible=false
Why is it undefined?

You are trying to access the movieClip like you would in the Flash IDE, where you set the name property in the properties panel and that's how you access it in AS3
However, when instantiating movieClips in AS3 (meaning, you didn't drag them from the Library to the Stage) the variable is set differently.
Here, you should be referencing "btn" not "light"
btn.box.visible = false;
because that's what you called your variable

Access of undefined property light.
Means that light, has a null reference, and you're trying to access it. Make sure that the variable light has been initialized or it has a reference to movie clip in the stage.

I think you should use the getChildByName method, for example
getChildByName("light").box.visible = false;
instead of :light.box.visible=false

Related

How to fix an error #1009 in a class added to Main?

I have a class called ChestScene that represents a scene/MovieClip in a .fla file I'm working on. I've had tons of issues that seem to be rooted in a fundamental misunderstanding of how to properly use objects that have code attached to them. It is my understanding that adding the object to the stage automatically instantiates it, so right now all I'm trying to do is instantiate and add to stage ChestScene() in the constructor of my Main method. I thought it would be as simple as this:
public class Main extends MovieClip {
var chest:Chest = new Chest();
public function Main() {
stage.addChild(chest);
}
But I get this error:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at Chest()/startScene()
at Chest()
at Main()
So my first question is why is Chest null? The object exists in my fla. If I add it to the stage by dragging from the library, the class works as intended. addChild seems to work on other objects that I am using the same way so I don't get why I can't use it on this object.
How to use the Main method to instantiate an object and access/change properties of said object relative to the stage? And how can I do the same thing for the objects nested inside of my initial object?
***** Edit after answer
Thanks for your reply and for teaching me how to read the debug message. startScreen() was indeed the culprit, and the issue there was this:
stage.addEventListener(Event.ENTER_FRAME, gameLoop)
Removing stage and adding the listener to the object fixed that error, so kudos! But I'm still confused; why does trying to add the listener to the stage cause a null error? I don't understand why the stage would be null at this point. Also, removing "stag." from the addEventListener caused the size of the frame that holds the scene to be way smaller, which cropped a lot of my image. Why is an event listener affecting my stageWidth and height? This is why I also asked questions about how to correctly position things relative to the stage width and height, because I know it has something to do with the errors.
why is Chest null?
Chest is not null. It's the constructor of the class and cannot be null.
You should pay attention to the Stack trace attached to the error (the lines with "at …" below the message).
It tells you where the error occurred. Reading it from the bottom up gives you the order of method calls performed.
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at Chest()/startScene()
at Chest()
at Main()
Main() called Chest(), Chest() called startScene() and BOOM! this is where the error occurred.
To debug this error look at startScene() . Something in there is null.
Looking at your current code:
stage.addChild(chest);
I guess that you also try to add something to stage in Chest(). But stage is not available ( null) in Chest().
In general, it's bad practice to add things to stage as can be read in the documentation of addChild()
Simply add to the object and not stage :
addChild(chest);

as3 Trying to access a main timeline variable from inside a movieclip

I just found a way to do it, but I'm still getting an error.
On the main timeline I have:
var onBeat:Boolean = new Boolean;
and inside a movieclip I attempt to access it with:
MovieClip(root).onBeat = true;
and it technically works, the variable changes. But it throws this error which causes problems:
Error #1034: Type Coercion failed: cannot convert flash.display::Stage#7fffaa2c0d1 to flash.display.MovieClip.
Is this just an impossible task?
You got that error because you've added your MovieClip to the stage's display list and not to the main timeline one.
So in your main timeline code (or your document class), you can add your MovieClip using addChild(your_mc_instance) or this.addChild(your_mc_instance).
But you can also get a working code even with your MovieClip instance added to the stage using, for example :
var _root:DisplayObjectContainer = DisplayObjectContainer(root);
MovieClip(_root.getChildAt(0)).onBeat = true;
_root.getChildAt(0) here is returning your main timeline instance as it has also been added to the stage's display list before any other object.
Hope that can help.

AS3 Accessing stage objects from a class

I'm writing a class Player, and I'm developing collisions but flash gives me an error to this line:
function checkCollision(event:Event)
{
if (this.hitTestObject(stage.wall)) // THIS LINE!!!!!!!!
{
trace("HIT");
}
else
{
trace("MISS");
}
}
}
The error is:
Access of possibly undefined property wall through a reference with
static type flash.display:Stage.
How can I access to wall ? wall is a symbol on the stage... Should I develop it in another way? please help
MovieClip is a dynamic object, whereas Sprite or Stage are not. With these classes, unless the property is explicitly defined, the compiler will complain about the absence of the property when you try to reference it.
If you're programming with Flash IDE, "Automatically Declare stage Instances" will create properties on your stage that make dot.notation pathing possible.
If you're creating objects dynamically, you'll have to either create the properties yourself (which is impossible with static classes like Sprite), or reference them by DisplayList fetching methods getChildAt() or getChildByName().
In the case of a class, unless you extend a class that is already a DisplayObject, you won't inherently have access to stage or root. You'd have to pass a reference to the MainTimeline or Stage manually (probably during instantiation). Even if you did extend a DisplayObject, you'd have to first parent the object to the stage; until then, the properties are null.
For the sake of argument, let's assume Player class is extending Sprite, and you have parented it to the stage. Your code would correctly be written as follows:
function checkCollision(e:Event) {
if (this.hitTestObject(this.root.getChildByName("wall"))) {
trace("HIT");
} else {
trace("MISS");
}
}
Notice that the call to "wall" is not on the Stage. That's because there is only one child of stage, and that's MainTimeline (a.k.a. root).
BTW, you had an extra close brace in you example.
Yep if you have automatically declare stage instances unchecked you will get that error. It is a good practice to declare everything in AS3 and not rely on the GUI to do it. Even if it is
Public var boringBackground:Sprite;
It will pay off in the end performance and coding wise.

AS3 - Addchild from library

I'd like to add a movieclip from the library to a movieclip on the stage.
function setMc(con:Sprite,mc:Sprite):void
{
con.addChild(mc)
mc.x=mc.width/2
mc.y=mc.height/2
}
setMc(myholder,mylibrarymc)
I get this error:
TypeError: Error #1034: Type Coercion failed
What do I need to change?
Library only contains prototypes, not actual objects. I assume "mylibrarymc" is a name of the MC type in library. In this case "mylibrarymc" is type Class, which is used differently.
function setMc(con:Sprite,mc:Class):void
{
var newMC:DisplayObject=new mc() as DisplayObject;
// Here you actually make an object out of a class
con.addChild(newMC);
newMC.x=newMC.width/2;
newMC.y=newMC.height/2;
}
setMc(myholder,mylibrarymc);
Hope this helps. It's been quite some time I dabbled with libraries.
Your function expects a Sprite, and you're probably passing it a MovieClip. Have a look at the "export for actionscript" options you have when right click on the mc in the library
Right click the object in the library and go to 'Properties'. Make sure the box labelled "Export for ActionScript" is ticked and assign it an appropriate name. The class name you give the symbol is what you would use to create an object of that type in the code itself, for example:
Export a symbol for ActionScript with the Class name "Player".
In your ActionScript file:
var player = new Player();
addChild(player);
You can manipulate the object using any of the MovieClip member functions (position, alpha) and assign event listeners to make it interactive.

AS3: Access button from class

So im quite new to AS3 but have worked with AS2 a lot before.
I have created a button and placed it on my stage then inside my class i have added this:
test.addEventListener(MouseEvent.CLICK, buttonClicked);
function buttonClicked(ev:MouseEvent):void
{
trace("Clicked");
}
Now this does not work as it can't find the stage, the only way i can get this to work is if i put the listener on the same frame as the button & not in the class.
But there must be away around this.
Thank you.
Eli
Update - adding Error messages
If I keep the above code all in the external class these are the errors i get.
Line 22 1120: Access of undefined property test. Line 22 1120: Access
of undefined property myButtonClick.
If you have created a document class with timeline then your "test" button must be in first frame. Because document class starts executing from first frame. You can access your button instance only when its available in stage.
Oh, I forgot to mention. You have to declare those instances as public variable in your document class.
public var test:SimpleButton;
Please go thru below and let me know which of the way you were having.
1) Are you having Document class?
There is a field Class in the Document Properties under the Publish tab of the flash IDE, if you are giving your class name in that field then it is called as Document Class
If you are having document class then you can create listener to your button even in the constructor button. Flash won't throw any errors like you got.
2) If you are instantiated your class in the first frame, it won't have the properties of stage till you add that to the stage using addChild. Also it won't have access to your button. And so it will throw the error, The access of undefined property.
Have you assigned the instance of the button on the stage the name "test"? The error message you posted seems to say there is nothing with the name "test" to assign the event listener to.
To check, click on the button the stage and look at the 'Properties' tab: will show in a text box near the top if it needs assigning.
Now the second error you posted means you're referring to something called "myButtonClick" without first declaring/initialising a variable/function with that name. You will either need to declare it or correct it if you meant to refer to something else.
Fixed.
I was being rava stupid as normal, forgot to put them inside the init :|
For the people who might come across this problem.
Working Code:
public function Main()
{
// constructor code
test.addEventListener(MouseEvent.CLICK, myButtonClick);
}
function myButtonClick(ev:MouseEvent):void
{
trace("button Clicked);
}
Anyway thanks guys for the help sometimes its just the simplest answers are the correct ones.
Eli