Error 1180 at AS3 - actionscript-3

i am building a game on flash cs5. i am making the start screen, and now i try to load the game but I get an error 1180 at my play game function. here is how it works
this is the function were i get the error at line this.stageRef. This class is my mainMenu which extends basemenu.
private function playGame(e:MouseEvent) : void
{
unload();
this.stageRef.dispatchEvent(new Event("gameSTART"));
}
and here is my engine function
public function Engine()
{
preloader = new ThePreloader(474, this.loaderInfo);
stage.addChild(preloader);
preloader.addEventListener("loadComplete", loadAssets);
preloader.addEventListener("preloaderFinished", showMenu);
stage.addEventListener("gameSTART", fGameStart);
}
private function fGameStart(e:Event):void
{
.......... here is all my game code
}

It seems, your stageRef is not proper EventDispatcher object. Either you have another custom Stage class, or when you get stage property with Stage object the owner of this property is not on the stage yet. So try to get stage property after Event.ADDED_TO_STAGE event of the source object. Or show your code where you get Stage and pass to the MainMenu.

make stageRef class implement IEventDispatcher

Related

method (function) in subClass not being called on mouse event

My goal is:
define a subClass of Sprite called Ship
use an event at runtime to call a function within this new class
It seems that I've figured out how to create my Ship class using a package in a linked .as file. But I can't seem to access the function within that class. Can anyone see what I'm doing wrong?
var ShipMc:Ship = new Ship();
addChild(ShipMc);// This successfully adds an instance, so I know the class is working.
addEventListener(MouseEvent.CLICK, ShipMc.addShip);//But this doesn't seem to run the function
This code works fine for instantiating a Sprite, but the code in the Ship.as file, specifically the function, is not working. No runtime errors, but nothing traced to the output window, either.
package
{
import flash.display.Sprite
public class Ship extends Sprite
{
public function addShip():void
{
trace("running addShip function")
}
}
}
The last time a coded anything in flash it was AS2!
I'll just mention that I've tried using addShip():void and just addShip(). Same response with both. It should be with :void, right? Anyway, the fact that neither one throws, tells me that this section of code isn't even getting read, I think.
Any help is much appreciated! Pulling my hair out.
Your code is not working because it contains some problems, so let's see that.
You should know that you are attaching the MouseEvent.CLICK event listener to the main timeline which didn't contain any clickable object yet now (it's empty), so let's start by adding something to your Ship class to avoid that :
public class Ship extends Sprite
{
// the constructor of your class, called when you instantiate this class
public function Ship()
{
// this code will draw an orange square 100*100px at (0, 0)
graphics.beginFill(0xff9900);
graphics.drawRect(0, 0, 100, 100);
graphics.endFill();
}
public function addShip():void
{
trace("addShip function run");
}
}
N.B: You can attach the MouseEvent.CLICK event listener to the stage, which will work even if you have nothing in the stage.
Now, if you test your app, you'll get an clickable orange square at the top left corner of your stage, but the compiler will fire an error (ArgumentError) because it's waiting for a listener function (the Ship.addShip() function here) which accept an MouseEvent object.
So to avoid that error, your Ship.addShip() function can be like this for example :
public function addShip(e:MouseEvent):void
{
trace("addShip function run");
}
Then your code should work.
You can also simplify things by using another listener function in your main code which can call the Ship.addShip() function, like this for example :
var ShipMc:Ship = new Ship();
addChild(ShipMc);
addEventListener(MouseEvent.CLICK, onMouseClick);
function onMouseClick(e:MouseEvent): void
{
ShipMc.addShip();
}
For more about all that, you can take a look on AS3 fundamentals where you can find all what you need to know about AS3.
Hope that can help.

How can I call timeline-specific methods from an external file in AS3?

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();

Is it possible to load a non-Document Class before preloader starts?

