I'm using a Vector structure in ActionScript 3 to store references to a custom class. My Vector is fixed length for performance reasons, and also because it needs to map 1:1 to another data structure.
I'm trying to figure out how I "remove" an element from this fixed list. I don't want the length of the Vector to change, I just want the value of that element to be "null". Or more specifically, when I test for the truth of that element (eg: if (myVector[index]) { // do something... }), I want that test to fail for that element, since it's "empty".
So naturally, I've tried:
myVector[index] = null;
but that throws a TypeError, as does
myVector[index] = Vector.<MyClass>([]);
So what's the process for "emptying" an element of a Vector?
There must be something wrong with your index variable because
myVector[0] = null;
does not throw a TypeError when I try that. Is index an int or uint?
if you're receiving:
TypeError: Error #1009: Cannot access
a property or method of a null object
reference
than you probably haven't added your class to the object you are trying to manage (IE: you haven't added your Display objects to the stage that you are trying to nullify)
posting more code could help, but something like the following should work for you:
var spriteA:Sprite = new Sprite();
var spriteB:Sprite = new Sprite();
var spriteC:Sprite = new Sprite();
var spritesVector:Vector.<Sprite> = new <Sprite>[spriteA, spriteB, spriteC];
spritesVector.fixed = true;
trace(spritesVector); //[object Sprite],[object Sprite],[object Sprite]
spritesVector[1] = null;
trace(spritesVector); //[object Sprite],null,[object Sprite]
Related
I am a baffled noob here. I have the following code:
var mC:mc = new mc();
I do NOT instantiate mC at all with an addChild(mC);
But, later in the code, I have a loop using onEnterFrame and in this loop I have the following trace function:
if(mC){
trace("mC is here");
}
This returns "mC is here" in the output window. HUH???
The problem is that I want to use this 'if' statement to removeChild(mC); [I will be adding it in the code later with an addChild(mC); based on certain stuff that happens] but it keeps throwing dang "ERROR child of the caller" messages even with the 'if' condition...
WHAT am I doing wrong? I did not know declaring variables would add them to the stage/display list, I thought you needed an addChild(); statement. Am I smoking something I shouldn't be?
Thanks in advance, ~Frustrated Inc.
When you new up an object it exists in memory, even if you have not added it to the stage. That is why when you check if mC exists, it returns true. You want to check if it exists on the stage. Something like:
var mc:MovieClip = new MovieClip();
mc.name = "test";
if (this.getChildByName("test") != null) {
trace("mc is on stage");
}
I have not used Flash for a long time, so I did not test this code. Hopefully it works.
Complex objects in AS3 (that means anything that is not a string or a number) have a default value of null. WHen evaluated that default value of null equals false:
var mymc:MovieClip;//that MC is NOT instantiated yet so it has a default value of null
if(mymc)
{
//mymc is null so this evaluates to false
//and this statement DOES NOT execute
Now when a complex object is instantiated and exist its value would now evaluates to true
var mymc:MovieClip = new MovieClip();//that MC IS instantiated
if(mymc)
{
//mymc exits so this evaluates to true and this statement EXECUTE
//notice that "!= null" is not necessary
Now your problem has to do with display list. A DisplayObject has a parent property that is null when that object is not added to a display list, and that property point to the parent when that object is added to a display list:
var mc:MovieClip = new MovieClip()
trace(mc.parent);//this is null
addChild(mc);
trace(mc.parent);//this is not null anymore and points to the parent
SO what you mean to do is:
if(mC.parent){//this means mC has a parent and can be removed from it
trace("mC is here");
}
In your code, you just control whether your variable is null or not.
You can use contains method on the display object you are trying to add to.
If you are adding mC to some sprite named container, you can simply check whether it exists in that container with:
if (!container.contains(mC))
container.addChild(mC);
Edit: The safer method to control whether a movieclip is on the stage is to control its stage value.
if (mC.stage) {
mC.parent.removeChild(mC); // this is how you remove, if you simply want to check existence, don't remove it
}
It has to have a stage value if you added the movieclip to the stage or a container that is added to stage.
Hope it is clearer this way.
I am just wondering, if it is possible to load an image via URLRequest once, and display that image twice? Or do i have to load the image 2 times?
Edit:
Also want to ask if it is possible to duplicate the bitmaps when they are loaded in a loop(array).
For example:
var duplicate:Array = new Array(loadedArray.push(e.target.content));
When i am trying the code :
loadedArray.push(e.target.content);
var duplicate:Array = new Array(loadedArray.push(e.target.content));
It doesnt give me any errors, but from before it adds the bitmap with no problem, but now, it doesnt add anything.
And when i tried
var duplicate:Array = new Array(loadedArray as Bitmap);
addChild(duplicate[0]);
I have an error Error #2007: Parameter child must be non-null.
Duplicating Bitmap or BitmapData is easy. There are a lot of options, these are few of them:
// in your case, but can be any Bitmap
var original:Bitmap = Bitmap(loader.content);
// we actually need the bitmapData; separate for easy reading
var originalBitmapData:BitmapData = original.bitmapData;
var duplicate:Bitmap = new Bitmap(originalBitmapData);
// this one returns brand new copy of the BitmapData (sometimes needed)
var duplicate:Bitmap = new Bitmap(originalBitmapData.clone());
copyPixels() on BitmapData is also super fast and can be used for duplication, depending if there is already Bitmap(Data) instantiated.
I've an object contain all types of data
var obj1:Object={boo:true,num:0,str:"me",arr:[0,"me2",[0,1]],mc:myMc,obj:{boo:false,num:0,str:"me3",arr:[0,"me4",[0,1]]}};
when I clone this object to obj2 using ByteArray with writeObject(obj1)& readObject()properties, everything is fine except obj2.mc (mc is a variable that hold the linkage of a movie clip in the library whose class is set to myMc) can not be added to stage,
addChild(new obj2.mc)
//TypeError: Error #1007: Instantiation attempted on a non-constructor.
Help please!!
You cannot duplicate movie clips that easy. It should be something similar to:
var objectClass:Class = Object(obj2.mc).constructor;
var instance:MovieClip = new objectClass() as MovieClip;
It would be much easier if you pass a Class rather than instance. In your case, that should be myMc - the class name of the object that is in the library, right?
If so, you can simply instantiate it directly: var instance:MovieClip = new myMc();
The important think to remember is that you don't need to hold reference to an instance, but the class instead!
Guys After 2 hours of experimenting, I came out with this, This is simply the perfect solution... I changed to another way than using ByteArray, which is writing each variable in obj2 to its corresponding value in obj1, but faced another problem: when I change arrays in obj2, I found that arrays in obj1 is changed too, this means when writing variables of obj2, arrays were only referenced to that of obj1.. so I had to loop through arrays to write each value in an array individually..
var obj1:Object={mc:myMc,bo:true,num:0,str:"me",arr:[myMc,true,0,"me2",[0,1,[0,1]]],obj:{mc:myMc,bo:false,num:0,str:"me3",arr:[myMc,true,0,"me4",[0,1]]}};
var obj2:Object=clone(obj1);
function clone( source:Object ):* {
var myOBJ:Object=new Object();
for (var property in source) {
if (source[property] is Array) {
myOBJ[property]=clone(source[property]);
} else {
myOBJ[property]=source[property];
}
}
return (myOBJ);
}
Thanks for all, you've inspired me..
I am new to ActionScript and Flex.I need to learn the application developed using Flex and ActionScript.I saw an ArrayCollection declaration :
[Bindable]
public var someThing:ArrayCollection = new ArrayCollection([[]]);
What does that declaration mean.Is it multi dimensional?What is it?
This would be an ArrayCollection which is a wrapper for an Array basically to give you sort and filter function capabilities (and other methods). The constructor optionally takes an Array as an argument, [] is a new array with no elements. [[]] is an array with one element in it that is an array with no elements in it. So this is saying make a new ArrayCollection with it's source as an array which in turn contains one element that is an empty array. Not sure why they would be doing this, but that's what it does.
To sum up, you can declare and instantiate an array in AS3 like:
var myArray:Array = [];
or
var myArray:Array = new Array();
To add since this is I believe ECMAScript specific as well you can instantiate an object similarly using {}. Such as:
var myObj:Object = {};
or
var myObj:Object = new Object();
Either of these sites is good reference material for AS3:
http://help.adobe.com/en_US/as3/dev/WS5b3ccc516d4fbf351e63e3d118a9b90204-7ee5.html#WS5b3ccc516d4fbf351e63e3d118a9b90204-7ee1
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/Array.html
When I first got started with Flex (having a background in HTML/JS, C, C++, and Java) I found these videos to be really useful (if not always 100% correct/up to date, they explain the overarching concepts):
http://www.adobe.com/devnet/flex/videotraining.html
Should be easy. I have an object. I want to modify it, but before i do I want to save a copy of it that I can go back to. I tried setting copy = original but when i modify the attributes of the original the copy also shows the changes. I am assuming this is because in actionscript any time you assign, it really just stores a reference to the original object. So whats the best way for me to store a copy of the original object for later use?
var newObj:Object = Object(ObjectUtil.copy(oldObj));
"Copies the specified Object and returns a reference to the copy. The copy is made using a native serialization technique. This means that custom serialization will be respected during the copy.
This method is designed for copying data objects, such as elements of a collection. It is not intended for copying a UIComponent object, such as a TextInput control. If you want to create copies of specific UIComponent objects, you can create a subclass of the component and implement a clone() method, or other method to perform the copy."
http://livedocs.adobe.com/flex/3/langref/mx/utils/ObjectUtil.html#copy()
What you are looking for is a deep copy of the object rather then passing by reference. I found the answer here which uses the new ByteArray class in AS3:
http://www.kirupa.com/forum/showthread.php?p=1897368
function clone(source:Object):* {
var copier:ByteArray = new ByteArray();
copier.writeObject(source);
copier.position = 0;
return(copier.readObject());
}
Which you then use like this:
newObjectCopy = clone(originalObject);
Cheers!
// duplicate any given Object (not MCs)
Object.prototype.copy = function()
{
ASSetPropFlags(Object.prototype,["copy"],1);
var _t = new this.__proto__.constructor(this) //
for(var i in this){
_t[i] = this[i].copy()
}
return _t
};
Usage
x = ["1","2","3",[4,5],[{a:1,b:2}]]
y = x.copy()
y[0] = 0
y[3][0]="d"
trace(x)
trace(y)