Search code examples
flashactionscriptmovieclip

ActionScript 3: Make the movieclip play to the end


(I am a complete noob, this is one of my first scripts in Flash/AS3 so excuse me if this is "common knowledge")
I have a "smiley" movie clip that is around 10 frames.
Presently when a person clicks and drags I get the smiley face next to the cursor, this is my code:

stage.addEventListener(MouseEvent.MOUSE_MOVE, mousePosition);

var smiley:MovieClip = addChild(new Smiley) as MovieClip; 
stage.addEventListener(MouseEvent.MOUSE_DOWN,toggleSmiley);
stage.addEventListener(MouseEvent.MOUSE_UP,toggleSmiley); 

function mousePosition(event:MouseEvent) {
smiley.x = mouseX; smiley.y = mouseY;

}

function toggleSmiley(e:MouseEvent):void
{
    smiley.visible = (e.type == MouseEvent.MOUSE_DOWN); 
    }

The problems are:
1 - If a person clicks and releases quickly it does not play the whole smiley movieclip, as they release it disappears, how do I make it play the whole smiley movie clip?

2 - if they click and drag I want it to leave a trail of smilies that play exactly like point 1 above.

Any ideas?

Thanks in advance!


Solution

  • The smiley movie clip vanishes as toggleSmiley() is called when the mouse is released: (e.type == MouseEvent.MOUSE_DOWN) evaluates false which makes the visible property of the movie clip false, which makes it invisible (keep in mind that invisible clips are still actually on the stage, since you did not remove them...)

    If you want to make the smiley clip stay then vanish when it is done playing, you could attach an Event.ENTER_FRAME event to the movieclip. The 'Event.ENTER_FRAME' event is thrown and handled every time a movieclip's frame ticks. So the handler you could check if the current frame is on the last frame and then have it remove itself.

    Something like:

    // and event handler that runs every frame tick of a movieclip
    // when it detects the current frame is the same as the last frame (indicating it is done playing) remove it from the stage
    function smileyEnterFrame(inputEvent:Event):void {
        var clip:MovieClip = (MovieClip) (inputEvent.target); // inputEvent.target should refer to the smiley clip as it is what threw the event (just need to cast this to a movieclip)
        if(clip.currentFrame == clip.totalFrames){
            // remove this event handler for the clip since the clip is set to be removed (no longer need the event listener)
            clip.removeEventListener(Event.ENTER_FRAME, smileyEnterFrame);
            // remove the clip from the stage
            clip.parent.removeChild(clip);
        }
    }
    

    Then back in your original code:

    stage.addEventListener(MouseEvent.MOUSE_MOVE, mousePosition);
    
    // moved this line in to the mouse movement, as that is where the clip would actually be created
    // (when the mouse moves to a new position)
    //var smiley:MovieClip = addChild(new Smiley) as MovieClip; 
    
    //stage.addEventListener(MouseEvent.MOUSE_DOWN,toggleSmiley); // no longer need this
    //stage.addEventListener(MouseEvent.MOUSE_UP,toggleSmiley); // no longer need this
    
    function mousePosition(event:MouseEvent) {
        var smiley:MovieClip = new Smiley();
        smiley.x = mouseX;
        smiley.y = mouseY;
        this.addChild(smiley);
    
        smiley.addEventListener(Event.ENTER_FRAME, smileyEnterFrame, false, 0, true);
    }
    
    // no longer needed as the smiley clips will remove themselves once they are done playing
    /*function toggleSmiley(e:MouseEvent):void {
        smiley.visible = (e.type == MouseEvent.MOUSE_DOWN); 
    }*/
    

    Edited as mentioned in my comment

    Probably easier to just append all the resulting code together now in to one box. It's messy, but I've kept all your original code in there commented out so you can hopefully see what I am doing.

    The change I made was I removed the mousePosition() event listener (as it was the one that created the smiley clips) so it doesn't get added right away. It only gets added when the MOUSE_DOWN event happens and is removed when the MOUSE_UP event happens.

    import flash.events.MouseEvent;
    
    // and event handler that runs every frame tick of a movieclip
    // when it detects the current frame is the same as the last frame (indicating it is done playing) remove it from the stage
    function smileyEnterFrame(inputEvent:Event):void {
        var clip:MovieClip = (MovieClip) (inputEvent.target); // inputEvent.target should refer to the smiley clip as it is what threw the event (just need to cast this to a movieclip)
        if(clip.currentFrame == clip.totalFrames){
            // remove this event handler for the clip since the clip is set to be removed (no longer need the event listener)
            clip.removeEventListener(Event.ENTER_FRAME, smileyEnterFrame);
            // remove the clip from the stage
            clip.parent.removeChild(clip);
        }
    }
    
    // moved to toggleSmiley() as this event listener that spawns the smiley clips 
    // when the mouse moves, should only be running when the mouse button is down
    //stage.addEventListener(MouseEvent.MOUSE_MOVE, mousePosition);
    
    // moved this line in to the mouse movement, as that is where the clip would actually be created
    // (when the mouse moves to a new position)
    //var smiley:MovieClip = addChild(new Smiley) as MovieClip; 
    
    //stage.addEventListener(MouseEvent.MOUSE_DOWN,toggleSmiley); // no longer need this
    //stage.addEventListener(MouseEvent.MOUSE_UP,toggleSmiley); // no longer need this
    
    function mousePosition(inputEvent:MouseEvent) {
        var smiley:MovieClip = new Smiley();
        smiley.x = inputEvent.stageX;
        smiley.y = inputEvent.stageY;
        smiley.addEventListener(Event.ENTER_FRAME, smileyEnterFrame, false, 0, true);
        this.addChild(smiley);
    }
    
    // no longer needed as the smiley clips will remove themselves once they are done playing
    /*function toggleSmiley(e:MouseEvent):void {
        smiley.visible = (e.type == MouseEvent.MOUSE_DOWN); 
    }*/
    
    // this adds or removes the mousePosition() event listener based on the given mouse event
    function toggleSmiley(inputEvent:MouseEvent):void {
        // if down, then add this event listener (which would create the smiley clips when the mouse moves)
        if(inputEvent.type == MouseEvent.MOUSE_DOWN){
            this.stage.addEventListener(MouseEvent.MOUSE_MOVE, mousePosition, false, 0, true);
        // else on any other mouse event (MOUSE_UP), remove this event listener to stop the smiley clips from being created
        } else {
            this.stage.removeEventListener(MouseEvent.MOUSE_MOVE, mousePosition, false);
        }
    }
    
    this.stage.addEventListener(MouseEvent.MOUSE_UP,toggleSmiley);
    this.stage.addEventListener(MouseEvent.MOUSE_DOWN,toggleSmiley);