I started a new AS3 document today in Flash CC. My stage was empty. I made the document class a .as file called test.as - my .fla was also called test.fla.
So I created a movieclip called mirror and gave it a AS3 linkage name of mirror. I put it in my library and deleted it from the stage. Then I went to my external .as file and wrote this:
package {
import flash.display.MovieClip;
import flash.events.MouseEvent;
public class test extends MovieClip {
public var mirror1:MovieClip = new mirror();
public function dragMirror1(event:MouseEvent):void
{
mirror1.startDrag();
}
public function releaseMirror1(event:MouseEvent):void
{
mirror1.stopDrag();
}
mirror1.addEventListener(MouseEvent.MOUSE_DOWN,dragMirror1);
mirror1.addEventListener(MouseEvent.MOUSE_UP,releaseMirror1);
}
}
This seemed perfectly harmless code, but when I ran the code I got four errors:
C:\Users\Raphael\Creative Cloud Files\LightStage\Testing\test.as, Line 20, Column 48 1120: Access of undefined property releaseMirror1.
C:\Users\Raphael\Creative Cloud Files\LightStage\Testing\test.as, Line 20, Column 3 1120: Access of undefined property mirror1.
C:\Users\Raphael\Creative Cloud Files\LightStage\Testing\test.as, Line 19, Column 50 1120: Access of undefined property dragMirror1.
C:\Users\Raphael\Creative Cloud Files\LightStage\Testing\test.as, Line 19, Column 3 1120: Access of undefined property mirror1.
Does anyone have any idea why this is happening? Maybe I'm missing something basic, but I've created a few new .fla and .as files to test this and it keeps happening, even when I rewrite the code and use different AS3 linkage names.
To avoid these errors, you have to use your mirror1.addEventListener() inside the constructor of your class after adding your mirror object to your stage :
public class Test extends MovieClip {
public var mirror1:MovieClip = new mirror();
public function Test():void
{
addChild(mirror1);
mirror1.addEventListener(MouseEvent.MOUSE_DOWN, dragMirror1);
mirror1.addEventListener(MouseEvent.MOUSE_UP, releaseMirror1);
}
public function dragMirror1(event:MouseEvent):void
{
mirror1.startDrag();
}
public function releaseMirror1(event:MouseEvent):void
{
mirror1.stopDrag();
}
}
Hope that can help.
Related
I'm creating a game is Flash CS5 with ActionScript 3. To simplify things, I've created a file (Game.as) in the top layer of my source folder. My Game.as file looks as follows:
package {
public class Game {
public static function fail():void {
stop();
var restart:RestartButton = new RestartButton();
addChild(restart);
restart.x = stage.stageWidth/2;
restart.y = stage.stageHeight/2;
Game.createButton(restart, function(e:MouseEvent):void { gotoAndPlay (1, "Title Sequence") });
}
}
}
I would supposedly call Game.fail () from a frame on a timeline a scene, but I get these compiler errors:
Line 11 1180: Call to a possibly undefined method stop.
Line 19 1180: Call to a possibly undefined method gotoAndPlay.
Line 17 1120: Access of undefined property stage.
Line 16 1120: Access of undefined property stage.
Line 14 1180: Call to a possibly undefined method addChild.
Why are these errors happening? What can I do to fix them?
Thanks for your help in advance.
The problem is that none of those methods exist on your Game class.
There's at least two good reasons for this:
Your Game class needs to extend MovieClip to have the methods stop(), gotoAndPlay(), addChild(), and the stage property. For example class Game extends MovieClip would give you those methods.
Even if your Game extends MovieClip you can't access methods like stop() from static scope, only from instance scope (ie this). This is because static scope is essentially a global code space so none of those methods make any sense: when you say stop() you have to say what instance will stop, ex this.stop() or thatThing.stop(). The static code has no awareness of what instances of the class there may even be, so there's no way an instance function can work. You need an instance of the Game class, not just a static function.
What I think you are trying to do is essentially use Game as a singleton for your main timeline. You can do that like this:
package {
public class Game extends MovieClip {
// global reference to a single instance of the Game
public static game:Game;
public function Game() {
// store a global reference to this instance
// NOTE: bad things will happen if you create more than one Game instance
game = this;
}
// do NOT use static for your methods
public function fail():void {
stop();
var restart:RestartButton = new RestartButton();
addChild(restart);
restart.x = stage.stageWidth/2;
restart.y = stage.stageHeight/2;
createButton(restart, function(e:MouseEvent):void { gotoAndPlay (1, "Title Sequence") });
}
}
}
Now you need to set this class as your document class. There is only ever one instance of the document class, so this works well for you. However, you could link this class to a symbol in your library and instantiate it by code (new Game()) or by placing a timeline instance on a keyframe.
Finally, to call Game methods from anywhere you can use the Game.game instance:
Game.game.fail();
Okay, so my game codes are not problematic at all and don't effect the game UNLESS I declare the level "OneManager" as a variable.
OneManager is the class for my level. The level is a movieclip containing all the level's components. And Main is the document class.
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at OneManager()[C:\Users\Jay\Creative Cloud Files\Subject 51 Experimental\OneManager.as:38]
at Main()[C:\Users\Jay\Creative Cloud Files\Subject 51 Experimental\Main.as:16]
I don't think it makes any sense. I deleted line 38, then the problem indicated until line 39, then I deleted them over and over. Then practically until my code was useless, that's when I FINALLY got no error...
These codes don't even look problematic at all. I even tried adding them manually by adding the class's movieclip to the stage myself and it worked completely fine. But what I'm trying to do is add it to the stage through code by making this class's movieclip a variable and when the button is clicked, but if I did that - I would get these random errors from other classes.
I'm not sure what's wrong here. There is no trouble compiling, so I get no compile errors. Only errors from the output. These lines of codes aren't null, but the output says it is. I'm confused.
Please help, thanks!
Code for Main Document Class:
package
{
import flash.display.MovieClip;
import flash.events.MouseEvent;
public class Main extends MovieClip
{
var mountains: Mountains;
var homePage: HomePage;
var oneManager: OneManager;
public function Main()
{
mountains = new Mountains;
homePage = new HomePage;
oneManager = new OneManager;
addChild(homePage);
homePage.playButtons.addEventListener(MouseEvent.CLICK, onPlayButtonsClick);
}
function onPlayButtonsClick(event:MouseEvent):void
{
//var level1Page = new Level1Page;
removeChild(homePage);
addChild(oneManager);
}
}
}
I am new to working with Flash Builder and Flash Professional. I have a movie clip called myplayer that I created in Flash Professional, and I am trying to code some ActionScript for it in Flash Builder that will change its position on the stage, but I keep getting the following error: TypeError: Error #1009: Cannot access a property or method of a null object reference. at level_1()
Here's the code:
package
{
import flash.display.MovieClip;
public class level_1 extends MovieClip
{
public function level_1()
{
myplayer.x=650;
myplayer.y=350;
}
}
}
I know I am missing something, but I'm not sure what. Any advice?
There are two symbols here: level_1 and myplayer. Naming convention for classes usually start with a capital letter; so, I'm going to refer to these types as Level1 and MyPlayer.
So, here's the scene:
Level1 is your game level
MyPlayer instance is a child of Level1
The player of this level needs an instance name defined as myplayer.
myplayer is an instance of the MyPlayer class (ActionScript linkage).
Now from Flash Builder, our Level1 class may manipulate the child myplayer instance:
package {
import flash.display.MovieClip;
public class Level1 extends MovieClip {
public var myplayer:MyPlayer;
public function Level1() {
super();
myplayer.x = 650;
myplayer.y = 350;
}
}
}
Flash CS5 example source code with Level1 ActionScript class at: http://labs.jasonsturges.com/stack-overflow/examples/referencing-flash-professional-object-in-flash-builder/
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".
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.
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.
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:
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:
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);
How do I access Stage Class properties in Costum Class?
Class:
package {
import Main;
import flash.events.*;
import flash.display.Sprite;
import flash.display.Stage;
public class Run extends Sprite {
var obj:a1_spr;
public function Run() {
runAssets();
}
private function runAssets():void {
obj = new a1_spr()
addChild(obj);
obj.x = stage.stageWidth/2;
}
}
}
Output:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
To expand on what Joel said, and put it into context:
Every display object has a .stage property, but that property is null until you add you display object onto the display list. So during construction, you will never be able to access it, (because it gets added afterwards)
The event ADDED_TO_STAGE gets fired when you add your object to the stage, ltting you know that the .stage property is now populated. After that happens you can access the stage from anywhere in you object.
Hope that clarifies things for you.
this.addEventListener(Event.ADDED_TO_STAGE, handleAdedToStage)
private function handleAddedToStage(event:Event):void
{
this.runAssets()
}
private function runAssets():void
{
obj = new a1_spr();
addChild(obj);
obj.x = this.stage.stageWidth/2;
}
You aren't going to have access to the stage in the constructor (unless you inject the stage into the class). Sprite has a stage property.
when flash compiles the fla assets with your .as files, there's no stage. so the code is initiated as preparation for your documentclass, you have to listen to if there's a stage so it can be rendered.
that's why you listen to ADDED_TO_STAGE , to check it's actually in the display list.
This problem occurs for all display objects, since they must be added to the display list when there's an actual stage.
get used to add that listener, and check for a stage. specially when working in a team and your doing your own components in a larger project.