AS3 Error #1009 in my constructor? - actionscript-3

So I'm working on a 2d platforming game, and I'm getting a #1009.
In my Pickup() class, in the constructor, I'm trying to set this.x and this.y to the center stage, but it's saying the stage a null object reference.
public function Pickup() {
// constructor code
bitmapData.draw(_displayObject);
mSprite = new Bitmap(bitmapData);
addChild(mSprite);
this.x =
stage.width/2;
}
I separated the this.x and the stage.width to see which part was triggering the null, and it's definitely the stage.
It's probably something so horribly obvious I'm going to beat myself up for not noticing it.
Anyways, any help is greatly appreciated.
Cheers

The stage property is null on any DisplayObject, unless it is actually on the Stage.
This means you'll need to add an event listener to the object listening for Event.ADDED_TO_STAGE, and then work with the stage in the handler.
Alternatively, you could just pass a reference to the Stage to the constructor of Pickup:
public function Pickup(stage:Stage)
{
// Your code.
}

Add an event listener of add to stage
public function Pickup() {
// constructor code
bitmapData.draw(_displayObject);
mSprite = new Bitmap(bitmapData);
addChild(mSprite);
this.addEventListener(Event.ADDED_TO_STAGE, onAddToStage);
}
protected function onAddToStage(event:Event):void
{
this.x = stage.width/2;
}

Related

Removing a child from the stage with active event listeners

I have an enemy object that fires missile objects, like so;
public function fire():void {
var missile:Bullet = new Bullet();
stage.addChild(missile);
}
No problem there.
Now, when any missile objects leave the stage area, I want to remove them. Seems simple enough. So in my Bullet class, I've done the following;
I've used the standard method of calling this in my constructor;
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
Which then triggers init();
public function init(e:Event = null):void {
trace("init");
removeEventListener(Event.ADDED_TO_STAGE, init);
addEventListener(Event.ENTER_FRAME, actions);
}
So actions(); is triggered by Event.ENTER_FRAME;
public function actions(e:Event):void {
this.move();
trace(stage.stageWidth); // this works fine
stage.removeChild(this); // this throws Error #1009:
}
I'm just using this is an example. My actions(); function will eventually contain code to remove the object when it leaves the stage, not just when the function is called. I can trace the stageWidth property, no problem. So why is stage.removeChild(this); throwing this error?
[Fault] exception, information=TypeError: Error #1009: Cannot access a
property or method of a null object reference.
Now, this is where it gets really baffling.
If I move stage.removeChild(this); into init();, it works perfectly. So why would it work there, and not in actions(); which is always called after init();?
I never thought to check for this, as I assumed once an object was removed from the stage, all of its event listeners would be as well.
Removing a child from the stage, however, does not mean the object has been deleted, so stage.removeChild(this); was working within actions();, but even though I'd removed the bullet object from the stage, it was still calling actions();, which was then calling stage.removeChild(this); again, which was trying to reference the object when it no longer existed on the stage.
if (this.y > stage.stageHeight) {
stage.removeChild(this);
removeEventListener(Event.ENTER_FRAME, actions);
}
All I had to do was remove the event listener so actions(); would stop being called after I removed the bullet object from the stage.
Hopefully someone else can learn from my mistake, here. Still, I'm a bit surprised that Event.ENTER_FRAME still triggers even when you remove the child from the stage.

ActionScript3, moving objects of type movieclip

Here i am trying to create a new movieclip type object, which is moved when function mvBall is called. When i run the code i get this err: implicit coercion of a value with static type object to a possibly unrelated type flash.display:MovieClip. Later on i want to be able to make the ball bounce back when it colides with another object. I'm new to action script and don't really know how things work so any help would be appreciated. Here's the code:
private function frame(x:Event):void {
var ball:MovieClip = new MovieClip();
ball.addEventListener(Event.ENTER_FRAME, animate);
ball.graphics.beginFill(0xff0000);
ball.graphics.drawCircle(100, 100, 15);
ball.graphics.endFill();
stage.addChild(ball);
}
private function animate(ev:Event):void {
mvBall(ev.target);
}
private function mvBall(mc:MovieClip) {
mc.x += 10;
}
You need to cast the target to MovieClip
private function animate(ev:Event):void {
mvBall(ev.target as MovieClip);
}
With that said it is better to just have one ENTER_FRAME handler and animate your objects in there.
stage.addEventListener(Event.ENTER_FRAME, animate);
private function animate(ev:Event):void
{
mvBall(myBall);
//other object animations
}
You are getting this error because the target property of the Event class is of type object.
In order to not throw the error, you need to cast it as a MovieClip:
mvBall(ev.target as MovieClip);
or
myBall(MovieClip(ev.target));
Something else to consider, is the difference between an Events target and currentTarget properties. If you ball had multiple layers/object inside it (sprites or other movieClips), the target would be whichever one of those sub-elements had the mouse over it during the click. currentTarget refers to the object that you've attached the listener to. In your case they may be the same (if your ball doesn't have any movie clips inside it), but your code could have unexpected results if you have sub-movieClips inside your ball.

