AS3 - Why am I getting this 1009 error? (Cannot access a property or method of a null object) - actionscript-3

I can't get this program to work. I Always get this error: Error #1009: Cannot access a property or method of a null object reference.
I don't understand why and would appreciate some help.
Here's my code:
Main class:
package
{
import flash.display.Sprite;
import flash.events.Event;
public class Main extends Sprite
{
private var enginge:Engine = new Engine(stage);
private var enemy:Enemy = new Enemy(100, 100);
public function Main():void
{
addChild(enemy);
}
}
}
Engine class:
package
{
import flash.display.Sprite;
import flash.display.Stage;
public class Engine
{
public static var stage:Stage;
public static var gravity:int = 1;
public function Engine(stage:Stage)
{
Engine.stage = stage;
}
public static function gravitate(object:Sprite):void
{
object.y += Engine.gravity;
if (object.y < Engine.stage.stageHeight - object.height / 2)
{
Engine.gravity += 1;
}
else
{
Engine.gravity = 0;
object.y = Engine.stage.stageHeight - object.height / 2;
}
}
}
}
Enemy class:
package
{
import flash.display.Sprite;
import flash.display.Stage;
import flash.events.Event;
public class Enemy extends Sprite
{
private var gravity:int = 1;
public function Enemy(x:int, y:int)
{
this.graphics.beginFill(1, 1);
this.graphics.drawRect(this.x - 25, this.y - 40, 50, 80);
this.graphics.endFill();
this.x = x;
this.y = y;
this.addEventListener(Event.ENTER_FRAME, function(e:Event):void
{
Engine.gravitate(this);
});
}
}
}

In order to fix the problem you need to get rid of the anonymous function in the Enemy class.
You will have:
public function Enemy(x:int, y:int)
{
this.graphics.beginFill(1, 1);
this.graphics.drawRect(this.x - 25, this.y - 40, 50, 80);
this.graphics.endFill();
this.x = x;
this.y = y;
this.addEventListener(Event.ENTER_FRAME,handler);
}
private function handler(event:Event):void
{
Engine.gravitate(Sprite(this));
}
and the code will be working. This is due to context difference of word this inside anonymous function.
Usage of anonymous function is terrible practice and you should refrain from doing it.

Related

AS3 Classes Public Atributte

I am getting an error whenever I try running the game. I get errors for every class saying that the public attribute can only be used inside a package and on this line with "private function moveMe" "the private attribute may only be used on class functions". I verified if I have the as file linked properly. I am not sure what the issue is.
package {
import flash.display.MovieClip;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.events.Event;
public class banana_fall extends MovieClip {
public function banana_fall (){
var velX:Number=0;
var velY:Number=0;
var falling:Boolean=false;
var gravity:Number=2;
public function banana() {
var timing:Timer = new Timer(20,0);
timing.addEventListener(TimerEvent.TIMER,moveMe);
timing.start();
}
private function moveMe(event:TimerEvent){
this.x=this.x+velX;
this.y=this.y+velY;
if (falling) {
velY=velY+gravity;
}
}
public function setSpot(atX,atY){
this.x=atX;
this.y=atY;
}
//
public function setSpeed(dx,dy){
velX=dx;
velY=dy;
}
}
}
}
The problem is that your public functions were inside your constructor function, which doesnt work in as3.
try this code:
package {
import flash.display.MovieClip;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.events.Event;
public class banana_fall extends MovieClip {
var velX: Number = 0;
var velY: Number = 0;
var falling: Boolean = false;
var gravity: Number = 2;
public function banana_fall() {
var timing: Timer = new Timer(20, 0);
timing.addEventListener(TimerEvent.TIMER, moveMe);
timing.start();
}
private function moveMe(event: TimerEvent) {
this.x = this.x + velX;
this.y = this.y + velY;
if (falling) {
velY = velY + gravity;
}
}
public function setSpot(atX, atY) {
this.x = atX;
this.y = atY;
}
//
public function setSpeed(dx, dy) {
velX = dx;
velY = dy;
}
}
}

Actionscript 3 cannot access a property or method of a null object reference

