Looping through childs in actionscript-3 - actionscript-3

How do you loop through all the childs in a DisplayObjectContainer in as3? I would like a syntax like this:
for each(var displayObject:DisplayObject in displayObjectContainer )
{
displayObject.x += 10;
displayObject.y += 10;
}

Not sure if for each works, but this works.
for (var i:int = 0; i<myObj.numChildren; i++)
{
trace(myObj.getChildAt(i));
}

something like this maybe?
function getChildren(target:DisplayObjectContainer):Array {
var count:uint = target.numChildren;
var ret:Array = [];
for (var i:int = 0; i < count; i++)
ret.push(target.getChildAt(0));
return ret;
}
and then
for each (var child:Array in getChildren(displayObjectContainer)) {
//....
}
greetz
back2dos

You can use following recursive function to iterate through all children of any DisplayObjectContainer class.
function getChildren(dsObject:DisplayObjectContainer, iDepth:int = 0):void
{
var i:int = 0;
var sDummyTabs:String = "";
var dsoChild:DisplayObject;
for (i ; i < iDepth ; i++)
sDummyTabs += "\t";
trace(sDummyTabs + dsObject);
for (i = 0; i < dsObject.numChildren ; ++i)
{
dsoChild = dsObject.getChildAt(i);
if (dsoChild is DisplayObjectContainer && 0 < DisplayObjectContainer(dsoChild).numChildren)
getChildren(dsoChild as DisplayObjectContainer,++iDepth);
else
trace(sDummyTabs + "\t" + dsoChild);
}
}
It will display all children in hierarchical manner exactly as DisplayList tree.

My two cents.
public static function traceDisplayList(displayObject:DisplayObject, maxDepth:int = 100, skipClass:Class = null, levelSpace:String = " ", currentDepth:int = 0):void
{
if (skipClass != null) if (displayObject is skipClass) return;
trace(levelSpace + displayObject.name); // or any function that clean instance name
if (displayObject is DisplayObjectContainer && currentDepth < maxDepth)
{
for (var i:int = 0; i < DisplayObjectContainer(displayObject).numChildren; i++)
{
traceDisplayList(DisplayObjectContainer(displayObject).getChildAt(i), maxDepth, skipClass, levelSpace + " ", currentDepth + 1);
}
}
}

Related

adding X amount of addChild per maxvalue in loop

The assignment is the spawn several light and dark feathers according to score points from a quiz. The light feathers symbolize the correct points (light_feather), and the dark feather are the incorrect points (dark_feather) (Each are being tracked). All the feathers are supposed to line up on one line, meaning first light feathers, followed by the dark feathers. I got the quiz dynamics figured out, and the function I have posted here is only for when they press end quiz.
var light_feather:LightFeather = new LightFeather();
var dark_feather:DarkFeather = new DarkFeather();
var good_answers:uint = 0;
var bad_answers:uint = 0;
function avsluttFunc (evt:MouseEvent)
{
var sum_LightFeatherX:Number = 0;
for (var i = 0; i < good_answers; i++) {
addChild(light_feather);
light_feather.x += 12 + (i*16);
light_feather.y = 0;
trace("Lys X-verdi: " + light_feather.x);
sum_LightFeatherX += Number(light_feather.x);
return sum_LightFeatherX;
}
trace(sum_LightFeatherX);
dark_feather.x += sum_LightFeatherX;
for (var j = 1; j <= bad_answers; j++) {
addChild(dark_feather);
dark_feather.x += 12 + (j*16);
dark_feather.y = 0;
trace("Mørk X-verdi: " + dark_feather.x);
}
/*
//Resetter poengsummen
good_answers = 0;
bad_answers = 0;
*/
}
You can do what you are looking for using only one for loop, take a look :
var good_answers:uint = 2;
var bad_answers:uint = 4;
function avsluttFunc(evt:MouseEvent)
{
for (var i:int = 0; i < good_answers + bad_answers; i++) {
var feather:DisplayObject = i < good_answers ? new LightFeather() : new DarkFeather();
feather.x += 12 + i * (feather.width + 1);
feather.y = 0;
addChild(feather);
}
}
This code example will create 4 DarkFeather instances next to 2 LightFeather ones.
Edit :
How to add your objects to an array ?
// feathers array should be accessible for both codes (adding and removing objects)
var feathers:Array = [];
for (var i:int = 0; i < good_answers + bad_answers; i++) {
var feather:DisplayObject = i < good_answers ? new LightFeather() : new DarkFeather();
addChild(feather);
feathers.push(feather);
}
then to remove them from the stage, you can do for example :
for (var i:int = 0; i < feathers.length; i++) {
var feather:DisplayObject = DisplayObject(feathers[i]);
feather.parent.removeChild(feather);
}
Hope that can help.

