AS3 Can't get array from another class - actionscript-3

Well, I have a problem, with searching changes of array in ItemProperty class. When i calling to trace item array length, than it gets 0. But in ItemProperty class only in RecieveIndex function item length getting more than 2. Even ReturnData() got 0. The question is how to get final result of this array(Item) in InventoryData class?
That is class, when i got 0:
public class InventoryData extends Sprite {
private var item:ItemProperty = new ItemProperty();
public function InventoryData(){
trace(item.Item);
trace(item.Item.length);
//trace(item.ReturnData());
}
}
Class where array was formed. In RecieveIndex method Item length more than 0.
public class ItemProperty extends Sprite{
public var Item:Array = [];
public function ItemProperty() {
var connect:Connection = new Connection();
connect.setRequest("Select", "`inventory`", ["all"], ["all"], InventoryContent);
}
private function InventoryContent(RecieveData:Array):void
{
var picking:Connection = new Connection();
picking.setRequest("Select","`weapon`",["all"],["id IN("+RecieveData[0].contents.toString() + ")"], InventotyData);
}
private function InventotyData(RecieveData:Array):void{
var indexdecode:Connection = new Connection();
for(var i:uint=0; i<RecieveData.length; i++)
{
indexdecode.loadImageFromBase64(RecieveData[i].id, RecieveIndex);
}
}
public function RecieveIndex(index:int):void {Item.push(index); }
public function ReturnData():Array {return Item;}
}

Something like this with the event I mentioned in my comment:
public class InventoryData extends Sprite {
private var item:ItemProperty = new ItemProperty();
public function InventoryData(){
item.addEventListener(ItemProperty.ARRAY_READY, onArrayReady);
}
private function onArrayReady(e:Event):void {
trace(item.Item.length);
}
}
In ItemProperty class you declare a new constant:
public static const ARRAY_READY:String = "arrayReady";
and once you have the array filled with the items you want to retrieve, you add:
dispatchEvent(new Event(ARRAY_READY));

Related

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