I'm still really new about classes and stuffs. So, I tried making this and I got an error: Access of undefined property.
Why speedX and speedY var still error although I've defined it in public var in the main class?
Thanks!
EDITED: I've tried calling the variables from other class with main.speedX and main.speedY
But it got error : Cannot access a property or method of a null object reference.
at Ball/moveBall()
This is the Main code:
package
{
import flash.display.MovieClip;
import flash.events.Event;
public class Main extends MovieClip
{
public var speedX:Number = 5;
public var speedY:Number = 5;
public var speedMax:Number = 10;
private var ball:MovieClip = new Ball();
private var paddle:MovieClip = new Paddle();
public function Main()
{
paddle.addEventListener(Event.ENTER_FRAME, movePaddle);
addChild(ball);
addChild(paddle);
}
}
}
This is the Ball Movie Clip Code:
package
{
import flash.display.MovieClip;
import flash.events.Event;
public class Ball extends MovieClip
{ public var main:Main;
public function Ball()
{addEventListener(Event.ENTER_FRAME, moveBall);
main= new Main();
}
public function moveBall(e:Event):void
{
x += main.speedX;
y += main.speedY;
}
}
}
That's because your class Ball cannot access speedX and speedY inside the event callback. Why not add speedX and speedY to your Ball class directly instead ?
public class Ball extends MovieClip
{
public var speedX:Number;
public var speedY:Number;
public function Ball(sX:Number = 0, sY:Number = 0)
{
this.speedX = sX;
this.speedY = sY;
addEventListener(Event.ENTER_FRAME, moveBall);
}
public function moveBall(e:Event):void
{
x += speedX;
y += speedY;
}
}
Here's another possible solution where you would be passing main to ball to use the values of speed stored in Main.
public class Main extends MovieClip
{
public var speedX:Number = 5;
private var ball:MovieClip;
public function Main()
{
ball=new Ball(this);
addChild(ball);
}
}
and
public class Ball extends MovieClip
{
private var _main:Main;
public function Ball(main:Main)
{
_main=main;
addEventListener(Event.ENTER_FRAME, moveBall);
}
public function moveBall(e:Event):void
{
x += _main.speedX;
}
}
}

AS3 - TypeError # 1009 with Timers

I just have no idea what to do with this. I've been looking through this for an hour now and I keep getting an error reading:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at Shooter_Enemy/shotHandler()
at flash.utils::Timer/_timerDispatch()
at flash.utils::Timer/tick()
When I debug it it points to the line of the code where "seekingBullet" is added to the stage. Any help resolving this would be greatly welcomed.
package
{
import flash.display.*;
import flash.events.*;
import flash.utils.Timer;
public class Shooter_Enemy extends MovieClip
{
private var yMove:int = 2;
private var shootTimer:Timer = new Timer(500);
public function Shooter_Enemy()
{
this.name = "mc_shooter_enemy";
this.addEventListener(Event.ENTER_FRAME,enemyMove);
shootTimer.start();
shootTimer.addEventListener(TimerEvent.TIMER,shotHandler);
}
public function addShooterEnemy(X:int):void
{
this.x = X;
this.y = 0;
}
public function removeEnemy()
{
shootTimer.removeEventListener(TimerEvent.TIMER,shotHandler);
shootTimer.stop();
this.removeEventListener(Event.ENTER_FRAME,enemyMove);
this.x = 0;
this.y = (stage.height + this.height);
}
private function shotHandler(te:TimerEvent):void
{
var seekingBullet:SeekingBullet = new SeekingBullet();
Main.seekingBulletArray.push(seekingBullet);
stage.addChild(seekingBullet);
seekingBullet.addSeekingBullet(this.x,this.y);
}
private function enemyMove(e:Event)
{
this.y += yMove;
}
}
}
If it's actual, a good practice for using stage is listening *Event.ADDED_TO_STAGE* and then starting your activity like:
package
{
import flash.display.*;
import flash.events.*;
import flash.utils.Timer;
public class Shooter_Enemy extends MovieClip
{
private var yMove:int = 2;
private var shootTimer:Timer = new Timer(500);
public function Shooter_Enemy()
{
this.name = "mc_shooter_enemy";
this.addEventListener(Event.ENTER_FRAME,enemyMove);
shootTimer.addEventListener(TimerEvent.TIMER, shotHandler);
addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
}
public function addShooterEnemy(X:int):void
{
this.x = X;
this.y = 0;
}
public function removeEnemy()
{
shootTimer.removeEventListener(TimerEvent.TIMER,shotHandler);
shootTimer.stop();
this.removeEventListener(Event.ENTER_FRAME,enemyMove);
this.x = 0;
this.y = (stage.height + this.height);
}
private function addedToStageHandler(e:Event)
{
shootTimer.start();
}
private function shotHandler(te:TimerEvent):void
{
var seekingBullet:SeekingBullet = new SeekingBullet();
Main.seekingBulletArray.push(seekingBullet);
stage.addChild(seekingBullet);
seekingBullet.addSeekingBullet(this.x,this.y);
}
private function enemyMove(e:Event)
{
this.y += yMove;
}
}
}

