Two dimensional array of objects in as3 - actionscript-3

Is it possible to make array in as3 like this :
countdowns[bodyID][powerupName] = { time: powerup.getTime(), onRemove: onRemove };
I have been trying for hours but no luck..
Thanks

Sure, but you have to declare each object separately and you have to call index number instead of variable name
Say I have an array of colors with a sub array of types of that color filled with objects describing RGB
var colors:Array = [];
var red:Array = [];
var darkRed:Object = { r : 256, g : 100, b : 100 }
red.push( darkRed ); //darkRed is now part of red
colors.push( red ); //red is now part of colors
To access darkRed, you would do this:
colors[0][0]; //that is darkRed

I believe this is what you are trying to accomplish :
var countdowns:Array = new Array;
countdowns[bodyID] = new Array;
countdowns[bodyID][powerupName] = { time: powerup.getTime(), onRemove: onRemove };
The second dimension of the countdowns Array is achieved by inserting an array into each element of the first dimension.

While this certainly can be done, but it's possible you're overcomplicating things. Perhaps a single-dimensional Array ob tailored Objects will suit better.
var ob:Object=new Object();
ob.bodyId=bodyId;
ob.powerup=powerup; // direct link to powerup might serve you better!
ob.onRemove=onRemove;
countdowns.push(ob);

Related

Errors when loading random movie clips from an array as3

I am getting closer to finding a solution for the errors being generated when running the code below.
I have three boxes on the stage. The goal is to load one random item from the array without any one item being duplicated in more than one of the three boxes.
Yasuyuki Uno has been very helpful. We are currently trying to solve the following:
Code:
var animalArray: Array = [animal1, animal2, animal3, animal4, animal5, animal6, animal7, animal8, animal9, animal10];
var randArr: Array = [];
var rand: int;
// Get random value for 3 times.
for(var i:int=0,len:int=animalArray.length;i<3;i++,len--){
rand = Math.floor( Math.random() * len); // Generate random integer between 0 and len-1.
randArr.push(animalArray.splice(rand,1)); // Delete a value from original array and add that value to new array.
}
box1.addChild(randArr[0]);
box2.addChild(randArr[1]);
box3.addChild(randArr[2]);
Error Message: Incorrect number of arguments. Expected no more than 0
Any help would be greatly appreciated. Thnx!
Assuming that animal1, animal2, etc are linkage IDs in your library, they are class references so they need to be instantiated using the new operator.
There are a few other non-critical issues with your code that made it hard to understand from my point of view:
Using animal1 instead of Animal1 and so on for class names. Uncapitalized names look like properties or functions, not classes.
Using Array instead of Vector. Vectors give you better errors; had you been using Vectors from the start your problem would be obvious.
Example:
var animalTypes:Vector.<Class> = new <Class>[Animal1, Animal2, Animal3, Animal4, Animal5, Animal6, Animal7, Animal8, Animal9, Animal10];
var randomAnimals:Vector.<DisplayObject> = new <DisplayObject>[];
// Get random value for 3 times.
for (var i:int = 0; i < 3; i++){
// Generate random integer between 0 and length-1.
var randomIndex:int = Math.random() * animalTypes.length;
// Remove a class from original vector.
var randomAnimalType:Class = animalTypes.splice(randomIndex, 1)[0];
// Create an instance of the animal class.
var randomAnimal:DisplayObject = new randomAnimalType();
// Add the instance to the random vector.
randomAnimals.push(randomAnimal);
}
box1.addChild(randomAnimals[0]);
box2.addChild(randomAnimals[1]);
box3.addChild(randomAnimals[2]);
As you check length of animalArray in for expression, it's no need to change variable len.
Also if you want to fill with 3 random items new array, you need to use this code:
const arr: Array = [animal1, animal2, animal3, animal4, animal5, animal6, animal7];
const genArr: Array = [];
var len: int = arr.length;
var n: int = 3;
while(n--) {
const randIndex: int = Math.floor(Math.random()*len); // get random index
genArr.push(arr.splice(randIndex, 1)[0]); // splice returns array, so we need first and exist item
len--; // decrement length as optimized solution of no-read length of array each cycle
}
trace(genArr);

TweenLite/TweenMax support for ConvolutionFilter

