A Flash Developer Resource Site

Results 1 to 11 of 11

Thread: Is it possible to access a child of a movieclip without using the movieclip name?

  1. #1
    Member
    Join Date
    Oct 2008
    Posts
    35

    Is it possible to access a child of a movieclip without using the movieclip name?

    Here's the situation,
    I've got a dozen movie clips on stage, each with 3 children, and each of those have 8 children, as example named u01-u08.

    Is it possible to access u01 directly without the parent names? like a wildcard? like the xml way of getting to nodes with a .. ?

    sort of like:
    stage..u01.alpha = .5;

    Thanks in advance!

  2. #2
    Senior Member jweeks123's Avatar
    Join Date
    Mar 2006
    Posts
    1,124
    Well, you could if you define them in variables in your script. For example.

    you have mc0 with child mcChild0, with children of u01 - u08.

    in your script:

    var mc0Arr:Array = new Array();
    for(var i:Number = 0; i<mc0.mcChild0.numChildren; i++) {
    mc0Arr.push(mc0.mcChild0["u0"+i]);
    }

    Then you could access them like mc0Arr[index].

    Does this help?

  3. #3
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    jweeks code will work for what it attempts to do, but it's essentially reproducing the getChildAt function. And neither of those is what the original question was asking for.

    No, there's no xpath-like syntax to access a particular instance as if it were in a document. You're far better off keeping variables that point directly at the objects you're interested in, or keeping them in a collection appropriate to your processing.

    It would be an interesting exercise to implement the xpath style access through recursively processing the displaylist and building an xml document along with a dictionary mapping xml nodes to instances. But ultimately it would be extremely inefficient.

  4. #4
    Member
    Join Date
    Oct 2008
    Posts
    35
    Both answers are helpful, thanks gents.
    Bummer that I cant just do something to the grand-child without the full path. Would have made life a little easier...

    I may resort to iterating through all the children of the children, as jweeks suggests, since I don't feel like declaring paths to 500 grandchildren. I may have 25 children to affect at a time, so maybe just a if child name == var, do this...

  5. #5
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    My point was that you don't need paths at all. Just keep direct references in a variable or array. It does not matter where on the displaylist the item are, you can still keep them together in your code.

  6. #6
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    So, as I said, it was an interesting exercise to implement xpath style access of the displaylist. I've attached an implementation that does just that. It depends on the xpath-as3 project.

    see the included Main.as for example usage. The basics are:
    Code:
    var md:MovieDocument = new MovieDocument(someDisplayObject, true);
    Where someDisplayObject will be the root context for your xpath, and true indicates that the MovieDocument should automatically update itself as stuff is added and removed from the displayList.

    Then, once you have a MovieDocument, you can use it like this:
    Code:
    trace(md.xpath("//*[@type='flash.display::Sprite']")); //gets all Sprites in subtree
    trace(md.xpath("/s1")); //gets all children of someDisplayObject with name == s1
    trace(md.xpath("//s1")); //gets all descendents of someDisplayObject with name == s1
    Enjoy.
    Attached Files Attached Files

  7. #7
    half as fun, double the price senocular's Avatar
    Join Date
    Feb 2002
    Location
    San Francisco, CA (USA)
    Posts
    4,358
    5TonsOfFlax: Does setting properties also work? when considering a solution (in my head) that was the one thing that was tripping me up. As per the original post:

    stage..u01.alpha = .5;

  8. #8
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    No, this is only to access instances. After you have them, you can manipulate them like usual. It is also xpath, not e4x, so the syntax is slightly different.

    Your example would be something like this:
    Code:
    var md:MovieDocument = new MovieDocument(stage);
    var u01s:Array = md.xpath("//u01");
    for (var i:int = 0; i < u01s.length; i++){
      u01s[i].alpha = .5;
    }
    It would be easy enough to inline that
    Code:
    var md:MovieDocument = new MovieDocument(stage);
    md.xpath("//u01").forEach(function(item:*, index:int, array:Array):void{item.alpha = 0.5;});

  9. #9
    half as fun, double the price senocular's Avatar
    Join Date
    Feb 2002
    Location
    San Francisco, CA (USA)
    Posts
    4,358
    I thought I'd give this a shot. This uses E4X syntax for display objects. Class is attached (Proof of concept; use at own risk; may be bugs)

    Example code:
    PHP Code:
    // ECMAScript For Display Lists instance
    var me:E4DL = new E4DL(this);


    // property access
    this.foo "bar";
    trace(me.@foo); // bar

    me.@foo "none";
    trace(this.foo); // none

    delete me.@foo;
    trace(this.foo); // undefined


    // display list traversal
    addChild(new Sprite()).name "a";
    addChild(new MovieClip()).name "b";
    Sprite(getChildByName("a")).addChild(new Shape()).name "c";
    MovieClip(getChildByName("b")).addChild(new Bitmap()).name "c";

    trace(me.a); // [object Sprite]
    trace(me.b); // [object MovieClip]
    trace(me.c); // 
    trace(me.a.c); // [object Shape]
    trace(me..c); // [object Bitmap],[object Shape]


    // multiple property access
    trace(me..c.@alpha); // 1,1
    me..c.@alpha .5;
    trace(Sprite(getChildByName("a")).getChildByName("c").alpha); // 0.5
    trace(MovieClip(getChildByName("b")).getChildByName("c").alpha); // 0.5 
    Last edited by senocular; 08-15-2009 at 09:08 PM.

  10. #10
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    Very nice. Excellent use of proxy. The only thing that looks a little awkward is using a returned value/set as the base type. But I see that there is a method to get the source list.

  11. #11
    half as fun, double the price senocular's Avatar
    Join Date
    Feb 2002
    Location
    San Francisco, CA (USA)
    Posts
    4,358
    Quote Originally Posted by 5TonsOfFlax View Post
    But I see that there is a method to get the source list.
    That's actually an error. There should be no direct class properties as it would interfere with lookup. Consider the following:
    PHP Code:
    var me:E4DL = new E4DL(this);
    addChild(new Sprite()).name "notSource";
    addChild(new Sprite()).name "source";
    trace(me.notSource); // [object Sprite]
    trace(me.source); // [object MainTimeline] 
    me.source should also have a sprite. Instead it's providing the source list. That's why length is a function and not a property (just like in E4X XML). I just neglected that aspect of the source property due to habit.

    That's not saying that this approach still isn't a little awkward. The fact remains that all instances are comparable to XMLLists rather than single XML instances. I suppose a separate class could be created to facilitate that, but I don't feel like making it . What this means is that it's a little hard to access a single value since they're all lists. Though the way I have it set up now, using array access with numbers will give you a direct reference to an object in the source list.
    PHP Code:
    var me:E4DL = new E4DL(this);
    addChild(new Sprite()).name "notSource";
    trace(getQualifiedClassName(me.notSource)); // E4DL
    trace(getQualifiedClassName(me.notSource[0])); // flash.display::Sprite 
    Of course then its a question of * style access. For example, how would you get all display objects in me? I haven't implemented *, but if I did, it would give you just the source list, which in the case of me, is [me], not all the children of me. And me[0] is a direct reference to the main timeline, not a E4DL instance capable of iterating through the children of the main timeline. So yes, it's weird. But it was just a POC anyway. I'm sure a lot of this (if not all) could probably be resolved with the singular XML-like instance (i.e. something like E4DL and E4DLList).

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center