Circular Slider in ActionScript 3

I'm hoping to get a round slider into ActionScript, very similar to what this page shows:
It's going to ultimately be altering the hue of an object (returning a CMY value), however if it just spits out the degree I can totally work with that. If you know of any resources, tutorials, pseudocode, or a snippet with this functionality, I would hugely appreciate it. Thanks!
Below is my solution to this problem.
It's worth noting that angles in Flash are handled in radians instead of degrees, which is why you'll notice the conversion methods in the code. Personally, I find setting angles in degrees much easier to visualize and understand, which is why the CircleSlider constructor accepts a value in degrees and why the CircleSliderEvent class dispatches both degrees and radians.
Use Case:
var circleSlider:CircleSlider = new CircleSlider(100, 270);
circleSlider.x = stage.stageWidth / 2;
circleSlider.y = stage.stageHeight / 2;
circleSlider.addEventListener(CircleSliderEvent.CHANGE, circleSliderEventHandler);
addChild(circleSlider);
function circleSliderEventHandler(event:CircleSliderEvent):void
{
trace(event.degrees, event.radians);
}
CircleSlider Class:
package
{
//Imports
import flash.display.Sprite;
import flash.display.Shape;
import flash.events.Event;
import flash.events.MouseEvent;
//Class
public class CircleSlider extends Sprite
{
//Properties
private var mRadius:uint;
private var mAngle:Number;
private var mThumb:Sprite;
//Constructor
public function CircleSlider(radius:uint, degrees:Number)
{
mRadius = radius;
mAngle = degrees;
init();
}
//Init
private function init():void
{
createCircle();
createThumb();
positionThumb(degreesToRadians(mAngle));
}
//Create Circle
private function createCircle():void
{
var circle:Shape = new Shape();
circle.graphics.lineStyle(4.0, 0xFFDDDD, 1.0);
circle.graphics.drawCircle(0, 0, mRadius);
addChild(circle);
}
//Create Thumb
private function createThumb():void
{
mThumb = new Sprite();
mThumb.graphics.beginFill(0xFF2222, 1.0);
mThumb.graphics.drawCircle(0, 0, 10);
mThumb.graphics.endFill();
mThumb.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownEventHandler);
addChild(mThumb);
}
//Mouse Down Event Handler
private function mouseDownEventHandler(event:MouseEvent):void
{
mThumb.addEventListener(Event.ENTER_FRAME, enterFrameEventHandler);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpEventHandler);
stage.addEventListener(Event.MOUSE_LEAVE, mouseUpEventHandler);
}
//Enter Frame Event Handler
private function enterFrameEventHandler(event:Event):void
{
positionThumb(Math.atan2(mouseY, mouseX));
}
//Mouse Up Event Handler
private function mouseUpEventHandler(event:MouseEvent):void
{
mThumb.removeEventListener(Event.ENTER_FRAME, enterFrameEventHandler);
stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpEventHandler);
stage.removeEventListener(Event.MOUSE_LEAVE, mouseUpEventHandler);
}
//Position Thumb
private function positionThumb(radians:Number):void
{
mThumb.x = Math.cos(radians) * mRadius;
mThumb.y = Math.sin(radians) * mRadius;
mAngle = radiansToDegrees(radians);
dispatchEvent(new CircleSliderEvent(CircleSliderEvent.CHANGE, mAngle, radians));
}
//Degrees To Radians
private function degreesToRadians(degrees:Number):Number
{
return degrees * Math.PI / 180;
}
//Radians To Degrees
private function radiansToDegrees(radians:Number):Number
{
return radians * 180 / Math.PI;
}
//Set Angle
public function set angle(degrees:Number):void
{
positionThumb(degreesToRadians(degrees));
}
//Get Angle
public function get angle():Number
{
return mAngle;
}
}
}
CircleSliderEvent Class:
package
{
//Imports
import flash.events.Event;
//Class
public class CircleSliderEvent extends Event
{
//Constants
public static const CHANGE:String = "change";
//Properties
public var degrees:Number;
public var radians:Number;
//Constructor
public function CircleSliderEvent (type:String, degrees:Number = NaN, radians:Number = NaN)
{
super(type);
this.degrees = degrees;
this.radians = radians;
}
//Clone
public override function clone():Event
{
return new CircleSliderEvent (type, degrees, radians);
}
//To String
public override function toString():String
{
return formatToString("CircleSliderEvent", "type", "degrees", "radians");
}
}
}

