PDA

View Full Version : Sprite 'stage' problem in Flex


RR_QQ
07-02-2008, 06:31 PM
Ok so Im trying to learn animation in AS3 and I am using Flex Builder 3 to create my Flash animations. I am learning from the book Foundation ActionScript 3.0 Animation, Making Things Move. One thing I have not been able to figure out is an error I get when I try to use the 'stage' property in a sprite. Here is a sample class I'm trying to use:


package animation
{
import Shapes.Ball;

import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.text.TextField;
import flash.events.Event;

public class SecondAnimation extends Sprite
{
public function SecondAnimation()
{
init();
}

private function init():void
{
graphics.lineStyle(1);
stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
}

private function onMouseDown(event:MouseEvent):void
{
graphics.moveTo(mouseX, mouseY);
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
}

private function onMouseUp(event:MouseEvent):void
{
stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
}

private function onMouseMove(event:MouseEvent):void
{
graphics.lineTo(mouseX, mouseY);
}
}
}


That gives me this runtime error:


TypeError: Error #1009: Cannot access a property or method of a null object reference.
at animation::SecondAnimation/init()[C:\Documents and Settings\user1\My Documents\Flex Builder 3\AnimationTest1\src\animation\SecondAnimation.as: 20]
at animation::SecondAnimation()[C:\Documents and Settings\user1\My Documents\Flex Builder 3\AnimationTest1\src\animation\SecondAnimation.as: 14]
at BallMotion/initApplication()[C:\Documents and Settings\user1\My Documents\Flex Builder 3\AnimationTest1\src\BallMotionMain.as:23]
at BallMotion/___BallMotion_Application1_creationComplete()[C:\Documents and Settings\user1\My Documents\Flex Builder 3\AnimationTest1\src\BallMotion.mxml:3]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.core::UIComponent/dispatchEvent()[E:\dev\3.0.x\frameworks\projects\framework\src\mx\ core\UIComponent.as:9051]
at mx.core::UIComponent/set initialized()[E:\dev\3.0.x\frameworks\projects\framework\src\mx\ core\UIComponent.as:1167]
at mx.managers::LayoutManager/doPhasedInstantiation()[E:\dev\3.0.x\frameworks\projects\framework\src\mx\ managers\LayoutManager.as:698]
at Function/http://adobe.com/AS3/2006/builtin::apply()
at mx.core::UIComponent/callLaterDispatcher2()[E:\dev\3.0.x\frameworks\projects\framework\src\mx\ core\UIComponent.as:8460]
at mx.core::UIComponent/callLaterDispatcher()[E:\dev\3.0.x\frameworks\projects\framework\src\mx\ core\UIComponent.as:8403]



I have gotten around the problem by doing things a bit differently but I think it's time I addressed this problem. Does anyone know why I cannot get this to work?

Here is my MXML and Main.as file:


<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
creationComplete="initApplication();">

<mx:Script source="Main.as"/>

<mx:Canvas id="animationStage">
</mx:Canvas>
<mx:Button x="48" y="237" label="Restart" click="onRestartClickHandler();"/>

</mx:Application>



Main.as:


import animation.*;

import mx.core.UIComponent;

public var ballanimation:BallMotion;
public var secondAnimation:SecondAnimation;

public function initApplication():void
{
// create a new sprite object
/*ballanimation = new BallMotion();

// need to create a UI wrapper to be able to add the sprite to the canvas
var uiWrapper:UIComponent = new UIComponent();
uiWrapper.addChild(ballanimation);

// add the child
animationStage.addChild(uiWrapper);
*/

// create a new sprite object
secondAnimation = new SecondAnimation();

// need to create a UI wrapper to be able to add the sprite to the canvas
var uiWrapper:UIComponent = new UIComponent();
uiWrapper.addChild(secondAnimation);

// add the child
animationStage.addChild(uiWrapper);
}

public function onRestartClickHandler():void
{
//secondAnimation.restart();
}


Any help is appreciated!

Zunskigraphics
07-02-2008, 07:16 PM
I didn't have time to go through all your code.. but your issue might be this...

In flex you need to declare a UIComponent that will hold the sprite. It's basically an "extra" step to holding the sprite which holds all your other stuff.

I recently had this problem.

One other note --- This was in Flex Builder 2... so I am not sure if this was fixed in Flex 3.

Good Luck

*** just looked at your code... try bringing the UIComponent outside of the function (just the declaration)

RR_QQ
07-02-2008, 07:26 PM
Ok I moved it like you said:

Main.as:


import animation.*;

import mx.core.UIComponent;

public var ballanimation:BallMotion;
public var secondAnimation:SecondAnimation;
public var uiWrapper:UIComponent = new UIComponent();

public function initApplication():void
{


but still the same error!

box86rowh
07-02-2008, 08:16 PM
try : systemManager.stage
instead of just stage

RR_QQ
07-02-2008, 10:50 PM
How interesting I get an error: 1120: Access of undefined property systemManager. Any idea what causes that? Must I instantiate a systemManager object somehow?

matlevy
07-03-2008, 12:48 AM
in SecondAnimation, you can reference the stage until the object has been added to the stage. You need to add an event listener in the contructor that listends for the addedtostage event eg

package
{
import flash.display.Sprite;
import flash.events.Event;

public class Foo extends Sprite
{
public function Foo()
{
super();
this.addEventListener(Event.ADDED_TO_STAGE, onAddedToStage)
}

private function init():void
{
.....
}

private function onAddedToStage(e:Event):void
{
this.init();
}

}
}

RR_QQ
07-04-2008, 12:22 AM
Thank you I will attempt to get this working!

Sly_cardinal
07-04-2008, 08:59 AM
There are a couple of things to be aware of with Flex: it is an application framework with it's own component lifecycle. This means that things are a bit more strict that flash in relation to your component subclasses and the order in which you perform actions.

For the most part your Flex components (i.e. your visual classes) must implement the IUIComponent interface, which the Sprite class does not do (in fact the UIComponent is a subclass of the Sprite a few times removed).

The quickest and easiest way of ensuring you have implemented this interface is just to extend a class that already does it for you. The Canvas class is a good candidate for this - it already implements a lot of the Flex functionality so we don't have to worry about it.

The next aspect of creating Flex components is learning when things happen (this took me quite a while - and I'm still learning new things about it). There is a fair bit of setup that occurs behind the scene when flex components are created so we generally can't do things straight away in the constructor. Luckily the flex developers have provided us access to a suite of event handlers and functions that we can listen to or override in order to setup our components.

In the following code you'll see that we add our event listeners in the 'initializationComplete' function.

As for the systemManager, and the problems you encountered trying to access it, that is another part of the Flex framework machinery. The systemManager property is defined in the UIComponent class and because we are now subclassing that we shouldn't have any issues referencing it now.


SecondAnimation.as:

package
{
import flash.events.MouseEvent;

import mx.containers.Canvas;

public class SecondAnimation extends Canvas
{
override protected function initializationComplete():void
{
addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
}

private function onMouseDown(event:MouseEvent):void
{
graphics.lineStyle(1);
graphics.moveTo(mouseX, mouseY);

systemManager.addEventListener(MouseEvent.MOUSE_MO VE, onMouseMove);
}

private function onMouseUp(event:MouseEvent):void
{
systemManager.removeEventListener(MouseEvent.MOUSE _MOVE, onMouseMove);
}

private function onMouseMove(event:MouseEvent):void
{
graphics.lineTo(mouseX, mouseY);
}
}
}


Main.mxml:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
xmlns:animation="*">

<animation:SecondAnimation width="100%" height="100%" />

</mx:Application>



Good luck with it :)