getChildByName with Regex - actionscript-3

I've got:
stage.getChildByName("button_1")
button_1
button_2
button_3
button_...
button_15
I could easily create a var XSample to store the number, run for statement, increase +1 XSample and use XSample.toString() with "button_"
But things are going to be a little more complex, so I need to get everything after button_
stage.getChildByName("button_" + everything)
// it could be button_5, button_Ag6, button_0086, button_93 and so on
How can I do that with Regex?
Thanks

Usecase:
import flash.display.Shape;
import flash.display.Sprite;
var shapeContainer:Sprite = new Sprite();
addChild(shapeContainer);
var shape_1:Shape = new Shape();
shape_1.name = "shape_ONE";
var shape_2:Shape = new Shape();
shape_2.name = "displayObject_TWO";
var shape_3:Shape = new Shape();
shape_3.name = "shape_THREE";
shapeContainer.addChild(shape_1);
shapeContainer.addChild(shape_2);
shapeContainer.addChild(shape_3);
trace(getIndicesWithChildNamePattern("shape_", shapeContainer)); //0, 2
Using String.indexOf():
function getIndicesWithChildNamePattern(pattern:String, container:DisplayObjectContainer):Vector.<uint>
{
var indices:Vector.<uint> = new Vector.<uint>();
for (var i:uint = 0; i < container.numChildren; i++)
{
if (container.getChildAt(i).name.indexOf(pattern) != -1)
{
indices.push(i);
}
}
return indices;
}
Using Regular Expressions:
function getIndicesWithChildNamePattern(pattern:String, container:DisplayObjectContainer):Vector.<uint>
{
var indices:Vector.<uint> = new Vector.<uint>();
var regExp:RegExp = new RegExp(pattern, "g");
for (var i:uint = 0; i < container.numChildren; i++)
{
if (container.getChildAt(i).name.match(regExp).length)
{
indices.push(i);
}
}
return indices;
}

Related

How to Save positions for 3 objects in Array to make random position between each other by AS3?