I have no idea what is causing the error. I'm sure its very obvious.
(See comments below).
package src.main{
import src.tilespack.Tile;
public class Main{
public var tile:Tile;
public function Main{
var t:Tile = Tile.tiles[0]; //Error here
trace(Tile); //This will also cause an error
}
Tile:
package src.tilespack{
public static var tiles:Array = [];
public static var floorTile:Tile = new FloorTile(0); //Causes an error in FloorTile Class
public var bitmapData:BitmapData;
public function Tile(bitmapData:BitmapData, ID:int)
{
this.ID = ID;
tiles[ID] = this;
this.bitmapData = bitmapData;
}
}
FloorTile:
package src.tilespack{
import src.gfx.Assets;
import src.tilespack.Tile;
public class FloorTile extends Tile{ //Error here
public function FloorTile(ID:int){
super(Assets.floorTileData, ID);
}
}
}
Error #1009: Cannot access a property or method of a null object
reference.
I've noticed few problems in your code:
1) The file Tile doesn't have a definition of class. Probably, this is just a typo, but anyway, this file should look something like:
package src.tilespack
{
public class Tile
{
public static var tiles:Array = [];
public static var floorTile:Tile = new FloorTile(0); //Causes an error in FloorTile Class
public var ID:int;
public var bitmapData:BitmapData;
public function Tile(bitmapData:BitmapData, ID:int)
{
this.ID = ID;
tiles[ID] = this;
this.bitmapData = bitmapData;
}
}
}
2) Your code has something like "recursive linkage" (sorry, I don't know the official term). Your class Tile has the static variable floorTile, and it tries to create an instance of the FloorTile class, which itself extends the class Tile.
So we have a situation, when the class Tile tries to use the class FloorTile (because static variables should be instantiated during the first class use), and the class FloorTile tries to use the class Tile. And it's a problem.
You may either remove static variable of the type FloorTile or change code of the class Tile to prevent usage of the class FloorTile before the class Tile is prepared to work. Here an example of the second approach:
package src.tilespack
{
import flash.display.BitmapData;
public class Tile
{
public static var tiles:Array = [];
private static var _floorTile:Tile;
public static function get floorTile():Tile
{
if (!Tile._floorTile)
{
Tile._floorTile = new FloorTile(0);
}
return Tile._floorTile;
}
public var ID:int;
public var bitmapData:BitmapData;
public function Tile(bitmapData:BitmapData, ID:int)
{
this.ID = ID;
tiles[ID] = this;
this.bitmapData = bitmapData;
}
}
}

Access class instance from another function - getDefinitionByName(AS3)

I have a function, sceneLoader, that will instantiate an object of the Class Scene1 from a string using getDefinitionByName. I then want to access a function (sceneHandler) in Scene1, from another function.
public class Main extends MovieClip{
private var sceneNumber:int = 1;
private var SceneRef:Class;
private var sceneString:String;
public function Main(){
sceneLoader();
responseHandler();
}
private function sceneLoader():void{
sceneString = "Scene" + int(sceneNumber);
SceneRef = getDefinitionByName(sceneString) as Class;
var scene = new SceneRef();
addChild(scene);
}
private function responseHandler():void{
scene.sceneHandler(); //Obviously this will not work
}
}
Class Scene1
public class Scene1 extends MovieClip{
public function sceneHandler():void{
//Do something
}
}
The problem is that scene is out of scope. I cannot instantiate Scene1 outside the function as I need to first call getDefinitionByName. I also want to keep the function for loading scenes later on.
How can I call sceneHandler from responseHandler?
EDIT: I've tried
public class Main extends MovieClip{
private var sceneNumber:int = 1;
private var SceneRef:Class;
private var sceneString:String;
public function Main(){
sceneLoader();
responseHandler();
}
private function sceneLoader():void{
addChild(getScene());//Does not work
}
private function responseHandler():void{
getScene().sceneHandler(); //Works now
}
private function getScene():Object{
sceneString = "Scene" + int(sceneNumber);
SceneRef = getDefinitionByName(sceneString) as Class;
var scene = new SceneRef();
//addChild(getScene());//This does work but doesn't suit my need
return scene;
}
}
Now I can't add the object to the stage.
I get the Error:
Implicit coercion of a value with static type Object to a possibly unrelated type flash.display:DisplayObject.
I figured it out. I just forgot to cast as a DisplayObject.
public class Main extends MovieClip{
private var sceneNumber:int = 1;
private var SceneRef:Class;
private var sceneString:String;
public function Main(){
sceneLoader();
responseHandler();
}
private function sceneLoader():void{
addChild(getScene() as DisplayObject);
}
private function responseHandler():void{
getScene().sceneHandler();
}
private function getScene():Object{
sceneString = "Scene" + int(sceneNumber);
SceneRef = getDefinitionByName(sceneString) as Class;
var scene = new SceneRef();
return scene;
}
}
Obviously:
import flash.display.DisplayObject;

Flex - Cursor search in ArrayCollection not working

So I'm following the book Adobe Flex 4 Training From the Source by Michael Labriola, Jeff Tapper and Matthew Boles, for context.
I'm building a Shopping Cart Class that recieves a ShoppingCartItem object (which is just a POAO) from the mxml and adds it to an ArrayCollection via this public function:
private var $items:ArrayCollection = new ArrayCollection();
public function addItem(item:ShoppingCartItem):void
{
var inCart:Boolean = false;
var currentItem:ShoppingCartItem;
for(var i:int = 0; i < $items.length; i++)
{
currentItem = $items.getItemAt(i) as ShoppingCartItem;
if(item.$product == currentItem.$product)
{
inCart = true;
break;
}
}
if(inCart)
{
currentItem.$quantity++;
}
else
{
$items.addItem(item);
}
updateTotal();
$items.refresh();
}
According to the book, the same function can be achieved with an IViewCursor, like this.
public function addItem(item:ShoppingCartItem):void
{
var cursor:IViewCursor = $items.createCursor();
var inCart:Boolean = cursor.findFirst(item);
if(inCart)
{
var existing:ShoppingCartItem = cursor.current as ShoppingCartItem;
existing.$quantity++;
}
else
{
$items.addItem(item)
}
}
Problem is, when I use this function the item quantity is never updated. Then I have a Shopping cart with 2 entries of 1 product when I should have 1 entry of 2 products. Tracing the inCart boolean yields "false", no matter what I do. The first function works properly and as expected, so I have no idea why the data is not being updated correctly. Also, if I call $items.refresh(); at the end of the second function (for sorting), it throws a NullPointerException error.
Another thing to notice is that I'm using a book for Flex 4 when I'm using the 4.6.0. SDK, the last Adobe release before it was gifted to Apache. I don't know if this is of any importance.
Here's the code for ShoppingCartItem:
[Bindable]
public class ShoppingCartItem
{
public var $product:Product;
public var $quantity:uint;
public var $subtotal:Number;
public function getSubTotal():Number
{
calculateSubTotal();
return $subtotal;
}
public function toString():String
{
return "[ShoppingCartItem]"+$product.prodName+":"+$quantity;
}
public function calculateSubTotal():void
{
this.$subtotal = $product.listPrice*$quantity;
}
public function squeak():void
{
trace("squeak");
}
public function ShoppingCartItem(product:Product, quantity:uint = 1)
{
this.$product = product;
this.$quantity = quantity;
calculateSubTotal();
}
EDIT: More information request by Sunil D.
Product.as class:
[Bindable]
public class Product
{
public var catID:Number;
public var prodName:String;
public var unitID:Number;
public var cost:Number;
public var listPrice:Number;
public var description:String;
public var isOrganic:Boolean;
public var isLowFat:Boolean;
public var imageName:String;
public function toString():String
{
return "[Product]"+this.prodName;
}
public static function buildProductFromAttributes(data:XML):Product
{
var p:Product;
var isOrganic:Boolean = (data.#isOrganic == "Yes");
var isLowFat:Boolean = (data.#isLowFat == "Yes");
p = new Product(data.#catID,
data.#prodName,
data.#unitID,
data.#cost,
data.#listPrice,
data.#description,
isOrganic,
isLowFat,
data.#imageName);
return p;
}
public static function buildProduct(o:Object):Product
{
var p:Product;
p = new Product(o.catId,o.prodName,o.unitID,o.cost,o.listPrice,
o.description,(o.isOrganic == 'true'),
(o.isLowFat == 'true'),o.imageName);
return p;
}
public function Product(cid:Number, name:String, uid:Number, cost:Number, listp:Number, desc:String, iso:Boolean, ilf:Boolean, imn:String)
{
this.catID = cid;
this.prodName = name;
this.unitID = uid;
this.cost = cost;
this.listPrice = listp;
this.description = desc;
this.isOrganic = iso;
this.isLowFat = ilf;
this.imageName = imn;
}
}
ArrayCollection sorting sortfield is the Product POAO contained in the ShoppingCartItem Class. It's done within the constructor function of ShoppingCart like this:
public class ShoppingCart
{
[Bindable]
private var $items:ArrayCollection = new ArrayCollection();
public function ShoppingCart()
{
var prodSort:Sort = new Sort();
var sortField:SortField = new SortField("product");
prodSort.fields =[sortField];
$items.sort = prodSort;
$items.refresh();
}
The reason the viewcursor approach is not working is because the item (ShoppingCartItem) is not in the $items collection. This method compares object references and will hence not find your item if it is another instance of ShoppingCartItem.
In the first approach you are not comparing object references of ShoppingCartItem, but comparing the "product" property of the items.

How to call a function from a Class AS3

I'm studying to be a Game Designer, and right now I'm having some issues with my flash game.
the game has a Counter Class, with a Score Class that extends Counter. and it is added to the stage in my PlayScreenA Class.
The Timer starts with a number and decreases every 24frames. but in my Hero Class I can pick up some coins and that coins are going to increase the Time on my Score.
The question is: How I can say in my Hero Class to execute the addToValue function inside the Counter Class?
Pieces of Code:
Creating my score in the PlayScreenA Class:
private var myTime:Score = new Score();
private function create_time (){
myTime.x = 800;
myTime.y = 50;
addChild(myTime);
}
Counter Class:
package
{
import flash.display.MovieClip;
public class Counter extends MovieClip
{
public var currentValue:Number;
public function Counter()
{
reset();
}
public function addToValue( amountToAdd:Number ):void
{
currentValue = currentValue + amountToAdd;
updateDisplay();
}
public function subToValue( amountToSub:Number ):void
{
currentValue = currentValue - amountToSub;
updateDisplay();
}
public function reset():void
{
currentValue = 20;
updateDisplay();
}
public function updateDisplay():void
{
}
}
}
Score Class:
package
{
import flash.text.TextField;
import flash.events.Event;
public class Score extends Counter
{
protected var _timeCounter:int;
public function Score()
{
super();
addEventListener(Event.ENTER_FRAME, onUpdate);
}
override public function updateDisplay():void
{
super.updateDisplay();
scoreDisplay.text = currentValue.toString();
}
protected function onUpdate(e:Event):void
{
_timeCounter++;
trace(currentValue);
if (_timeCounter == 24)
{
this.subToValue( 1 );
_timeCounter = 0;
}
}
}
}
Piece of my Hero Class where I need to Call the function:
for(var i:int; i<collisionList.length;i++)
{
var $collision:platform_tile = collisionList[i];
if($hasCollided = hitbox.hitTestObject($collision.hitBox) && $collision.alpha<0.8 && $collision.alpha>0.6)
{
$collision.alpha=0;
$collision.visible = false;
//Here is where I want to call my subToValue function!
break;
}
since addToValue and subToValue are instance methods, you should provide a reference (an instance variable) to the counter object in your hero object, then call its addToValue or subToValue methods.
var theCounter:Counter;
you should either initiate this in your hero object, or assign a pre-existing counter object through getter/setters. then you can call:
theCounter.addToValue();
I assume you are trying to access the object of Score class created initially in the PlayerScreenA class...
If that is the case then you either derive a relationship between the two classes to pass this object or you could keep a static class keeping track of the function at a global level...
public class AppRefrences
{
public static var addToValueFunc:Function;
}
In Player A Class,
private var myTime:Score = new Score();
private function create_time (){
myTime.x = 800;
myTime.y = 50;
addChild(myTime);
// This is where you set the function
Apprefrences.addToValueFunc = myTime.addToValue;
}
In Hero Class,
for(var i:int; i<collisionList.length;i++)
{
var $collision:platform_tile = collisionList[i];
if($hasCollided = hitbox.hitTestObject($collision.hitBox) && $collision.alpha<0.8 && $collision.alpha>0.6)
{
$collision.alpha=0;
$collision.visible = false;
// This is where you call the function
if(AppRefrences.addToValueFunc != null)
AppRefrences.addToValueFunc(0);
break;
}
Try using getter & setters to control the update of the static variable. I didn't include it for the sake of clarity.

how to to assign a parent's variable from the parent's child?

i want to pass the variable from parent to child .How Can i pass the Variable.Here i paste my code.AnyBody please guide me.Thanks in advance!
My Parent Class
public class PlayerStrobe_domaincheck extends Sprite
{
private var myService:NetConnection = new NetConnection();
private var _loader:Loader;
public function PlayerStrobe_domaincheck()
{
_loader = new Loader();
var sourceId:String = loaderInfo.parameters.src;// I want to pass This Variable
var some:StrobeMediaPlayback = new StrobeMediaPlayback(parentObject);// Access of undefined property parentObject(Error Message).
some = new StrobeMediaPlayback(this);
}
}
My Child Class
public class StrobeMediaPlayback extends Sprite
{
private var _loader:Loader;
private var sourceId:String; //i want to access the the parent variable(sourceId) here
parentClass = parent;
function Test():void
{
mediaContainer.addMediaElement(alert);
alert.alert("Error",parentClass.sourceId);
}
public class PlayerStrobe_domaincheck extends Sprite
{
private var myService:NetConnection = new NetConnection();
private var _loader:Loader;
public function PlayerStrobe_domaincheck()
{
_loader = new Loader();
var sourceId:String = loaderInfo.parameters.src;
var some:StrobeMediaPlayback = new StrobeMediaPlayback(sourceId);
new StrobeMediaPlayback(this);
}
}
public class StrobeMediaPlayback extends Sprite
{
private var _loader:Loader;
private var sourceId:String;
parentClass = parent;
public function StrobeMediaPlayback(sourceIdVariablePassed:String):void
{
mediaContainer.addMediaElement(alert);
trace("Source ID "+sourceIdVariablePassed);
}
}
You can not directly do it unless your variable in the parent is public
Then again, it is not really good code to do that, because then the child is constrained to be added to only your parent class and nothing else.
The best way would be to dispatch an event, and have the parent listen to that event. The event handler in the parent should change the variable in the parent.
Yoc can pass parent to child class
public class StrobeMediaPlayback extends Sprite
{
private var _loader:Loader;
private var sourceId:String; //i want to access the the parent variable(sourceId) here
private var parentClass:PlayerStrobe_domaincheck;
public function StrobeMediaPlayback(parent:PlayerStrobe_domaincheck)
{
parentClass = parent;
trace("welcome");
}
public function Test():void
{
trace(parentClass.sourceId);
}
}
and when you construct your child from parent (for example) pass parent object as param like
var some:StrobeMediaPlayback = new StrobeMediaPlayback(parentObject)
and you definition of parent should be like this
public class PlayerStrobe_domaincheck extends Sprite
{
private var myService:NetConnection = new NetConnection();
private var _loader:Loader;
private var some:StrobeMediaPlayback; //update
public var sourceId:String;
public function PlayerStrobe_domaincheck()
{
_loader = new Loader();
sourceId = loaderInfo.parameters.src;// I want to pass This Variable
some = new StrobeMediaPlayback(this) //update
}
}
you can defile your child object in parents constructor