'Error #1009: Cannot access a property or method of a null object reference.' in Flash CS5?

TypeError: Error #1009: Cannot access a property or method of a null object reference.
at src::Game/onClick()
This is the full error^, however it doesn't give me the error on the timeline, but the output, when the flash game is played. Here's the code: http://pastebin.com/FnjWCQJ8 , the error's in line 35 or 49.
Thank you.
Its because blue1,blue2,and blue3 are not defined anywhere.
private function onClick(m:MouseEvent):void{
blue1.startme = true;
blue2.startme = true;
blue3.startme = true;
}
Probably line 31 - your stage instance in the Game constructor. Your MovieClip is probably not on the stage yet. Use an ADDED_TO_STAGE event listener, then add listeners to stage on added to stage handlers.
/*
* Constructor.
*/
public function Game()
{
addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
}
protected function addedToStageHandler(event:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
// Listeners.
stage.addEventListener(Event.ENTER_FRAME, _update);
stage.addEventListener(MouseEvent.MOUSE_DOWN, _mouseAction);
stage.addEventListener(MouseEvent.MOUSE_UP, _mouseAction);
stage.addEventListener(MouseEvent.CLICK, onClick);
// Helicopter.
_helicopter = new Helicopter();
stage.addChild(_helicopter);
}

AS3 - Error #1009: Cannot access a property or method of a null object reference

I'm making a game where if the enemy's bullet hits the user, the bullet disappears. Everything works fine except that I keep getting,
'Error #1009: Cannot access a property or method of a null object
reference'
Once the bullet hits the user (bullet disappears though). It confuses me because I've used almost exact the same code in another class where it works perfect.
package classes.enemy
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.display.Stage;
import classes.Main;
public class Bullet extends MovieClip
{
var speed:Number;
public function initialize()
{
var stageReff:Stage = this.stage as Stage;
stage.addEventListener("enterFrame", enterFrame);
}
//code
function enterFrame(e:Event):void
{
this.x += speed;
if(this.hitTestObject(Main.user))
{
removeEventListener("enterFrame", enterFrame);
this.parent.removeChild(this);
// line above gives the error.
}
}
}
}
I have no clue what could be wrong.
Thanks in advance.
My guess is it has to do with the fact that you're adding an enter frame event listener to the stage, yet try to remove it from the listening object itself.
Try changing
var stageReff:Stage = this.stage as Stage;
stage.addEventListener("enterFrame", enterFrame);
to
addEventListener("enterFrame", enterFrame);
you're not removing the event listener from the stage, but the object itself :)
I would not recommend doing it like this, create one listener in your main game class, and call an update function on all objects!
The reason why it fails is because you're removing your Bullet from it's parent. So when you're referencing this.parent it returns null because there simply isn't a parent anymore. You're trying to remove the ENTER_FRAME event but because you set it on the stage the original ENTER_FRAME event keeps running. You can simply fix it like so:
if(this.x > 30)
{
stage.removeEventListener("enterFrame", enterFrame);
this.parent.removeChild(this);
}
But like #RasmusWriedtLarsen already pointed out, it's better to handle these events more globally. And also let the parent handle the removing of the Bullet.

Own drag function in AS3