Autocomplete search for any word in the sentence

I'm using an autocomplete for my flash app. The autocomplete uses an external text file.
When I'm typing the first word of the sentence, it display all the sentences that begins with this word.
Is it possible to display all sentence that have this word (and not just the begining of the sentence) ?
Exemple :
I've got two phrases : "I'm going to school" and " I'm going to look for him".
I would like to be able to type "school" and that it displays the first sentence.
Do you know how I can do that ?
For now, I have to type "I'm going to s" in order to display the first sentence.
Here's my code :
urlLoader.load(new URLRequest("test.txt"));
urlLoader.addEventListener(Event.COMPLETE, loadComplete);
inputField.addEventListener(KeyboardEvent.KEY_UP, suggest);
function loadComplete(e:Event):void
{
suggestions = e.target.data.split(",");
}
function suggest(e:KeyboardEvent):void
{
suggested = [];
for (var i:int = 0; i < textfields.length; i++)
{
removeChild(textfields[i]);
}
textfields = [];
for (var j:int = 0; j < suggestions.length; j++)
{
if (suggestions[j].indexOf(inputField.text.toLowerCase()) == 0)
{
var term:TextField = new TextField();
term.width = 300;
term.height = 20;
term.x = 70;
term.y = (20 * suggested.length) + 314;
term.border = true;
term.borderColor = 0x353535;
term.background = true;
term.backgroundColor = 0xFF9900;
term.textColor = 0x4C311D;
term.defaultTextFormat = format;
term.addEventListener(MouseEvent.MOUSE_UP, useWord);
term.addEventListener(MouseEvent.MOUSE_OVER, hover);
term.addEventListener(MouseEvent.MOUSE_OUT, out);
term.addEventListener(MouseEvent.CLICK, tellMe);
addChild(term);
textfields.push(term);
suggested.push(suggestions[j]);
term.text = suggestions[j];
}
}
if (inputField.length == 0)
{
suggested = [];
for (var k:int = 0; k < textfields.length; k++)
{
removeChild(textfields[k]);
}
textfields = [];
}
if(e.keyCode == Keyboard.DOWN && currentSelection < textfields.length-1)
{
currentSelection++;
textfields[currentSelection].textColor = 0x4C311D;
}
if(e.keyCode == Keyboard.UP && currentSelection > 0)
{
currentSelection--;
textfields[currentSelection].textColor = 0x4C311D;
}
if(e.keyCode == Keyboard.ENTER)
{
inputField.text = textfields[currentSelection].text;
suggested = [];
for (var l:int = 0; l < textfields.length; l++)
{
removeChild(textfields[l]);
}
textfields = [];
currentSelection = 0;
}
}
function useWord(e:MouseEvent):void
{
inputField.text = e.target.text;
suggested = [];
for (var i:int = 0; i < textfields.length; i++)
{
removeChild(textfields[i]);
}
textfields = [];
}
Thank you
Change the condition from:
suggestions[j].indexOf(inputField.text.toLowerCase()) == 0
to
suggestions[j].indexOf(inputField.text.toLowerCase()) != -1

Checking for straight combination in poker

I want to check for a straight combination in a poker game.
So, I have this array: var tempArr:Array = new Array;
I have this for sorting the array:
for (i = 0; i < 7; i++)
{
tempArr[i] = pValue[i];
}
tempArr.sort( Array.NUMERIC );
pValue is the value of the cards, it's have range from 2 to 14.
So, if I have this Array: tempArray = [2,3,3,4,5,5,6];
How can I check if I have a straight combination in my hand?
Set a bucket array to save if you got a card in hand
var t:Array = [];
//t[2] = 1;mean you have 2
// t[3] = 0;mean you don't have 3
//first initialize t
for(var i:int = 0; i < 15; i++)
{
t[i] = 0;
}
//then set the values from tempArray
for (var j:int = 0; j < tempArray.length; j++)
{
t[tempArray[j]] = 1;
}
//if you have a straight combination in your hand
//you will get a k that t[k] & t[k-1]& t[k-2] & t[k-3] & t[k-4] == 1
var existed:boolean = false;//the flag save if you got a straight combination
for (var k:int = t.length - 1; k >= 4; k--)
{
if (t[k] == 0)
{
continue;
}
if ((t[k] & t[k-1] & t[k-2] & t[k-3] & t[k-4]) == 1)
{
existed = true;
break;
}
}

