AS3 - TypeError: Error #1009 - actionscript-3

I'm trying to create a system that puts each block in a block Array which I can use to easily add blocks to the stage via XML, however I'm getting
[Fault] exception, information=TypeError: Error #1009: Cannot access a property or method of a null object reference.
When it initializes the 'blockStone'.
Here's my main Block class, each block is initialized here.
package com.snakybo.platformengine.block {
import flash.display.MovieClip;
public class Block extends MovieClip {
public static var blockList:Array = [];
public static const blockStone:Block = (new BlockStone(0));
public var blockID:int;
private var mc:MovieClip;
public function Block(blockID:int, mc:MovieClip) {
if (blockList[blockID] != null) {
throw new Error("Slot " + blockID + " is already occupied by " + blockList[blockID] + " when adding " + this);
} else {
blockList[blockID] = this;
this.blockID = blockID;
this.mc = mc;
mc.x = 100;
mc.y = 100;
addChild(mc);
}
}
}
}
Here's the BlockStone class:
package com.snakybo.platformengine.block {
public class BlockStone extends Block {
public function BlockStone(blockID:int) {
super(blockID, new stone());
}
}
}
FlashDevelop refers to this line when it errors:
public class BlockStone extends Block {
Here's the stack trace:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at global$init()[C:\Users\Kevin\Desktop\Extra\Code\Actionscript\PlatformEngine\src\com\snakybo\platformengine\block\BlockStone.as:3]
at com.snakybo.platformengine.block::Block$cinit()
at global$init()[C:\Users\Kevin\Desktop\Extra\Code\Actionscript\PlatformEngine\src\com\snakybo\platformengine\block\Block.as:5]
at com.snakybo.platformengine::Game()[C:\Users\Kevin\Desktop\Extra\Code\Actionscript\PlatformEngine\src\com\snakybo\platformengine\Game.as:13]
at com.snakybo.platformengine::Main/init()[C:\Users\Kevin\Desktop\Extra\Code\Actionscript\PlatformEngine\src\com\snakybo\platformengine\Main.as:20]
at com.snakybo.platformengine::Main()[C:\Users\Kevin\Desktop\Extra\Code\Actionscript\PlatformEngine\src\com\snakybo\platformengine\Main.as:11]
I'm pretty sure it's a problem with AS3, since this method works in Java. I'm open to suggestions on better ways to do this in AS3 using block ID's defined in an XML file.
Can anyone explain why this is happening?

It looks like you're instantiating a new Blockstone before you get through the Block constructor. Try simply declaring the public static const blockStone:Block; without setting a value to it first, and then set it in Block's constructor.

Related

Error: Call to a possibly undefined method getRegionNameForCountries through a reference with static type com.framework.model:CountryModel

Trying to figure out why I can call this function from a instantiated version of this class.
The error I get is this:
Error: Call to a possibly undefined method getRegionNameForCountries through a reference with static type com.framework.model:CountryModel.
The error comes from this code:
public static function territoriesFunction( item:Object, column:DataGridColumn ):String
{
return RemoteModelLocator.getInstance().appModel.countryModel.getRegionNameForCountries( item.countriesAvailable ) + ' ('+ item.countriesAvailable.length.toString() + ')';
}
The Class I'm trying to call the function from is here:
package com.framework.model
{
import com.adobe.cairngorm.vo.IValueObject;
import com.adobe.crypto.MD5;
import com.vo.RegionVO;
import flash.utils.ByteArray;
import mx.utils.ObjectUtil;
public class CountryModel implements IValueObject
{
public static function getCountriesForRegion( regionName:String ):Array
{
try
{
var result:Array = _dataModel[regionName];
}
catch(e:Error){}
result = ( result )? result: _dataModel[CountryModel.WORLDWIDE];
return ObjectUtil.copy( result ) as Array;
}
public static function getRegionNameForCountries( countries:Array ):String
{
if( !countries || !countries.length )
{
return CountryModel.WORLDWIDE;
}
countries.sortOn("name");
var buffer:ByteArray = new ByteArray();
buffer.writeObject(countries);
buffer.position = 0;
var hash:String = MD5.hashBytes( buffer );
try
{
var regionName:String = _dataModel[hash];
return ( regionName && regionName.length )? regionName : CountryModel.CUSTOM;
}
catch( e:Error )
{
}
return CountryModel.CUSTOM;
}
}
}
You can only access static vars/method from the Class object itself (eg. MyClass.method()), or from within the class declaration (static or instantiated).
Here is a simplified example:
MyClass.staticFunction(); //allowed
var myInstance = new MyClass();
myInstance.staticFunction(); //NOT allowed
//inside the MyClass.as
this.staticFunctionInSameClass(); //allowed
What you are trying to do is access a static method from a reference to an instantiated object of that class.
To keep the same structure as you are currently doing, you either need to create a non static helper method in the class:
//CountryModel class
public function getRegionNameForCountriesHelper(countries:Array):String
{
return getRegionNameForCountries(countries); //calls the static method
}
OR just access it on the class itself.
return CountryModel.getRegionNameForCountries(item.countriesAvailable, ....);
If the Class is not known ahead of time, you can do it by casting the instance as Object, then accessing the constructor property which returns a reference to the Class.
return (Object(RemoteModelLocator.getInstance().appModel.countryModel).constructor).getRegionNameForCountries(item.countriesAvailable, ...);
That way is very messy though, without compile time checking.
I would recommending either making the class static only (don't allow instantiation), or don't use static methods in it. Without knowing what all those parts of your application are (eg. RemoveModelLocator, appModel) it's difficult to say what would be best for your circumstance.

Error #1009: when listening to a button that exists on stage as3

I'm developing a game using as3. It is my first time using flash and as3.
My problem is that I have a button "callBasket" exists on stage, and it's an instance of a class called "CallMethod" my code is as follows:
public class SweetBasket extends Basket{
var basketButtonSweet:BasketButtonSweet = new BasketButtonSweet;
public function SweetBasket() {
}
override protected function clickButton (event:MouseEvent):void{
stage.addChild(basketButtonSweet);
basketButtonSweet.x = 547;
basketButtonSweet.y = 162;
basket = "sweet";
call = stage.getChildByName("callBasket") as CallMethod;
call.addEventListener(MouseEvent.CLICK, onClick);// here is my problem
}
protected function onClick(event:MouseEvent):void{
clicked = true;
trace(clicked);
}
And this is my Basket clas, although I don't think it matters.
public class Basket extends SimpleButton{
var basketButton:BasketButton;
var basket:String;
var call:CallMethod;
public var clicked:Boolean = new Boolean(false);
public function Basket() {
addEventListener(MouseEvent.CLICK, clickButton);
}
protected function clickButton (event:MouseEvent):void{
}
using addEventListener gives me an error
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at OOPGame::SweetBasket/clickButton()
Any idea why is this error happening and what have I done wrong?
It pretty much looks like callBasket" does not exist on stage(/is placed somewhere else but not on stage directly). To make sure it really exists, add a trace after "call = stage.getChildByName("callBasket") as CallMethod;" trace("call exists: " + call); what does the trace state?
It looks like element is simply not added to the stage. Check the code fragment where you add element with name "callBasket". Also check that "callBasket" is instance of class CallMethod (or it's inheritor).

AS3 undefined function #1006

I have a parent class called 'main.as'. I am trying to get the child class to call main's function. They both reside in the same folder.
// main.as //
package {
public class main extends MovieClip {
public function main() {
var child:child_mc = new child_mc(this);
}
public function callFunction():void {
trace("Done it");
}
}
}
.
// child.as //
package {
import main;
public class child extends MovieClip {
private var main:MovieClip = new MovieClip();
public function child(main:MovieClip):void {
this.main = main;
main.callFunction();
}
}
}
This is the error I've been getting:
TypeError: Error #1006: callFunction is not a function.
so I tried doing a trace like this
trace(main.callFunction);
and it says undefined. Can someone tell me what I am missing. I get this feeling its a very basic thing that I have overlooked!
Your "child" package is defined as "main". I'm not even sure how it complied, let alone run to the point of showing the error message you got.
I believe the code below should do what you expected.
(I also took the liberty to rename the classes to use CamelCase (with initial caps) to adhere to best practices and to be easier to distinguish from variable names.)
Main.as
package {
public class Main extends MovieClip {
public function Main() {
var child:ChildMC = new ChildMC();
child.main = this;
}
public function callFunction():void {
trace("Done it");
}
}
}
EDIT: I just saw your comment that points out that child_mc is a MovieClip in the Library. I guess then that the child class is set as the Base Class of the child_mc?
If so, you cannot pass properties through the instantiator, you need to find another way to pass along the instance of the Main class to the Child class.
One way would be to add a setter, like the following:
Child.as (Base Class for ChildMC)
package {
public class Child extends MovieClip {
private var _main:Main;
public function Child() {
}
public function set main(main:Main):void {
this._main = main;
this._main.callFunction();
}
}
}

AS3 Error accessing parent methods and variables

I'm learning AS3 and I understand that there are a bunch of related questions here with this type of error but I can't seem to figure it out.
I'm getting this error:
TypeError: Error #1034: Type coercion failed: cannot convert bej_cs5_fla::MainTimeline#330ae041 in Board.
at BoardTimer/gameOver()
at BoardTimer/countdown()
at flash.utils::Timer/_timerDispatch()
at flash.utils::Timer/tick()
I have to classes. Class Board and class BoardTimer.
Board:
public class Board extends MovieClip {
//Attributes
public var boardSide:uint;
public function Board(dimention:uint) {
boardSide = dimention;
// Code goes here
}
}
BoardTimer:
public class BoardTimer extends Board{
public function BoardTimer(dimention:uint)
{
boardSide2 = dimention;
super(dimention);
gameTimerBox = new TextField();
myTimer = new Timer(1000,count);
myTimer.addEventListener(TimerEvent.TIMER, countdown);
myTimer.start();
}
}
And some BoardTimer methods:
function countdown(event:TimerEvent):void
{
gameTimerBox.x = 700;
gameTimerBox.y = 200;
gameTimerBox.textColor = 0xFFFFFF;
gameTimerBox.text = String((count)-myTimer.currentCount);
if (gameTimerBox.text == "0")
{
gameOver();
gameTimerBox.text = String("Game Over");
}
addChild(gameTimerBox);
}
function gameOver()
{
trace(Board(parent).boardSide);
}
In one frame I have this:
dimention=10;
var boardTimer_mc= new BoardTimer(dimention);
boardTimer_mc.x=25;
boardTimer_mc.y=25;
addChild(boardTimer_mc);
and in another I have this:
var dimention:uint=10;
var board_mc: Board = new Board(dimention);
board_mc.x=25;
board_mc.y=25;
addChild(board_mc);
BoardTimer is doing all that Boardis doing but I'm failing to get access to Board methods and variables. I've tried trace(Board(parent).boardSide);, trace(Board(this.parent).boardSide); and trace(Board(this.parent.parent).boardSide); and nothing.
What am I doing wrong?
parent doesn't refer to base class or the parent class you derived from. It refers to the parent in the displaylist on the stage. (read this)
Use super keyword for referring to the base class. Also, when you are inheriting the class, all the protected & public methods & variables would be available as it is in the derived class.

when does the stage become initialised?

I have a singleton class that inherits from sprite so that it can access the stage, like this..
package
{
import flash.display.Sprite;
public class C extends Sprite
{
private var _grid:Array = new Array();
public function get Grid():Array
{
return _grid;
}
private static var _instance:C;
public static function get Instance():C
{
if (_instance == null)
{
_instance = new C();
}
return _instance;
}
function C()
{
this.InitGrid();
}
private function InitGrid():void
{
var gridWidth:Number = stage.width / 10;
}
}
}
This throws the error
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at C/InitGrid()
at C()
at C$/get Instance()
at C()
at Main()
If I replace stage.width with an int the code executes OK.
is this because the object has not been added to the displayList of any children of the stage?
Thanks
Yes. The Sprite will only have a stage property once it's a part of the Display list.
To get the stage you will need to either give your singleton a reference to the stage or add it to the Display list. If you choose the latter you can add a listener Event.ADDED_TO_STAGE, and handle that accordingly inside your singleton.