How to Save positions for 3 objects in Array to make random position between each other by AS3?
import flash.geom.Point;
var arry:Point = new Point();
arry[0] = arry[78,200];
arry[1] = arry[217,200];
arry[2] = arry[356,200];
//object called b1
b1.x = arry[0][0];
b1.y = arry[0][1];
//object called b2
b2.x = arry[1][0];
b2.y = arry[1][1];
//object called b3
b3.x = arry[2][0];
b3.y = arry[2][1];
//make objects swap positions between each other
var rand:Number = (Math.random()*arry.length);
//output to see random position [[78,200],[217,200],[356,200]]
trace(arry);
to get random with tween like this... https://www.youtube.com/watch?v=8m_m64plQ6E
At compile time you should get this Error I suppose : "ReferenceError: Error #1069"
Here is a way to store the positions (like in the link you provided from youtube) :
import flash.geom.Point;
var squareWidth:uint = 40;
var squareHeight:uint = 40;
var marginX:uint = 100;
var marginY:uint = 75;
var spacer:uint = 10;
var positions:Vector.<Point > = new Vector.<Point > (9);
function setPositions(v:Vector.<Point>):void {
var count:uint = 0;
var posx:uint;
var posy:uint;
for (var i = 0; i < 3; i ++)
{
for (var j = 0; j < 3; j ++)
{
posx = (j * squareWidth) + (spacer * j) + marginX;
posy = (i * squareHeight) + (spacer * i) + marginY;
v[count] = new Point(posx,posy);
count++;
}
}
}
setPositions(positions);
trace(positions);
// output :
// (x=100, y=75),(x=150, y=75),(x=200, y=75),(x=100, y=125),(x=150, y=125),(x=200, y=125),(x=100, y=175),(x=150, y=175),(x=200, y=175)
So here you have nine Points to place the clips like in the video.
You just have to add a function to swap the nine boxes stored in another Vector.
In your case.
For 3 positions do the following if I understand your question.
import flash.geom.Point;
var positions:Vector.<Point> = new Vector.<Point>(3);
var p1:Point = new Point(78,200);
var p2:Point = new Point(217,200);
var p3:Point = new Point(356,200);
positions[0] = p1;
positions[1] = p2;
positions[2] = p3;
trace(positions);
// output : (x=78, y=200),(x=217, y=200),(x=356, y=200)
So, you're still unclear!
Your issue is to find a random position?
This may help you if this is the problem you're facing :
import flash.geom.Point;
var positions:Vector.<Point > = new Vector.<Point > (3);
var numbers:Vector.<uint> = new Vector.<uint>();
var numbersAllowed:uint = 3;
var rndNmbrs:Vector.<uint> = new Vector.<uint>(3);;
var p1:Point = new Point(78,200);
var p2:Point = new Point(217,200);
var p3:Point = new Point(356,200);
positions[0] = p1;
positions[1] = p2;
positions[2] = p3;
trace(positions);
function populateRndNmbrs(n:uint):void {
for (var i:uint = 0; i < n; i++)
{
numbers[i] = i;
}
}
populateRndNmbrs(numbersAllowed);
function populateRandomNumbers(n:uint):void
{
var rnd:uint;
for (var i:uint = 0; i < n; i++)
{
rnd = numbers[Math.floor(Math.random() * numbers.length)];
for (var j:uint = 0; j < numbers.length; j++)
{
if (rnd == numbers[j])
{
numbers.splice(j,1);
}
}
rndNmbrs[i] = rnd;
}
}
populateRandomNumbers(numbersAllowed);
trace("rndNmbrs = " + rndNmbrs);
for (var i:uint = 0; i < numbersAllowed; i++)
{
trace("b"+ (i+1) + ".x = " + positions[rndNmbrs[i]].x);
trace("b"+ (i+1) + ".y = " + positions[rndNmbrs[i]].y);
// In place of trace, you should place the boxes at those random positions.;
}
//output:
//(x=78, y=200),(x=217, y=200),(x=356, y=200)
//rndNmbrs = 2,0,1
//b1.x = 356
//b1.y = 200
//b2.x = 78
//b2.y = 200
//b3.x = 217
//b3.y = 200
Is that what you want? Or do you want to know how to create a motion effect?
I'm not sure about what you really need...
This will help you to place all the boxes in a random position.
You may do this like here bellow, and add a function to check if the random positions are not the same.
With only 3 MovieClips, you will often have the same random positions as long they're stored in the "positions Vector"
var squares:Vector.<MovieClip> = new Vector.<MovieClip>(3);
function populateMCs(target:DisplayObjectContainer,n:uint):void{
for (var i:uint = 0; i < n; i++){
squares[i] = target["b"+(i+1)];
}
}
function swapMCs():void{
for (var i:uint=0; i<squares.length; i++){
squares[i].x = positions[rndNmbrs[i]].x;
squares[i].y = positions[rndNmbrs[i]].y;
}
}
populateMCs(this,numbersAllowed);
swapMCs();
I give you a last example to get a motion effect in AS3.
I'm not a translator AS2 -> AS3 and a video is not the best way to show your code :(
This will make your boxes move smoothly, but not the way you want.
Now, you have to learn AS3 and try to make the job by yourself.
Then, if you have another issue, just ask clearly what you want.
var friction:Number = 0.15;
setDestination(squares[0],squares[0].x,350,friction);
setDestination(squares[1],squares[1].x,350,friction);
setDestination(squares[2],squares[2].x,350,friction);
squares[0].addEventListener(Event.ENTER_FRAME,moveClip);
squares[1].addEventListener(Event.ENTER_FRAME,moveClip);
squares[2].addEventListener(Event.ENTER_FRAME,moveClip);
function setDestination(mc:MovieClip,x:uint,y:uint,friction:Number):void{
mc.destinx = x;
mc.destiny = y;
mc.f = friction;
}
function moveClip(e:Event):void{
var mc:MovieClip = e.target as MovieClip;
trace(mc.name)
mc.speedx = (mc.destinx - mc.x);
mc.speedy = (mc.destiny - mc.y);
mc.x += mc.speedx*mc.f;
mc.y += mc.speedy*mc.f;
if((Math.floor(mc.speedx)<1) && (Math.floor(mc.speedy)<1)){
mc.removeEventListener(Event.ENTER_FRAME,moveClip);
trace("STOP MOVE FOR " + mc.name);
}
}

