A Flash Developer Resource Site

Results 1 to 12 of 12

Thread: AddChild with Timer or ENTER_FRAME

  1. #1
    Junior Member
    Join Date
    Apr 2010
    Posts
    9

    AddChild with Timer or ENTER_FRAME

    Hi, I have been trying to add a child (ball) randomly on stage with a timer every certain time or with ENTER_FRAME, but I can't get it to work. In both cases it just add the first one and then stops, even though the timer keeps on working!
    Any idea?
    Thanks!!

    Here is the code:

    Actionscript Code:
    //Classes
    import com.greensock.*;
    import flash.ui.Keyboard;
    import flash.display.MovieClip;
    import flash.events.MouseEvent;

    //Variables
    var max:Number = 580
    var min:Number = 20
    var ball:MovieClip = new Pelota ();
    var randomNumber:Number = Math.round(Math.random() * (max - min) + min);
    var timer:Timer = new Timer(1000, 5);

    timer.addEventListener(TimerEvent.TIMER, onTimer, false, 0, true);
    timer.start();

    function onTimer(evt:TimerEvent):void {
    addChild(ball);
    ball.x = randomNumber
    TweenLite.to(ball, 3, {y:504});
    trace (timer);
    }

  2. #2
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    You are adding the same ball every time. You need to create a new ball each time.
    Code:
    //Classes
    import com.greensock.*;
    import flash.ui.Keyboard;
    import flash.display.MovieClip;
    import flash.events.MouseEvent;
    
    //Variables
    var max:Number = 580
    var min:Number = 20
    var timer:Timer = new Timer(1000, 5);
    
    timer.addEventListener(TimerEvent.TIMER, onTimer, false, 0, true);
    timer.start();
    
    function onTimer(evt:TimerEvent):void {
      var ball:MovieClip = new Pelota ();
      var randomNumber:Number = Math.round(Math.random() * (max - min) + min);
      addChild(ball);
      ball.x = randomNumber
      TweenLite.to(ball, 3, {y:504});
      trace (timer);
    }

  3. #3
    Junior Member
    Join Date
    Apr 2010
    Posts
    9
    Hey! Thanks man!
    That worked perfectly!!

  4. #4
    Junior Member
    Join Date
    Apr 2010
    Posts
    9
    Hi, The more I try to do things, the more errors I get!
    Now I'm trying to detect a collision between the ball that is falling and a bar. I detect the collision and I can make disappear the ball, but still I get an error:

    ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller.
    at flash.display:isplayObjectContainer/removeChild()

    I still can't figure out the whole thing about parent, child and this. I get so confused!

    Thanks!!

    Actionscript Code:
    //Classes
    import com.greensock.*;
    import flash.ui.Keyboard;
    import flash.display.MovieClip;
    import flash.events.MouseEvent;

    //Variables
    var max:Number = 580
    var min:Number = 20
    var timer:Timer = new Timer(2000);

    ///////////////////

    timer.addEventListener(TimerEvent.TIMER, onTimer, false, 0, true);
    timer.start();

    function onTimer(evt:TimerEvent):void {
        var randomNumber:Number = Math.round(Math.random() * (max - min) + min);
        var ball:MovieClip = new Pelota ();
        addChild(ball);
        ball.x = randomNumber
        TweenLite.to(ball, 3, {y:504});
        trace (timer);
       
        stage.addEventListener(Event.ENTER_FRAME, mouse, false, 0, true);
       
            function mouse(evt:Event):void
            {
                barra_mc.x = mouseX;
                if (barra_mc.hitTestObject(ball))
                {
                    removeChild(ball);
                    trace ("touched");
                }
            }
    }

  5. #5
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    Once it's already removed, you can't remove it again. You should remove the event listener at the same time you remove the ball.

    Also, you should not nest functions like that, and you should not name a function "mouse".

    I think you nested the functions in order to have access to ball, because ball is a local variable in onTimer. Instead, keep an array of all the balls, and use a single enter frame listener to test for and remove all the balls that need it.

  6. #6
    Junior Member
    Join Date
    Apr 2010
    Posts
    9
    Thanks, when I removed the eventlistener it worked perfectly.
    Can I ask you a question? Why I shouldn't nest functions? It makes everything more complicated? Does it affect the performance of the application?

    I tried what you said. Make a variable and have my balls there. But, I can't add them to stage. How can I put a movieclip inside of a variable and then put it in the stage? I'm completely lost.

  7. #7
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    When you nest functions, you introduce advanced concepts of scope capture and closures. Most of the time, things are much simpler when you don't have nested functions. In addition, it's very easy to create multiple identical functions without realizing it, and that is usually a performance drain. In this case, you have an enter frame listener for each ball doing pretty much the same thing. Using a single function which processes all the balls will be more efficient.

    I'm not sure where your difficulty is adding things to the display. That part shouldn't have to change.

    Code:
    //Classes
    import com.greensock.*;
    import flash.ui.Keyboard;
    import flash.display.MovieClip;
    import flash.events.MouseEvent;
    
    //Variables
    var max:Number = 580
    var min:Number = 20
    var timer:Timer = new Timer(2000);
    var balls:Array = [];
    ///////////////////
    
    timer.addEventListener(TimerEvent.TIMER, onTimer, false, 0, true);
    timer.start();
    
    addEventListener(Event.ENTER_FRAME, testBalls, false, 0, true);
    
    function onTimer(evt:TimerEvent):void {
        var randomNumber:Number = Math.round(Math.random() * (max - min) + min);
        var ball:Pelota = new Pelota ();
        addChild(ball);
        balls.push(ball);
        ball.x = randomNumber
        TweenLite.to(ball, 3, {y:504});
        trace (timer);
    }
       
    function testBalls(evt:Event):void{
        barra_mc.x = mouseX;
        for (var i:int = 0; i < balls.length; i++){
          var ball:Pelota = balls[i]
          if (barra_mc.hitTestObject(ball)){
           removeChild(ball);
           balls.splice(i, 1);
           i--;
           trace ("touched");
          }
        }
    }

  8. #8
    Junior Member
    Join Date
    Apr 2010
    Posts
    9
    Aha! Ok, I was trying to push the ball in the opposite way you did it.
    But, what is the difference between the way you put the array of ball with [] and ()?

    And I don't really understand what you did in the testBalls function. Why did you use a For loop? To make the balls keep on falling?
    But this bunch of code I don't really get it.

    Actionscript Code:
    var ball:Pelota = balls[i]
    if (barra_mc.hitTestObject(ball)){
    removeChild(ball);
    balls.splice(i, 1);
    i--;

    Thanks a lot!

  9. #9
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    I don't understand the question about [] vs (). [] is array literal notation for an empty array. I could have written:
    Code:
    var balls:Array = new Array();
    And that would be the same thing.

    I use a for loop in the testBalls function to iterate over all of the balls in the array. It does not make them keep falling.

    Let me comment on the code you've quoted.
    Code:
    var ball:Pelota = balls[i];//Get the ball at index i from the balls array
    if (barra_mc.hitTestObject(ball)){ //test that barra_mc against that ball
      removeChild(ball); //remove the ball from the display
      balls.splice(i, 1); //remove the ball from the array
      i--;//because we changed the array, we need to decrement i to be sure we process all balls.
    }

  10. #10
    Junior Member
    Join Date
    Apr 2010
    Posts
    9
    That is what I was saying of the array, I didn't know that you could do it in both ways to set it empty.

    The index i is the first position of the index? like 0? And if it is, and you only have a ball at a time, why do you have to decrement at the of the function instead of increment one?
    I'm a bit confused about that.

    Thanks for your time and the explanations!

  11. #11
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    i is a variable. It starts at 0, and increments by one each time through the loop. That's why when we remove a ball from the array with splice, we have to alter i.

    Say there are 5 balls, and we remove the one at index 2:
    [ball0, ball1, ball2, ball3, ball4] becomes [ball0, ball1, ball3, ball4]
    If we did not decrement i, then it would increment to 3, and the next ball to be tested would be ball4. Because ball3 and ball4 moved forward one index when we removed ball2, we have to adjust i so that index 2 is processed again.

  12. #12
    Junior Member
    Join Date
    Apr 2010
    Posts
    9
    Ohh, I got it (I think) haha! I need to read more about this and display list.

    Thanks a lot for you time. I really I appreciate it.

    Cheers!

Tags for this Thread

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