Accessing variable names dynamically

I have the following scenario:
if (event.status == AMFResultEvent.SUCCESS) {
var lev1:uint = 0;
var lev2:uint = 0;
var lev3:uint = 0;
var lev4:uint = 0;
var lev5:uint = 0;
var lev6:uint = 0;
for (var i:int = 0; i < event.result.length; i++) {
if (mainLevel == "1") {
lev1++;
}
if (mainLevel == "2") {
lev2++;
}
if (mainLevel == "3") {
lev3++;
}
if (mainLevel == "4") {
lev4++;
}
if (mainLevel == "5") {
lev5++;
}
if (mainLevel == "6") {
lev6++;
}
}
for (var j:int = 1; j < 7; j++) {
_row = new StatisticsRow(event.result[j], this);
_rowsPlace.addChild(_row);
_row.y = (_row.height +1) * j;
_row.codeLevel.htmlText = j; // works as it should
// need to access variables lev1 - lev6, called by something like "lev"+j here:
_row.amount.htmlText =
}
// traces correct amounts of mainLevels from the i loop:
trace ("level 1: " + lev1);
trace ("level 2: " + lev2);
trace ("level 3: " + lev3);
trace ("level 4: " + lev4);
trace ("level 5: " + lev5);
trace ("level 6: " + lev6);
}
I'm missing something obvious here, as the ["lev"]+j doen't work. How can I dynamically acces the lev1 - lev6 in the j-loop? As the code comment at the bottoms shows, this traces as expected.
Thanks in advance!
You can access them with brackets, string concatenation, and the this keyword. Here's an example of how you would use bracket notation in a loop:
for (var i:int = 0; i <= 6; i++) {
var currLev = this["lev"+i];
// do stuff to currLev
}
Thanks for answering guys!
I had a lousy approach to my problem anyway, and should have used an array right away:
var mainLevels:Array = new Array();
for (var n:int = 1; n < 7; n++) {
mainLevels[n] = 0;
}
if (event.status == AMFResultEvent.SUCCESS) {
for (var i:int = 0; i < event.result.length; i++) {
var data = event.result[i];
var correctCode:String = data["correct"];
var mainLevelFound:uint = uint(correctCode.substr(0, 1));
for (var k:int = 1; k < 7; k++) {
if (k == mainLevelFound) {
mainLevels[k]++;
}
}
}
for (var j:int = 1; j < 7; j++) {
_row = new StatisticsRow(event.result[j], this);
_rowsPlace.addChild(_row);
_row.y = (_row.height +1) * j;
_row.codeLevel.htmlText = j;
// Now this works as a reference to mainLevels[*] created above!
_row.amount.htmlText = mainLevels[j];
}
Thanks again for your effort :)

Putting displacement between circles

I would like to set a displacement between the circles that are drawn here. Besides, I would like to copy the circles positions to the head circle, but the offset of course is cleared due to that.
public var circles:Vector.<circle> = new Vector.<circle>(5);
public function t()
{
var offset:int = 10;
for ( var i:int = 0; i<5; i++)
{
var c:circle = new circle();
c.xPosition= 120+offset;
c.yPosition = 120;
c.vx = 1;
c.vy = 0;
circles[i] = c;
offset+=40;
}
addEventListener(Event.ENTER_FRAME, gameLoop);
}
public function gameLoop(event:Event):void
{
for ( var i:int = 0; i<5; i++)
{
addChild(circles[i]);
circles[i].drawCircle(circles[i].xPosition, circles[i].yPosition);
}
for ( var i:int = 0; i<5; i++)
{
if ( i != 0 )
{
circles[i].xPosition = circles[i-1].xPosition;
circles[i].yPosition = circles[i-1].yPosition;
}
else {
}
}
circles[0].xPosition-=circles[0].vx*(2*5);
circles[0].yPosition-=circles[0].vy*(2*5);
}
Do the loop from back to front. What you did change every circle's position same with circle 0
for ( var i:int = 4; i > 0; i--)
{
circles[i].xPosition = circles[i-1].xPosition;
circles[i].yPosition = circles[i-1].yPosition;
}