How do I access all of the children of a DisplayObject programatically? - actionscript-3

How do access all of the children of a DisplayObject using code? (I'm looking for something like movieclip.children)
I'm using this in two cases:
1) To loop through and reposition all of the children of an enclosing MovieClip.
Or
2) To loop through and delete all of the children of a MovieClip
Also, this is a Flash CS5 project.

This loop will touch every child inside movieclip foo. I'm not sure what you're going to do to them, but you can run whatever methods you need inside the loop.
for (var i:uint=0; i<foo.numChildren;i++){
foo.getChildAt(i).whateverMethodYouNeed();
}

Is your object just a display object? If it is an UIComponent, you could use getChildAt() and getChildByName() along with the numChildren property to loop over them. Is this part of a flex project or an actionscript only project?
A DisplayObject itself does not have the mechanisms to describe its children. The lowest level type that knows about children is the DisplayObjectContainer. You may have to convert the object into at least a DisplayObjectContainer to be able to do what you want. I would go with an UIComponent though if you have the flex framework to work with.
DisplayObject
DisplayObjectContainer
UIComponent

If you need to access all the children, inclusive of a child's children, you can try
this:
function doWhatever( mc:DisplayOjectContainer ):void
{
if( mc.numChildren > 0 )
for( var i:int ; i < mc.numChildren ; ++i )
{
//if you need to reposition
//set the points properties here
var point:Point = new Point( _x , _y );
setPosition ( mc.getChildAt(i ) , point );
//if you need to remove all children
//do it recursively
//remove( mc , mc.getChildAt( i );
}
}
function setPosition(mc:DisplayObject , point:Point ):void
{
mc.x = point.x ;
mc.y = point.y;
}
function remove(container:DisplayObjectContainer , child:DisplayObject ):void
{
//this will remove all children before being removed
if( child is DisplayObjectContainer )
{
var doc:DisplayObjectContainer = child as DisplayObjectContainer;
doWhatever( doc );
}
container.removeChild( child );
child = null;
}

Related

How to call on a variable from parent? AS3

Let's say I have a variable in the actionscript panel on a movieclip
parent_mc:
var ispaused:Boolean = false;
inside this movieclip is another movieclip with its own actionscript
child_mc:
if (!ispaused)
{ gotoAndPlay(1); }
How do I call for a variable from the parent when dealing the actionscript inside a child movieclip?
Ahem...
if (parent.ispaused) // ...
And if this does not work due to compile time type casting:
if (parent["ispaused"]) // ...
Or you can typecast:
if ((parent as ParentClass).ispaused) // ...
I have actually found that this is the proper way to call upon a variable from the parent, quite literally MovieClip(root) is not to change.
if ((MovieClip(root).entervariablename))
{ dothisaction; }
or to modify the variable value
if (thistrigger)
{ (MovieClip(root).entervariablename) = desiredvalue; }
On the parent MovieClip Timeline (I suppose that Your code is placed on it) :
var isPaused:Boolean=false;
function doSometing():void{
trace("function doSomething called in parent MovieClip");
}
On the child MovieClip Timeline:
import flash.display.MovieClip;
var parentClip:MovieClip = (parent as MovieClip);
var parentPaused:Boolean = parentClip.isPaused;
if (!parentPaused){
trace("parent clip isPaused = " + parentPaused);
parentClip.doSometing();
// Do what you want here
}
Output:
parent clip isPaused = false
function doSomething called in parent MovieClip

AS3 + Starling - Find Unknown Sprite

I have legacy code project. While Starling is running sometimes some Sprite appears and covers all application.
In pure flash I used "console" https://code.google.com/p/flash-console/wiki/GettingStarted to get object hierarhy in display tree. But it doesn`t work for Starling.
My idea is to add some listener to root, cause this Sprite is in display list tree.
And find who is this Spite's parent.
Is it possible?
And find who is this Spite's parent. Is it possible?
If you are trying to find a display object, and you have no idea where it is coming from, one thing you could try doing is in a frame event, keep track of all the new sprites that are added to the display list. Then you can work backwards from there. Eg.
// keep track of unique display objects
private var _displayList:Array = [];
public function Main()
{
addEventListener( Event.ENTER_FRAME, trackDisplayList );
}
private function trackDisplayList( event:Event ):void
{
trackAsset( stage );
}
private function trackAsset( asset:* ):void
{
var i:int = -1;
while( ++i < asset.numChildren )
{
var child:* = asset.getChildAt( i );
if ( _displayList.indexOf( child ) == -1 )
{
_displayList.push( child );
trace( "tracking display object: " + child.name );
}
if ( child.numChildren > 0 )
{
trackAsset( child );
}
}
}
Hopefully you don't have a boat load of sprites to sort through! This is one way you could recursively check all your unique display objects.

