开发者

AS3: Tween Lite: tweens stopping before they're finished?

edit2: Well I found out what was wrong. answered my own question. * Face-palm* sorry for this waste of space. (if you come across this randomly, my solution is answered at the bottom)

Edit: While mulling over my code trying to find a solution, I noticed that when my .swf freezes as it is tweening out, an animated movie clip that is on the stage also freezes mid-animation. which brings me to believe that my problems may stem from the loading/creating image portion of my code. as a result, here is my loading function to supplement the code below:

function loadImage():void {

    //if it's not already been loaded)
    if ((currentImageNbr+1) > imagesLoaded || images.length == 0) {

        imagesLoaded++;

        tempPic = xmlData.album[albumNum].image[currentImageNbr].attribute("file");
        tempCaption = xmlData.album[albumNum].image[currentImageNbr].attribute("caption");
        trace("Loading: "+galleryPath+tempPic+" ("+tempCaption+")");

        var loader:Loader = new Loader();
        loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, catchIOError);

        loader.load(new URLRequest(galleryPath+tempPic));
        images[currentImageNbr] = loader;
        paths[currentImageNbr] = tempPic;
        captions[currentImageNbr] = tempCaption;
        //loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS,onImgProgress); (not incorporated yet.)

        loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onImgComplete);
    }
    else {
        trace("image already loaded.");
        onImgComplete(null);
    }
}

Original Post: Hi again StackOverflow!

This might be a little tricky for me to explain my problem so please humour me if I don't make much sense..

I'm trying to make a (simple enough..) XML image gallery. the XML and loading part are (for the most part) fine and dandy. my problems are with using greensock's TweenLite to make my pictures slide in and out of the stage.

the motion i am trying to achieve is kinda like this:

  1. create my image from the right of the stage
  2. swoosh in from the right and stop at the center of the stage
  3. then when i switch to the next picture, I want the current image to swoosh out of the stage to the left
  4. be deleted
  5. create a new slide outside of the stage on the right
  6. and finally, swoosh in from the right
  7. etc

My code works perfectly when I run it using Ctrl + Enter in flash, but when I run my .swf in a browser, the images do not slide correctly a lot of the time.

they often stop, mid-"swoosh" and don't move for a few seconds then they disappear and the next image suddenly appears in the center without any tween occurring.

I have a hunch (based on similar problems I've read) that my problem has something to do with me mistakenly using the same tween for the next one and it getting garbage collected mid-tween..

I'm still very new to using TweenLite so I don't know its ins and outs too well.. Perhaps I'm not creating my tweens correctly?

Here are some relevant snippets of code that I think are probably the problem areas, if you spot me using a bad method or a bug, please let me know, I'm still learning ActionScript 3:

a few prerequisits (that might be important?)

import com.greensock.*;
import com.greensock.easing.*;

stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;

stage.addEventListener(Event.RESIZE, resizeHandler, false, 0, true);

load my image (there's more inside this function but i'm not bothered about this part)

loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onImgComplete);

Once loaded:

function onImgComplete(e:Event):void {
    trace("loading done");

    // check if containerSp exists on stage 
    // if it does, tween it, on complete- delete it and make a new one.
    if (containerSp.stage) {
        trace("containerSp already exists. removing, then making a fresh one");

        // need to check if we're going forwards or backwards.
        if (leftRight == "right") {
            //forwards
            trace("tweening out..");
            moving = true;

            TweenLite.to(container开发者_高级运维Sp, .5, {x:0-(containerSp.width+20), y:containerSp.y, ease:Quint.easeIn, onComplete:removeSprite}); 
        }
        else if (leftRight == "left") {
            //backwards
            trace("tweening out..");
            moving = true;

            TweenLite.to(containerSp, .5, {x:stage.stageWidth+20, y:containerSp.y, ease:Quint.easeIn, onComplete:removeSprite});
        }
    }
    else {
        trace("containerSp doesn't exist. making a fresh one.");
        makeSprite();
    }
}

When the tween out is done, remove the image and make a fresh sprite:

function removeSprite():void {
    moving = false;
    stage.removeChild(containerSp);
    makeSprite();
}

Make my image inside of containerSp (which hasn't been added to the stage yet):

function makeSprite():void {
    containerSp = new Sprite();
    containerSp.graphics.beginFill(0xFF0000);
    containerSp.graphics.drawRect( 0, 0, 0, 0);
    trace("Done.");

    trace("making image");
    var bm:Bitmap = new Bitmap();
    bm = Bitmap(images[currentImageNbr].content);
    bm.smoothing = true;

    containerSp.addChild(bm);

    trace("done");
    tweenIn();
}

set our containerSp's position, add it to the stage and tween it in:

function tweenIn():void {
    moving = true;
    resizeHandler();

    // need to check if we're going forwards or backwards.
    if (leftRight == "right") {
        //forwards
        containerSp.y = (stage.stageHeight/2)-(containerSp.height/2)-(barHeight/2);
        containerSp.x = stage.stageWidth;
    }
    else if (leftRight == "left") {
        //backwards
        containerSp.y = (stage.stageHeight/2)-(containerSp.height/2)-(barHeight/2);
        containerSp.x = (0 - stage.stageWidth);
    }

    stage.addChild(containerSp);

    trace("tweening in..");

    TweenLite.to(containerSp, .5, {x:(stage.stageWidth/2)-(containerSp.width/2), y:(stage.stageHeight/2)-(containerSp.height/2)-(barHeight/2), ease:Quint.easeOut, onComplete:done}); 
}

function done():void {
    trace("all done");
    moving = false;
    resizeHandler();
}

The use of resizeHandler is to re-size my picture when the window is re-sized. it basically sets containerSp.width, .height, .x and .y relative to size of frame.

the moving variable is for resizeHandler so it doesn't set the X and Y to the center of stage unless the picture isn't moving.

so to summarize my question, why do the tweens stop working before they're finished only when I load my .swf in the browser?

if I've forgotten to mention anything, please let me know and i'll be happy to fill in the blanks.

thank you in advance for your time and patience.


Have you tried the killTweensOf() method ?


So it wasn't TweenLite's fault at all. turns out the size of images I was loading were not web friendly; which flash couldn't handle (on my lappy at least..) so even after I'd loaded my images into cache and everything, the moment I added that behemoth of a MovieClip to the stage the .swf would hang while trying to keep working. So the tweens were actually triggering correctly. I found all this out by making a smaller prototype with 40x40 .gif's and applying it to my project.

As a solution (besides shrinking and optimizing my images), when loading a new image, instead of adding it to the stage AFTER the previous image was deleted (even though it's already loaded) I've made it add the movie clip to the stage as part of the loading process so that no tweens look ugly when a movie clip is added.

Regardless, thank you to anyone who looked over my code and/or thread. a few more suggestions would have been nice but I realise that this post was rather big and tedious.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