public class Framework extends MovieClip
{
var _loadingSystem:LoadingSystem;
public function Framework()
{
_loadingSystem = new LoadingSystem(this);
loaderInfo.addEventListener(ProgressEvent.PROGRESS,progressHandler);
loaderInfo.addEventListener(Event.COMPLETE, completeListener);
}
...
public class LoadingSystem extends MovieClip
{
public function LoadingSystem(parent:DisplayObjectContainer)
{
parent.addChild(this);
myLogo.buttonMode = true;
myLogo.addEventListener(MouseEvent.CLICK, gotoMySite);
}
As you can see, Framework is my Doc class which is creating _loadingSystem which is basically a movieclip that contains the preloader graphics. When I debug I get the following error "TypeError: Error #1009: Cannot access a property or method of a null object reference." pointing to myLogo.buttonMode = true;
From what I understand this is due to LoadingSystem not being fully loaded before being created in Framework. Is there any way for me to make this work? I have tried adding listeners for Event.ADDED but it didn't work.
Additional info: 3-frame FLA, first empty with a stop, second holding an AssetHolder movieclip, third for the application. I have export on 2nd frame set in publishing settings, all checkboxes for export on 2nd frame unchecked in the assets, and this all worked before I changed the export on 2nd frame setting except it wasn't preloading 50% of the file.
i think what's happening is this:
A document class is ALWAYS loaded in the first frame, because it represents your swf root class and thus has to be there in the first frame. Now, since you export all the other classes to frame 2, i would imagine, that LoadingSystem is existing only beginning with frame two, but you try to instantiate it in the constructor of your document class Framework.
What you could try out is, create a method "initialize" in Framework and call that from the timeline in frame 2. And in that method you would do the stuff, you currently do in the constructor of Framework.
if myLogo is a sprite/movieclip on the stage, it wont exist until LoadingSystem is added to the stage.
Now your first reaction should be "but I added it to the stage with parent.addChild(this)!". What you didn't take into account is that the document class isn't on the stage when the constructor is called. Flash basically executes like this:
docClass = new DocumentClass();
stage.addChild(docClass);
Which means that the stage property of the document class will be null until after the constructor is finished. It also means that any children added during the constructor wont have access to the stage or objects located on the stage until after the docClass is added to the stage.
There is a simple fix; listen for the ADDED_TO_STAGE event.
public function LoadingSystem(parent:DisplayObjectContainer)
{
parent.addChild(this);
addEventListener(Event.ADDED_TO_STAGE, initialize);
}
private function initialize(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, initialize);
addEventListener(Event.REMOVED_FROM_STAGE, uninitialize);
//attach stage listeners etc
myLogo.buttonMode = true;
myLogo.addEventListener(MouseEvent.CLICK, gotoMySite);
}
private function uninitialize(e:Event):void
{
removeEventListener(Event.REMOVED_FROM_STAGE, uninitialize);
addEventListener(Event.ADDED_TO_STAGE, initialize);
//detach stage listeners etc.
}

Overriding flash.display.Sprite's eventDispatcher

Hai,
I want to override the dispatchEvent method while inheriting from flash.display.Sprite. Whenever an event gets dispatched now like ADDED_TO_STAGE and CLICK it will get through dispatchEvent in my theory. However there is no single trace he'll get through dispatchEvent.. so the events get dispatched internally from some where else?
public class TestSprite extends Sprite
{
public function TestSprite()
{
this.addEventListener(Event.ADDED_TO_STAGE, this.handleAddedToStage);
}
private function handleAddedToStage(event:Event):void
{
}
override public function dispatchEvent(event:Event):Boolean
{
trace(event.type);
return super.dispatchEvent(event);
}
}
this._sprite = new TestSprite();
this._sprite.graphics.beginFill(0x000000);
this._sprite.graphics.drawRect(20, 20, 200, 200);
this._sprite.graphics.endFill();
this.addChild( this._sprite );
There is no trace..
The Sprite implements IEventDispatcher so that the coder - you - can dispatch custom events from display-list classes. As you suspected however, native Flash Player events are not dispatched through the dispatchEvent method itself, they are created and passed to event listeners internally. I imagine a primary reason for this is performance.
sooner or later in the function you need to pass the event to the real sprite eventDispatcher or it won't work (hint: super.dispatchEvent(event) )
by the way this will work only on objects that subclasses your own class, the others will continue to subclass Sprite, hence use the Sprite method.

ActionScript 3.0 stageWidth in custom Class

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.