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

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;
}
}
}

Related

Adobe AIR getQualifiedDefinitionNames

I have a problem with getQualifiedDefinitionNames, when I compile with AIR 20 I get
Main
gameBg_png$c19135a2672bad8837da970f47c7278f-30390368
and when I compile with Apach Flex 4.15.0 or Adobe Animate CC it returnes everything as expected!
Main
Main__gamebg
how to fix it with AIR, that it returned Main__gamebg class?
my sample code:
package{
import flash.display.MovieClip;
import flash.events.Event;
public class Main extends MovieClip {
[Embed(source="../assets/gameBg.png")]
public const _gamebg:Class;
public function Main() {
super();
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
var definitions:*;
if (this.loaderInfo.applicationDomain.hasOwnProperty("getQualifiedDefinitionNames")) {
definitions = this.loaderInfo.applicationDomain["getQualifiedDefinitionNames"]();
for (var i:int = 0; i < definitions.length; i++) {
trace(definitions[i])
}
}
}
}
}
http://forum.starling-framework.org/topic/getqualifieddefinitionnames-porblem?replies=5#post-90611
this trick works.
///////////////
// SomeImage.as
///////////////
[Embed(source="someimage.png")]
public class SomeImage extends Bitmap{
public function get dimensions(): String{
return width + "x" + height;}
}
/////////////
// MyClass.as
/////////////
public class MyClas{
public function foo(): void{
// Instantiate the bound class to get the embedded image
var someImage:SomeImage = new SomeImage();
// ... do whatever you'd like with someImage
trace("Dimensions: " + someImage.dimensions);
}
}

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

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.

AS3 Accessing classes and variables

I am new to AS3 and I try to make a simple flash game.
My problem concerns accessing a specific array outside of its class.
I succeeded accessing some variables and function but I am quite stuck on this one.
There are 3 classes : Game which is the main class tied to the flash file, Level1 which spawn background element and enemies, and finally the Enemy class.
The Game class instantiate the Level1 class which spawn enemies (with Enemy class) and push them to an array.
When the enemy get hit, a method in the Enemy class remove it from the display list and then tries to remove it from the array located in the Level1 Class, wich fails and throw :
1119: Access of possibly undefined property level1 through a reference with static type Class.
Another problem is some time the bullets stop in the middle of screen, I havn't been able to track down this bug as well.
Any way, this is my first code related post and if it's too messy, tell me and I'll try to make it more readable.
Sorry for any inconveniance and thank you for your help
-Yaniv
package
{
import flash.display.MovieClip;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.text.*;
import flash.geom.Point;
public class Game extends MovieClip
{
public var player:Player;
public var level1:Level1;
public var bullet:Bullet;
private var bullets_arr:Array;
var fire_on : Boolean;
var fire_counter : int;
public function Game()
{
level1=new Level1(this.stage);
player = new Player ;
addChild(player);
player.y = 600;
bullets_arr = [];
addEventListener(Event.ENTER_FRAME,Main);
stage.addEventListener(MouseEvent.MOUSE_DOWN,mouseDownHandler);
stage.addEventListener(MouseEvent.MOUSE_UP,mouseUpHandler);
}
function mouseDownHandler($e:MouseEvent):void
{
fire_on = true;
}
function mouseUpHandler($e:MouseEvent):void
{
fire_on = false;
fire_counter = 0;
}
function fire():void
{
bullet = new Bullet ;
addChild(bullet);
bullet.x = player.x;
bullet.y = player.y - 32;
bullets_arr.push(bullet);
}
public function Main(e: Event):void
{
player.x = mouseX;
if (bullets_arr)
{
for (var m:int = 0; m < bullets_arr.length; m++)
{
bullets_arr[m].y -= 20;
if(level1.enemies_arr)
{
for (var n:int = 0; n < level1.enemies_arr.length; n++)
{
if (bullets_arr[m])
{
if (level1.enemies_arr[n])
{
if (level1.enemies_arr[n].hitTestObject(bullets_arr[m]))
{
if(bullets_arr[m].parent)
{
bullets_arr[m].parent.removeChild(bullets_arr[m]);
bullets_arr.splice(bullets_arr[m],1);
level1.enemies_arr[n].DoDamage(10);
}
}
}
}
}
}
}
}
if(fire_on)
{
fire_counter++;
if(fire_counter == 01)
{
fire();
}
else if(fire_counter >5)
{
fire_counter =0;
}
}
}
}
}
package {
import flash.display.MovieClip;
import flash.display.Stage;
import flash.events.Event;
public class Level1 extends MovieClip{
var i:int;
var j:int;
var frame :int;
public var enemy:Enemy;
public var enemies_arr:Array;
public function Level1(target:Stage)
{
frame = 0;
enemies_arr = [];
for (var i:int = 0; i < 3; i++)
{
for (var j:int = 0; j < 3; j++)
{
enemy = new Enemy;
enemy.x = j*100 + 260;
enemy.y = i*40 - 150;
target.addChild(enemy);
enemies_arr.push(enemy);
}
}
}
}
}
package
{
import flash.display.MovieClip;
public class Enemy extends MovieClip
{
var Health : int;
var splash:Splash;
function Enemy()
{
Health =30;
}
public function DoDamage(Damage:int)
{
Health -= Damage;
if (Health <= 0)
{
Die();
}
}
public function Die()
{
if(this.parent)
{
this.parent.removeChild(this);
//HERE IS THE ERROR
Game.level1.enemies_arr.splice(this,1);
}
}
}
}
The syntacitical problem you're running into is that you're trying to get level1 from the class Game, when level1 is an instance variable, not a static variable. As an instance variable, level1 is a completely different variable for each instance of game, so if you simply say Game.level1, the compiler wonders, "Which Game?"
To change this, you could simply change level1 into a static variable, by changing this:
public var level1:Level1;
to this:
public static var level1:Level1;
That way the variable would be the same across all instances, and you shouldn't have any trouble accessing it on this line:
Game.level1.enemies_arr.splice(this,1);
I will say though that there could be issues here with certain design principles (it may be that you should use callbacks or signals or something for modularity), but the quick-and-easy fix is to just add the word static to level1's declaration.
You should call level1 on the Game instance.
In a simple way, you could define the Game as Singleton
public class Game extends MovieClip {
private static var _instance:Game;
public static function getInstance():Game {
if (_instance == null) {
_instance = new Game();
}
return _instance ;
}
}
So the Die function will be like this
public function Die()
{
if(this.parent)
{
this.parent.removeChild(this);
//HERE IS THE ERROR
Game.getInstance().level1.enemies_arr.splice(this,1);
}
}

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;
}
}
}