I need to develop my own drag function in AS3 (instead of using startDrag) because I'm resizing a MovieClip.
I'm doing this:
public class resizeBR extends MovieClip {
var initialScaleX, initialScaleY;
public function resizeBR() {
this.addEventListener(MouseEvent.MOUSE_DOWN, initResize);
this.addEventListener(MouseEvent.MOUSE_UP, stopResize);
}
public function initResize(e:MouseEvent):void
{
initialScaleX = e.target.scaleX;
initialScaleY = e.target.scaleY;
e.target.addEventListener(MouseEvent.MOUSE_MOVE, startResize);
}
public function startResize(e:MouseEvent):void
{
e.target.x += e.localX;
e.target.y += e.localY;
e.target.parent.parent.width += mouseX;
e.target.parent.parent.height += mouseY;
// Keep its own scale
e.target.scaleX = initialScaleX;
e.target.scaleY = initialScaleY;
}
public function stopResize(e:MouseEvent):void
{
e.target.removeEventListener(MouseEvent.MOUSE_MOVE, startResize);
}
}
But the drag feature is not working fluently. I mean, when I drag a MovieClip from class resizeBR I need to move slowly my mouse cursor or it's not going to work propertly.
resizeBR is a MovieClip as a child of another MovieClip; the second one is which I have to resize.
What am I doing wrong?
Thanks!
Thanks all for your answers, but I found a great classes to do what I want.
http://www.senocular.com/index.php?id=1.372
http://www.quietless.com/kitchen/transform-tool-drag-scale-and-rotate-at-runtime/
I'm not really sure if I completely understand what you mean. But I think your problem lies with your MOUSE_MOVE handler.
In your current example you're resizing your target only when moving your mouse over the target. When you're moving your mouse fast enough it's possible your mouse leaves the target, casuing it to stop resizing. When I'm writing my own drag handlers I usually set the MOUSE_MOVE and MOUSE_UP listeners to the stage.
Your class would end up looking something like this:
public class resizeBR extends MovieClip
{
var initialScaleX, initialScaleY;
public function resizeBR()
{
addEventListener(MouseEvent.MOUSE_DOWN, initResize);
addEventListener(MouseEvent.MOUSE_UP, stopResize);
}
public function initResize(e:MouseEvent):void
{
initialScaleX = scaleX;
initialScaleY = scaleY;
stage.addEventListener(MouseEvent.MOUSE_MOVE, startResize);
}
public function startResize(e:MouseEvent):void
{
x += e.localX;
y += e.localY;
parent.parent.width += mouseX;
parent.parent.height += mouseY;
// Keep its own scale
scaleX = initialScaleX;
scaleY = initialScaleY;
}
public function stopResize(e:MouseEvent):void
{
stage.removeEventListener(MouseEvent.MOUSE_MOVE, startResize);
}
}
There are a couple reasons the resizing is jumpy. First, like rvmook points out, you'll need to make sure you support the mouse rolling off of the clip while its being resized. Since there is not an onReleaseOutside type of event in AS3, you have to set listeners to the stage, or some other parent clip. If you have access to the stage, that is best. If not, you can use the root property of your resizable clip, which will reference the highest level display object you have security access to. Setting mouse events to the root is a little wonky, because for them to fire, the mouse needs to be on one of the root's child assets - whereas the stage can fire mouse events when the mouse is over nothing but the stage itself.
Another reason you might be seeing some strange resizing behavior is because of using the localX/Y properties. These values reflect the mouseX/mouseY coordinates to the object being rolled over - which might not necessarily be your clip's direct parent.
I tend to avoid having classes access their parent chain. You might want to consider placing the resizing logic in the clip you want resized, and not in one of its children. Here is simple self resizing example:
package {
import flash.display.MovieClip;
import flash.events.MouseEvent;
import flash.events.Event;
public class ResizableBox extends MovieClip {
public function ResizableBox() {
addEventListener(MouseEvent.MOUSE_DOWN, startResize);
}
private function startResize(evt:MouseEvent):void {
stage.addEventListener(MouseEvent.MOUSE_MOVE, handleResize);
stage.addEventListener(MouseEvent.MOUSE_UP, stopResize);
}
private function stopResize(evt:MouseEvent):void {
stage.removeEventListener(MouseEvent.MOUSE_MOVE, handleResize);
stage.removeEventListener(MouseEvent.MOUSE_UP, stopResize);
}
private function handleResize(evt:MouseEvent):void {
this.scaleX = this.scaleY = 1;
this.width = this.mouseX;
this.height = this.mouseY;
}
}
}
ResizableBox is set as the base class of a MC in the library.