How can I solve a "Type Error #2007 Parameter child must be non-null"?

I am working on a small game and am having some success.
I have encountered a few issues and managed to solve them (I think) but this one is stumping me.
The game is working but it throws up the above error, which I would like to resolve.
Can anyone offer any advice on how to solve this?
I am sure it is this line (because when I comment it out the error doesn't happen) but have spent the last two hours trying various ways of solving it with no joy.
for (var i:int = 0;i <=20;i++)
{
addToys(1200 * Math.random(), 200 * Math.random() * 2);
}
If someone could point the way it would help a lot.
I tried googling but my mind was fried trying to do it that way.
What am I missing?
Could the problem be that I have two layers on the timeline that contain animations? (I only did that as I couldn't figure how to add them through actionscript alone).
I have attached the full code below.
Bear in mind I am still learning, so please be gentle. :D
package {
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;
public class MyGame extends MovieClip {
public function MyGame() {
const BG_SPEED:int = 5;
const BG_MIN:int = -550;
const BG_MAX:int = 0;
var bg:BackGround = new BackGround;
var toy1:Toy1 = new Toy1;
var toy2:Toy2 = new Toy2;
var toy3:Toy3 = new Toy3;
var toy4:Toy4 = new Toy4;
var toy5:Toy5 = new Toy5;
var toy6:Toy6 = new Toy6;
var toy7:Toy7 = new Toy7;
var toy8:Toy8 = new Toy8;
var toy9:Toy9 = new Toy9;
var toy10:Toy10 = new Toy10;
var toy11:Toy11 = new Toy11;
var toy12:Toy12 = new Toy12;
var toy13:Toy13 = new Toy13;
var toy14:Toy14 = new Toy14;
var toy15:Toy15 = new Toy15;
var toy16:Toy16 = new Toy16;
var toy17:Toy17 = new Toy17;
var toy18:Toy18 = new Toy18;
var toy19:Toy19 = new Toy19;
var toy20:Toy20 = new Toy20;
var toyArray:Array = new Array();
toyArray.push(toy1);
toyArray.push(toy2);
toyArray.push(toy3);
toyArray.push(toy4);
toyArray.push(toy5);
toyArray.push(toy6);
toyArray.push(toy7);
toyArray.push(toy8);
toyArray.push(toy9);
toyArray.push(toy10);
toyArray.push(toy11);
toyArray.push(toy12);
toyArray.push(toy13);
toyArray.push(toy14);
toyArray.push(toy15);
toyArray.push(toy16);
toyArray.push(toy17);
toyArray.push(toy18);
toyArray.push(toy19);
toyArray.push(toy20);
addChildAt(bg, 0);
stage.addEventListener(Event.ENTER_FRAME, bgScroll);
function addToys(xpos, ypos)
{
addChild(toyArray[i]);
toyArray[i].x = xpos;
toyArray[i].y = ypos;
}
for (var i:int = 0;i <=20;i++)
{
addToys(1200 * Math.random(), 200 * Math.random() * 2);
}
function bgScroll (e:Event)
{
if (stage.mouseX > 600 && bg.x > BG_MIN)
{
bg.x -= BG_SPEED;
for (var i:int=0; i< toyArray.length; i++)
{
(toyArray[i] as MovieClip).x -=BG_SPEED
}
}
else if (stage.mouseX < 50 && bg.x < BG_MAX)
{
bg.x += BG_SPEED;
for (var j:int=0; j< toyArray.length; j++)
{
(toyArray[j] as MovieClip).x +=BG_SPEED
}
}
}
}
}
}
Any help would be greatly appreciated.
Your for loop do 21 iterations but your array has only 20 elements, so you should do :
...
for (var i:int = 0; i < toyArray.length; i++){
addToys(1200 * Math.random(), 200 * Math.random() * 2)
}
...

How to call a variable of a function using concatenation (AS3)

I need to acess a variable inside this function using concatenation, following this example:
public function movePlates():void
{
var plate1:Plate;
var plate2:Plate;
var cont:uint = 0;
for (var i:uint = 0; i < LAYER_PLATES.numChildren; i++)
{
var tempPlate:Plate = LAYER_PLATES.getChildAt(i) as Plate;
if (tempPlate.selected)
{
cont ++;
this["plate" + cont] = LAYER_PLATES.getChildAt(i) as Plate;
}
}
}
EDIT:
public function testFunction():void
{
var test1:Sprite = new Sprite();
var test2:Sprite = new Sprite();
var tempNumber:Number;
this.addChild(test1);
test1.x = 100;
this.addChild(test2);
test2.x = 200;
for (var i:uint = 1; i <= 2; i++)
{
tempNumber += this["test" + i].x;
}
trace("tempNumber: " + tempNumber);
}
If i run the code like this, the line this["test" + i] returns a variable of the class. I need the local variable, the variable of the function.
Your loop on first step access plate0 this will cause not found error, if plate0 is not explicitly defined as class member variable or if class is not defined as dynamic. Same thing will happen for plate3, plate4, plate5... in case LAYER_PLATES.numChildren is more than 3.
EDIT:
Thanks to #Smolniy he corrected my answer plate0 is never accessed because cont is incremented before first access. So as he mentioned problem should be on plate3
You don't get the local variable with [] notation. your case has many solutions. You can use dictionary, or getChildAt() function:
function testFunction():void
{
var dict = new Dictionary(true);
var test1:Sprite = new Sprite();
var test2:Sprite = new Sprite();
var tempNumber:Number = 0;
addChild(test1);
dict[test1] = test1.x = 100;
addChild(test2);
dict[test2] = test2.x = 200;
for (var s:* in dict)
{
tempNumber += s.x;
//or tempNumber += dict[s];
}
trace("tempNumber: " + tempNumber);
};

AS3: Line graph is glitchy

Having a bit of a problem with some code I've written. Basically what it does is take 3 values that constantly change and graphs them over time in the form of a cumulative line graph. It almost works except I get this weird line drawn across the entire stage and further and I can't figure out what the issue is. The full code is below, you can run it by pasting it into flash.
import flash.display.Shape;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.utils.Timer;
var y1:Array = new Array();
var y2:Array = new Array();
var y3:Array = new Array();
var avg:Array = new Array();
var y1Shape:Shape = new Shape();
var y2Shape:Shape = new Shape();
var y3Shape:Shape = new Shape();
var avgShape:Shape = new Shape();
var container:Sprite = new Sprite();
var scale:uint = 1;
var redrawGraph:int = setInterval(reDraw,500);
var y1Int:int = 0;
var y2Int:int = 0;
var y3Int:int = 0;
container.addChild(y1Shape);
container.addChild(y2Shape);
container.addChild(y3Shape);
container.addChild(avgShape);
this.addChild(container);
function reDraw():void
{
y1Shape.graphics.clear();
y2Shape.graphics.clear();
y3Shape.graphics.clear();
avgShape.graphics.clear();
y1Shape.graphics.lineStyle(1, 0x0066FF, 1);
y1Shape.graphics.beginFill(0x0066FF, 0.5);
y2Shape.graphics.lineStyle(1, 0x009900, 1);
y2Shape.graphics.beginFill(0x009900, 0.5);
y3Shape.graphics.lineStyle(1, 0x990000, 1);
y3Shape.graphics.beginFill(0x990000, 0.5);
avgShape.graphics.lineStyle(1, 0x000000, 1);
y1Int = rand();
y2Int = rand();
y3Int = rand();
trace(y1Int, y2Int, y3Int);
y1.unshift(y1Int);
y2.unshift(y2Int);
y3.unshift(y3Int);
popOut(y1);
popOut(y2);
popOut(y3);
var i:uint,sum:uint,aLength:uint,len:uint = y1.length,max:int = 0,height_:int = 400;
scale = 10;
for (i=0; i<len; i++)
{
max = Math.max(y1[i] + y2[i] + y3[i],max);
}
for (i=0; i<len; i++)
{
sum += y1[i] + y2[i] + y3[i];
}
avg.unshift(Math.round(sum/len));
/*--------------------------------MATCHED GRAPH------------------------------------------*/
var y1_commands:Vector.<int> = new Vector.<int>();
var y1_coord:Vector.<Number>= new Vector.<Number>();
var y1_coord_rev:Vector.<Number> = new Vector.<Number>();
y1_commands.push(1);
y1_coord.push(400,height_);
for (i=0; i<len; i++)
{
y1_commands.push(2);
y1_coord.push((400-i*scale),height_-(Math.round((y1[i]/max)*height_)));
y1_coord_rev.unshift((400-i*scale),height_-(Math.round((y1[i]/max)*height_)));
}
for (i=len; i>0; i--)
{
y1_commands.push(2);
y1_coord.push(400 - i*scale,height_);
}
y1_commands.push(2);
y1_coord.push(400,height_);
/*--------------------------------MATCHED GRAPH------------------------------------------*/
/*----------------------------------BUSY GRAPH-------------------------------------------*/
var y2_commands:Vector.<int> = new Vector.<int>();
var y2_coord:Vector.<Number>= new Vector.<Number>();
var y2_coord_rev:Vector.<Number> = new Vector.<Number>();
y2_commands.push(1);
y2_coord.push(400,height_-(Math.round((y1[i]/max)*height_)));
for (i=0; i<len; i++)
{
y2_commands.push(2);
y2_coord.push((400-i*scale),height_-(Math.round(((y1[i]+y2[i])/max)*height_)));
y2_coord_rev.unshift((400-i*scale),height_-(Math.round(((y1[i]+y2[i])/max)*height_)));
}
for (i=len; i>0; i--)
{
y2_commands.push(2);
y2_coord.push(400 - i*scale, height_-(Math.round((y1[i]/max)*height_)));
}
y2_commands.push(2);
y2_coord.push(400,height_-(Math.round((y1[i]/max)*height_)));
/*----------------------------------BUSY GRAPH-------------------------------------------*/
/*----------------------------------VAC GRAPH-------------------------------------------*/
var y3_commands:Vector.<int> = new Vector.<int>();
var y3_coord:Vector.<Number>= new Vector.<Number>();
var y3_coord_rev:Vector.<Number> = new Vector.<Number>();
y3_commands.push(1);
y3_coord.push(400,height_-(Math.round(((y1[i]+y2[i])/max)*height_)));
for (i=0; i<len; i++)
{
y3_commands.push(2);
y3_coord.push((400-i*scale),height_-(Math.round(((y1[i]+y2[i]+y3[i])/max)*height_)));
y3_coord_rev.unshift((400-i*scale),height_-(Math.round(((y1[i]+y2[i]+y3[i])/max)*height_)));
}
for (i=len; i>0; i--)
{
y3_commands.push(2);
y3_coord.push(400 - i*scale, height_-(Math.round(((y1[i]+y2[i])/max)*height_)));
}
y2_commands.push(2);
y2_coord.push(400,height_-(Math.round(((y1[i]+y2[i])/max)*height_)));
/*----------------------------------BUSY GRAPH-------------------------------------------*/
//y3Shape.graphics.drawPath(y3_commands, y3_coord);
y2Shape.graphics.drawPath(y2_commands, y2_coord);
y1Shape.graphics.drawPath(y1_commands, y1_coord);
}
function popOut(a:Array):void
{
if (a.length >=Math.ceil(400/scale))
{
a.pop();
}
}
function rand():int
{
return Math.floor(Math.random() * (1 + 5 - 0) + 0);
}
y3Shape is commented out until the problem with y2Shape is fixed (having both drawn just makes the problem harder to figure out).
Any ideas what could be up?
Thanks
If you insert trace your vectors near .drawPath, you'll see something like that:
trace(y2_commands); // 1,2,2,2,2
trace(y2_coord); // 400,171,400,57,390,NaN,400,171,400,57
So, NaN (Not a Number) means, that you have error in coordinates calculating.
ps. y1[i] in first calculating of BUSY GRAPH is undefined
You seem to be using beginFill(), when you draw a path that's not looped, Flash requires your path to get looped in order to fill it with something. So, it loops it implicitly by adding a line to your starting point and filling it. In order to receive a non-overlapping path, add two points to your path that will be right below 0 point in X axis, one right under the last point on your graph, and one right under the FIRST point on the graph.
Actually, you already have them installed, but for some reason you place not 2 points, but a whole lot of em, and height position of that line is plainly wrong. Your code states:
for (i=len; i>0; i--)
{
y2_commands.push(2);
y2_coord.push(400 - i*scale, height_-(Math.round((y1[i]/max)*height_)));
}
You should have:
for (i=len; i>0; i--)
{
y2_commands.push(2);
y2_coord.push(400 - i*scale, height_);
}
Or even better:
y2_commands.push(2);
y2_commands.push(2);
y2_coord.push(400 - len*scale, height_);
y2_coord.push(400, height_);

Create "changset" of two bytearrays

I have some binary data. I will change over time, some bytes get added here and there, some get changed. Overall most of the bytearray remains the same.
Is there any library, preferably Actionscript 3, that generats a "changeset" (is there a better name for this?) out of two bytearrays. Also it should let me apply a changeset to a bytearray and return the resulting new bytearray.
Does this make sense? I was not sure how to formulate my problem best.
EDIT for Clarification:
What i want is something that only emits changes, thus making the "changeset" as small as possible. So if only 1KB of a 1MB Binary have changed, the changeset should be a bytearray of about 1KB size.
EDIT:
Basically i need an AS3 Version of http://www.daemonology.net/bsdiff/ i think
I do not know any AS3 library for that but if I understood you right, coding this from scratch isn't as hard or time-consuming as you might think. Here is my (naive) approach on that. Maybe this already fits your needs.
Example output
Code
package {
import flash.display.Sprite;
import flash.events.Event;
import flash.utils.ByteArray;
public class Main extends Sprite {
public function Main():void {
if (stage)
init();
else
addEventListener(Event.ADDED_TO_STAGE, init);
}
private function createDiff(original:ByteArray, comparedTo:ByteArray):ByteArray {
var diff:ByteArray = new ByteArray();
var length:uint = Math.min(original.length, comparedTo.length);
original.position = 0;
comparedTo.position = 0;
for (var i:int = 0; i < length; i++) {
var byteOriginal:int = original.readByte();
var byteComparedTo:int = comparedTo.readByte();
if (byteOriginal != byteComparedTo) {
diff.writeByte(byteComparedTo - byteOriginal);
}
else {
diff.writeByte(0);
}
}
diff.compress();
return diff;
}
private function applyDiff(original:ByteArray, diff:ByteArray):ByteArray {
var result:ByteArray = new ByteArray();
diff.uncompress();
original.position = 0;
diff.position = 0;
var length:uint = Math.min(original.length, diff.length);
for (var i:uint = 0; i < length; i++) {
var byteOriginal:int = original.readByte();
var byteDiff:int = diff.readByte();
result.writeByte(byteOriginal + byteDiff);
}
return result;
}
private function init(e:Event = null):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
// generate one random byte array and a slightly different variant
var length:uint = 128;
var a:ByteArray = new ByteArray();
var b:ByteArray = new ByteArray();
for (var i:int = 0; i < length; i++) {
var value:int;
value = 127 - Math.floor(Math.random() * 256);
a.writeByte(value);
if (value > 64) {
value = 127 - Math.floor(Math.random() * 256);
}
b.writeByte(value);
}
// create a diff and apply it to the original byte array for verification
var diff:ByteArray = createDiff(a, b);
var result:ByteArray = applyDiff(a, diff);
// trace the byte arrays
a.position = 0;
b.position = 0;
diff.position = 0;
result.position = 0;
var outputA:String = "";
var outputB:String = "";
var outputDiff:String = "";
var outputResult:String = "";
for (var k:int = 0; k < length; k++) {
outputA += a.readByte() + "\t";
outputB += b.readByte() + "\t";
outputDiff += diff.readByte() + "\t";
outputResult += result.readByte() + "\t";
}
trace("1st: \t" + outputA);
trace("2nd: \t" + outputB);
trace("diff:\t" + outputDiff);
trace("test:\t" + outputResult);
}
}
}