How to create a Collisions var in the Back class

Edit: I have now included a Player.as and a addchild
I've been trying to understand how to do this all day and again learned a lot in doing so. But I've come to a point that i need help.
I know I have to do this: create a Collisions var in the Back1 class.
Because the background called Back1 is the movieclip that contains the Collisions image
I found a good site or 2 that does a good job of explaining variables and classes but i still don't get how i should solve this problem
Research after variables and classes:
http://www.republicofcode.com/tutorials/flash/as3variables/
http://www.photonstorm.com/archives/1136/flash-game-dev-tip-1-creating-a-cross-game-communications-structure
the above problem results in the folowing error but i believe it is caused by not creating a Collisions var in the Back1 class
ArgumentError: Error #1063: Argument count mismatch on Bumper(). expected: 2, value 0.
at flash.display::MovieClip/gotoAndStop() at
DocumentClass/onRequestStart()DocumentClass.as:64] at
flash.events::EventDispatcher/dispatchEventFunction() at
flash.events::EventDispatcher/dispatchEvent() at
MenuScreen/onClickStart()MenuScreen.as:18]
package
{
import flash.display.MovieClip;
import flash.events.*;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
import flash.geom.Point;
import Bumper;
//import Back1;
public class Test extends MovieClip
{
public var leftBumping:Boolean = false;
public var rightBumping:Boolean = false;
public var upBumping:Boolean = false;
public var downBumping:Boolean = false;
public var leftBumpPoint:Point = new Point(-30,-55);
public var rightBumpPoint:Point = new Point(30,-55);
public var upBumpPoint:Point = new Point(0,-120);
public var downBumpPoint:Point = new Point(0,0);
public var scrollX:Number = 0;
public var scrollY:Number = 500;
public var xSpeed:Number = 0;
public var ySpeed:Number = 0;
public var speedConstant:Number = 4;
public var frictionConstant:Number = 0.9;
public var gravityConstant:Number = 1.8;
public var jumpConstant:Number = -35;
public var maxSpeedConstant:Number = 18;
public var doubleJumpReady:Boolean = false;
public var upReleasedInAir:Boolean = false;
public var keyCollected:Boolean = false;
public var doorOpen:Boolean = false;
public var currentLevel:int = 1;
public var animationState:String = "idle";
public var bulletList:Array = new Array();
public var enemyList:Array = new Array();
public var bumperList:Array = new Array();
public var back1:Back1;
public var collisions:Collisions;
//public var back1:Collisions = new Collisions ;
public var player:Player;
public function Test()
{
addEventListener(Event.ADDED_TO_STAGE, init);
}
public function init(e:Event):void
{
player = new Player(320, 360);
back1 = new Back1();
collisions = new Collisions();
//back1.collisions = new Collisons();
addBumpersToLevel1();
}
public function addBumpersToLevel1():void
{
addBumper(500, -115);
addBumper(740, -115);
}
public function addPlayerTolevel1():void
{
addPlayer(320, 360);
}
public function loop(e:Event):void
{
trace("back1.collisions "+back1.collisions);
trace("back1 "+back1);
trace("collisions "+collisions);
if (back1.collisions.hitTestPoint(player.x + leftBumpPoint.x,player.y + leftBumpPoint.y,true))
{
just in case i've added Bumper.as
package {
import flash.display.MovieClip;
import flash.events.Event;
public class Bumper extends MovieClip{
public function Bumper(xLocation:int, yLocation:int) {
// constructor code
x = xLocation;
y = yLocation;
addEventListener(Event.ENTER_FRAME, bumper);
}
public function bumper(e:Event):void{
//code here
}
}
}
Player.as
package {
import flash.display.MovieClip;
import flash.events.Event;
public class Player extends MovieClip {
public function Player(xLocation:int, yLocation:int) {
// constructor code
x = xLocation;
y = yLocation;
}
// public function removeSelf():void {
// trace("remove enemy");
// removeEventListener(Event.ENTER_FRAME, loop);
// this.parent.removeChild(this);
// }
}
}
the Back1.as file (note it's got to be instanced wrong)
package {
import flash.display.MovieClip;
public class Back1 extends MovieClip {
//public var collisions:Back1;
//what should i put here?
}
}
I am not sure I understand completely what you mean. The question is phrased strange.
I assume you want to achieve a collision between your background object (The Back class) and a player object? I can't see from the code you have posted what the player object is since there is no such variable in your Test class.
To test a collision check between two objects use the following code:
if(someObject.hitTestObject(anotherObject))
Or in your case when using hitTestPoint:
if(back1.hitTestPoint(player.x, player.y,true))
Then again I don't know from the code you have posted how the back1 class looks like. If it extends a MovieClip or Sprite and you have a Player class that does the same (OR any DisplayObject) this should work.
This:
Argument count mismatch on Bumper(). expected: 2, value 0.
The error you get seems to come from another place not shown in your code. I would assume you did not pass any parameters into the Bumper class' constructor.
Btw, is this a Flash IDE sample or some other program such as FlashDevelop or FlashBuilder? If you are using the Flash IDE and are trying to attach code to a movie clip instance placed out on the scene I don't think its possible to pass parameters to it. Sorry been a while since I've worked in the Flash IDE.
EDIT:
Here's some sample code:
//:: Change Back1 class to this
package {
import flash.display.MovieClip;
public class Back1 extends MovieClip {
public function Back1()
{
graphics.beginFill(0xFF0000);
graphics.drawRect(0, 0, 50, 50);
graphics.endFill();
}
}
}
//:: Then in your Main class (Or the Test class) add the following
var player:Player = new Player(25, 25);
var collidable:Back1 = new Back1();
addChild(player);
addChild(collidable);
//:: Goes in your loop/update
if (collidable.hitTestPoint(player.x, player.y, true))
{
trace("HIT PLAYER");
}
How you apply the graphics to the Back1 class is up to you, I just drew a simple box. It could be anything.
Set default parameters for Bumper class:
package {
import flash.display.MovieClip;
import flash.events.Event;
public class Bumper extends MovieClip{
public function Bumper(xLocation:int = 0, yLocation:int = 0) {
// constructor code
x = xLocation;
y = yLocation;
addEventListener(Event.ENTER_FRAME, bumper);
}
public function bumper(e:Event):void{
//code here
}
}
}