I am applying filters to a bitmap using something like:
TweenLite.to(origBitmap,0,{colorMatrixFilter:{saturation:2,brightness:3});
and that works fine.
I need to somehow apply a sharpen filter to origBitmap which I have successfully achieved using a ConvolutionFilter. The problem is after I've ran the above tweenlite call, then create a convolution filter and apply it to origBitmap, it removes the initial saturation and brightness filters and just keeps the sharpen filter
private function applyEffects(effects:Array):void
{
currentEffects = effects;
var props:Object = {};
for (var i:String in effects)
{
props[effects[i].effect] = effects[i].amount;
}
TweenLite.to(bitmap,0,{colorMatrixFilter:props});
//-- props could look like {saturation:2,brightness:3}
//-- This will sharpen the container sprite
var matrix:Array = [0, -1, 0,
-1, 5, -1,
0, -1, 0];
var conv:ConvolutionFilter = new ConvolutionFilter();
conv.matrixX = 3;
conv.matrixY = 3;
conv.matrix = matrix;
conv.divisor = 1;
bitmap.filters = [conv]; //-- this removes the above filters and just sharpens the image
}
Is there a way to also incorporate the ConvolutionFilter in that TweenLite call above? I've searched quite a bit and found some guy made a class called TweenMan which was based around your class where ConvolutionFilter is incorporated: https://github.com/danro/tweenman-as3
Nothing to do with TweenMax here since your code is the one making the mistake. This correctly removes all current filter and apply only one:
bitmap.filters = [conv];
Since filters property is either null or is an Array. To add a filter to the list you use array operation and reapply the array:
var filters:Array = bitmap.filters;
if(!filters)
{
filters = [];
}
filters.push(conv);
bitmap.filters = filters;
EDIT: starting over since I think I understand what you are trying to do. You are avoiding creating the filter yourself and let TwennLite do it for you even tough you don't need to tween anything. Don't do that, you are making everything harder for yourself. Instead create your filter that way:
var props:Object = {};
var colorMatrix:ColorMatrixFilter = new ColorMatrixFilter();
for (var i:String in effects)
{
colorMatrix[effects[i].effect] = effects[i].amount;
}
bitmap.filters = [colorMatrix];
//etc .... then
var filters:Array = bitmap.filters;
filters.push(conv);
bitmap.filters = filters;
If you need to animate multiple filters remember that most tween engine can tween easily array values so you can just do that and then apply those array values to your filters.

AS3 - Using a For Loop to Update Multiple Points and Their Values in an Array

I'm a bit new with AS3 (but not really with coding) so please forgive my ignorance. I'm creating a small function that will be called by a Main Function to update the position of 52 Pointers that have the x and y position of multiple point objects (empty movie clips). It will also then update two global arrays with those values (one array for the x and one for the y).
The problem is, as there are 52 of them, and they will probably grow in quantity, I'd like to be able to use a FOR function to do it, but I can't seem to be able to figure it out.
I get this error: Access of undefined property _point.
Here is a piece of the code that dream about:
function happyFunc():void
{
var avpointers:int = 52;
var vpointx:Array = new Array();
var vpointy:Array = new Array();
for (aa=0; aa<vpointers; aa++)
{
vpointx[aa] = _point[aa].x;
vpointy[aa] = _point[aa].y;
}
}
And this is the code that I'm stuck with...
function reallySadFunc():void
{
_point1 = localToGlobal(new Point(point1.x,point1.y));
//...
_point52 = localToGlobal(new Point(point52.x,point1.y));
vpointx[0] = _point1.x;
vpointx[1] = _point2.x;
//...
//oh god there are 104 lines of this why do I have to suffer
}
Thank you!
If I read your question correctly, I think this is what you need:
public static const CLIP_COUNT:int = 52;
// ...
private function happyFunc(parentClip:DisplayObjectContainer):void
{
var vpointx:Vector.<Number> = new Vector.<Number>(CLIP_COUNT, true);
var vpointy:Vector.<Number> = new Vector.<Number>(CLIP_COUNT, true);
var clipPoint:Point = new Point ();
var globalPoint:Point;
for (var i:int = 0; i < CLIP_COUNT; i++)
{
var childClip:DisplayObject = parentClip.getChildByName("point" +
(i + 1).toString());
clipPoint.x = childClip.x;
clipPoint.y = childClip.y;
globalPoint = parentClip.localToGlobal(clipPoint);
vpointx[i] = globalPoint.x;
vpointy[i] = globalPoint.y;
}
// do something with vpointx and vpointy - they're local variables
// and will go out of scope unless you declare them as class members
// or somehow return them from this function.
}
This function works by taking the parent display object (the one that contains the 52 movie clips - this could be the Stage) and iterates through them by getting each movie clip by name. The code assumes that your movie clips are called point1, point2, ..., point52.
To speed up the local-to-global coordinate conversion, two Point objects are created and then reused during the for loop to avoid creating many temporary Point instances.
Instead of using Array, use Vector.<Number> - this class has better performance than Array does.

Comparing bitmap is not working

I am trying to compare the bitmap 1 to bitmap 2 and if they equal to 0 I want them to do something. so for sake of seeing what it's returning I added a trace. but it seems like it's tracing out something totally different from what I expected. This is the code:
var scratch_c : Scratch_card = new Scratch_card ();
var backgr: Background = new Background ();
var mouseclick:Number;
var masking:Sprite = new Sprite()
var bmd1:BitmapData = new BitmapData(742, 165);
var bm:Bitmap = new Bitmap(bmd1);
addChild (bm);
bm.x=20;
bm.y=40;
bmd1.draw(scratch_c);
var bmd2:BitmapData = new BitmapData(742, 165);
var bm2:Bitmap = new Bitmap(bmd2);
addChild (bm2);
bm2.x=20;
bm2.y=40;
bmd2.draw(backgr);
bm2.mask = masking;
addChild(masking);
stage.addEventListener(MouseEvent.MOUSE_DOWN, Pressing);
stage.addEventListener(MouseEvent.MOUSE_MOVE, Moving);
stage.addEventListener(MouseEvent.MOUSE_UP, Lifting);
function Pressing(event:MouseEvent):void {
mouseclick = 1;
}
function Moving(event:MouseEvent):void {
if (mouseclick == 1) {
masking.graphics.beginFill(0x000000);
masking.graphics.drawEllipse(mouseX, mouseY, 70, 60);
masking.graphics.endFill();
}
}
function Lifting(event:MouseEvent):void {
trace(bmd1.compare(bmd2));
mouseclick = 0;
}
This is what it is tracing out
How can I make it compare the pixels of bmd1 and bmd2?
Why is it not returning a number?
Not a percentage but it should return a new BitMapData object that you could assign as an image.
BitMapData.compare( )
Returns Object — If the two BitmapData objects have the same dimensions (width and height), the method returns a new BitmapData object that has the difference between the two objects (see the main discussion). If the BitmapData objects are equivalent, the method returns the number 0. If the widths of the BitmapData objects are not equal, the method returns the number -3. If the heights of the BitmapData objects are not equal, the method returns the number -4.
Taken from here
Result:
Your bitmaps are not equivalent, thats why you get an object made of 2 different bitmaps.
Have you tried
if(bmd1.compare(bmd2) == bmd2){
// complete
}
However after looking at your code a little more. i think you need to test on the masking not bmd1
So something like this.
var mymask:BitmapData = new BitmapData(742, 165, true,0x000000000);
mymask.draw(masking);
if(mymask.compare(bmd2) == bmd2){
// complete
}
untested code but should put you on the right path

Array cascades its changed to secondary temp array in as3

I came across a unique (to me), and quite puzzling situation.
I have an array of three values.
focal[x,y,z]
these values change based on user input.
however when the change occurs, they are logged into a new array to test for valid changed
A simplified psuedo version of my code:
var temp:Array = focal; //I have even changed this to a const at times but to no avail
//changes to array are made like thus:
focal[1]++;
focal[0]--;
if(valid){
doStuff();
} else {
focal = temp;
}
However, when the focal[1]++; focal[0]--; ect, ect, code takes place. It also changed the temp array.
and since it changes my temp, it never resets me original code back to its previous nature.
I have never seen this behavior and its kinda throwin' me off. Suggestions?
when you are doing like this:
var temp:Array = focal; // Both array variables refer to the same array.
if you want to make a backup or temporary array you need to copy all the componetns from one to another:
var baseArray : Array = [0, 0, 0];
var tempArray : Array = baseArray.slice();
baseArray[0]++;
baseArray[1] += 2;
baseArray[2] += 3;
trace ( baseArray ); // output: 1,2,3
trace ( tempArray ); // output: 0,0,0
I add the deep copy method to the (very good) post by Jevgenij:
import flash.utils.ByteArray;
function clone(source:Object):*
{
var myBA:ByteArray = new ByteArray();
myBA.writeObject(source);
myBA.position = 0;
return(myBA.readObject());
}
More informations here: http://help.adobe.com/en_US/ActionScript/3.0_ProgrammingAS3/WS5b3ccc516d4fbf351e63e3d118a9b90204-7ee7.html