ActionScript - Passing & Instantiating Class Reference Containing Required Parameters?

I'm unsuccessfully attempting to instantiate a reference of a class that is passed as a parameter to another class.
in this example there are 3 classes: MainClass, Canvas, MyCircle
from the MainClass i am creating an instance of Canvas, which is passed a class reference of MyCircle as i want to create instances of MyCircle from within Canvas. however, the MyCircle constructor contains required parameters that are created from within Canvas.
how can i pass and instantiate a class reference with required parameters?
MyCircle:
package
{
//Imports
import flash.display.Shape;
//Class
public class MyCircle extends Shape
{
//Constructor
public function MyCircle(color:uint, radius:uint)
{
graphics.beginFill(color, 1.0);
graphics.drawCircle(0, 0, radius);
graphics.endFill();
}
}
}
Canvas:
package
{
//Imports
import flash.display.DisplayObject;
import flash.display.Sprite;
import flash.utils.getDefinitionByName;
//Class
public class Canvas extends Sprite
{
//Constructor
public function Canvas(circleClassReference:String, amount:uint)
{
var CircleReference:Class = getDefinitionByName(circleClassReference) as Class;
for (var i:uint = 0; i < amount; i++)
{
var randomColor:uint = Math.random() * 0xFFFFFF;
var randomRadius:uint = Math.random() * 100 + 50;
var circleInstance:DisplayObject = new CircleReference(randomColor, randomRadius);
circleInstance.y = i * randomRadius;
addChild(circleInstance);
}
}
}
}
MainClass:
package
{
//Imports
import flash.display.Sprite;
//Class
public class MainClass extends Sprite
{
//Constructor
public function MainClass()
{
var myCanvas:Canvas = new Canvas("MyCircle", 10);
addChild(myCanvas)
}
}
}
[EDIT]
it seems that passing the actual Class instead of the name of the class avoids the need for the dirty fix that is mentioned below.
MainClass Constructor
public function MainClass()
{
var myCanvas:Canvas = new Canvas(MyCircle, 10);
addChild(myCanvas)
}
Canvas Constructor
public function Canvas(circleClassReference:Class, amount:uint)
{
var CircleReference:Class = circleClassReference;
for (var i:uint = 0; i < amount; i++)
{
var randomColor:uint = Math.random() * 0xFFFFFF;
var randomRadius:uint = Math.random() * 100 + 50;
var circleInstance:DisplayObject = new CircleReference(randomColor, randomRadius);
circleInstance.y = i * randomRadius;
addChild(circleInstance);
}
}
Importing (or being in the same package) isn't enough to make the compiler include a class definition in the Application Domain. You will actually have to use the class you want somewhere, or embed the definition in an SWF that you load in. This should fix your error though:
package
{
//Imports
import flash.display.Sprite;
//Class
public class MainClass extends Sprite
{
//Constructor
public function MainClass()
{
//unused variable definition for class embedding purposes
var tempCircle:MyCircle;
var myCanvas:Canvas = new Canvas("MyCircle", 10);
addChild(myCanvas)
}
}
}
While this will prevent MyCircle from being undefined later on, I've always thought of it as a bit of a dirty fix (despite having it in some fairly major projects). I'd love to know a better solution, other than embedding the definition in a separate SWF.
Are you aware that you can treat classes as Objects?
Depending on what you're trying to do you could do something like this:
My Circle:
package
{
//Imports
import flash.display.Shape;
//Class
public class MyCircle extends Shape
{
//Constructor
public function MyCircle(color:uint, radius:uint);
{
graphics.beginFill(color, 1.0);
graphics.drawCircle(0, 0, radius);
graphics.endFill();
}
}
}
Canvas:
package
{
//Imports
import flash.display.DisplayObject;
import flash.display.Sprite;
import flash.utils.getDefinitionByName;
//Class
public class Canvas extends Sprite
{
//Constructor
public function Canvas(classToCreate:Class, amount:uint)
{
for (var i:uint = 0; i < amount; i++)
{
var randomColor:uint = Math.random() * 0xFFFFFF;
var randomRadius:uint = Math.random() * 100 + 50;
var circleInstance:DisplayObject = new classToCreate(randomColor, randomRadius);
circleInstance.y = i * randomRadius;
addChild(circleInstance);
}
}
}
}
MainClass:
package
{
//Imports
import flash.display.Sprite;
//Class
public class MainClass extends Sprite
{
//Constructor
public function MainClass()
{
var myCanvas:Canvas = new Canvas(MyCircle, 10);
addChild(myCanvas)
}
}
}