AS3 removing all children from array in a class from parent class

In the Level 1 class (Parent) I generate citizens as seperate objects (c) to walk from left or right across the stage. all of these get added to an array called citizens:
if (citizens.length < 10)
{
// create citizen
var c:Citizen = new Citizen(side,speed,yPos);
addChildAt(c, 2);
citizens.push(c);
}
I want to remove each instance of the class and also remove the event listener that is attached to it in the class:
this.addEventListener(Event.ENTER_FRAME,moveCitizen);
Would I use a for each then splice from the array? E.G
for each (c in citizens) {
removeEventListener(Event.ENTER_FRAME,moveCitizen);
splice();
}
You could do something similar to the following:
// Creation
if (citizens.length < 10) {
// create citizen
var c:Citizen = new Citizen( side, speed, yPos );
addChildAt( c, 2 );
citizens.push( c );
}
// Removal
for( var i:int = 0; i < citizens.length; i++ ) {
var c:Citizen = citizens[ i ].pop();
removeChild( c )
c.cleanUp();
}
// In Class Citizen
public function cleanUp():void {
removeEventListener( Event.ENTER_FRAME, moveCitizen );
}
#user1878381 you have to make one method in citizens class if you needed to call in every object say reset(). when you removed a object you must call reset function of that object which reset the citizes by removing all eventlistner and reset all property of citizens in that object.
you can use array.pop() method to popout a latest pushed object from array by for each looping. if you are using array then array have many functionality like shift, pop, splice(i,1). etc...
i think for each is the best one among all..

flash as3 - prevent object from being used as dropTarget

Is there a way to prevent a flash movieclip (or its children) from being used as a dropTarget? I have objects on the stage which are getting in the way of my determining the underlying stage object where a draggable item is being dropped.
There is no way to prevent a flash movieclip (or its children) from being used as a dropTarget.
You could control it from the other end:
function onMouseUp( e:MouseEvent ):void
{
var obj = evt.target;
var target = obj.dropTarget;
if( target != nonDropAreaMovieClip )
{
obj.stopDrag();
}
}
or if you want the obj to be actually dropped to the backgroundMovieClip, which is behind the nonDropAreaMovieClip, you could calculate the global/local coorinates and just do:
function onMouseUp( e:MouseEvent ):void
{
var obj = evt.target;
var target = obj.dropTarget;
if( target != nonDropAreaMovieClip )
{
obj.stopDrag();
obj.x = //calculated x
obj.y = //calculated y
backgroundMovieClip.addChild( obj );
}
}
I've worked around a similar issue by creating movieclips that are transparent and placing them over the drop regions, or by creating a layer with a transparent object as the topmost layer to prevent the children (in the movieclip) from becoming the dropTarget.

Detech event target from which position of Array

I have a loop MC which will be duplicate to stage several times according to every click.
Now I want to detect if the MC being click belongs to which position in the array.
private function levelsBG():void {
LIST = new MovieClip();
d++;
for (var i:Number=0; i<myXML.children().length(); i++) {
listMC=new MovieClip();
LIST.addChild(listMC);
listMC.addEventListener(MouseEvent.CLICK,listClick);
}
listArray.push(LIST);
LISTmc.addChild(LIST);
addChild(LISTmc);
}
private function listClick(event:MouseEvent):void {
var currentListArray=listArray[listArray.length-1];
//trace from which position of Array
trace(listArray.length-event.target.parent)
}
why do you lookup the parent? maybe use mouseChildren = false, so event.target points to you clip ...
to find the index, use Array::indexOf, so should be something like trace(listArray.indexOf(event.target)) in the end ...