views:

445

answers:

2

i'm attempting (so far unsuccessfully) to programatically increase and decrease the scale of an object on stage. there is a Grow button (grow_btn) and a Shrink button (shrink_btn), which increase and decrease the scaleX and scaleY properties of a selected object (either redObject, greenObject or blueObject) over time.

the problem i'm encountering seems random, where sometimes only one of the properties (either scaleX or scaleY) will change while the other does not. additionally, the target and original sizes for the tween functions don't adjust correctly. For example: 1.0 is nearly twice as large as the object onstage.

//Imports
import fl.transitions.Tween;
import fl.transitions.easing.*;

//Constants And Variables
const starRotationAngle:Number = 0.5;
const starSpeed:Number = 2;

var moveForward:Boolean = true;
var selectedObject:MovieClip;

//Event Listeners & Functions
star_mc.addEventListener(MouseEvent.CLICK, rotateStar);
function rotateStar(e:MouseEvent):void
    {
    star_mc.rotation += 5;
    }

addEventListener(Event.ENTER_FRAME, starMove);
function starMove(e:Event):void
    {
    if (star_mc.x >= stage.stageWidth + star_mc.width)
        {moveForward = false;}
    else if (star_mc.x <= stage.x - star_mc.width)
        {moveForward = true;}

    if (moveForward == true)
        {
        star_mc.x += starSpeed;
        star_mc.rotation += starRotationAngle;
        }       
        else
        {
        star_mc.x -= starSpeed;
        star_mc.rotation -= starRotationAngle;
        }   
    }

redObject.addEventListener(MouseEvent.CLICK, changeSelectedObjectVariable);
greenObject.addEventListener(MouseEvent.CLICK, changeSelectedObjectVariable);
blueObject.addEventListener(MouseEvent.CLICK, changeSelectedObjectVariable);
function changeSelectedObjectVariable(e:MouseEvent):void
    {
    selectedObject = e.currentTarget as MovieClip;
    }

grow_btn.addEventListener(MouseEvent.CLICK, grow);
function grow(e:MouseEvent):void
    {
    var tweenGrowX:Tween = new Tween(selectedObject, "scaleX", None.easeIn, 1.0, 2.0, 3.0, true);
    var tweenGrowY:Tween = new Tween(selectedObject, "scaleY", None.easeIn, 1.0, 2.0, 3.0, true);
    }

shrink_btn.addEventListener(MouseEvent.CLICK, shrink);
function shrink(e:MouseEvent):void
    {
    var tweenShrinkX:Tween = new Tween(selectedObject, "scaleX", None.easeIn, 2.0, 1.0, 3.0, true);
    var tweenShrinkY:Tween = new Tween(selectedObject, "scaleY", None.easeIn, 2.0, 1.0, 3.0, true);
    }
+1  A: 

Hi Chunk1978,

your code is correct. Works as it should. Check in the ide the scale of your movieclips in the transform panel, they should be set to 100 100.

dome
ok, the scales were not 100x100. however, i'm still seeing strange behaviour, but i believe the scaling somehow is being interrupted by an animation in the background. when i remove the constant animation, all scaling is correct.without removing the constant background animation, scaling of an object will be wrong at first. the first few times the scaling function is executed, the selected object will start to scale correctly, but suddenly the width will stop while the height continues to increase. i've updated my original post to show my entire script. hopefully there's an explanation.
TheDarkInI1978
+2  A: 

Move the tween objects outside of the listener functions, and don't use different tween objects for both grow() and shrink(). I think your problem is that you are not destroying a previous tween before applying a new tween so they are stepping on each other.

var tweenScaleX:Tween;
var tweenScaleY:Tween;

Your grow() and shrink() methods should both use these two tween variables instead of creating tween variables within the method (which makes them available for garbage collection when the function has completed even if the tween has not completed). When you call grow(), tweenScaleX and tweenScaleY are both assigned new tween objects. If the shrink button is clicked before grow() is finished, the shrink() method will begin and the tweens assigned during grow() will essentially be "destroyed" to make way for the new shrink tweens.

Furthermore, your problem might be related to AS3's garbage collection. The first answer provided said that the code works fine, but garbage collection is different from computer to computer due to performance and memory availability. A memory intensive Flash app will perform garbage collection more frequently, but on a box with lots of memory and performance it may not happen at all. As I mentioned above, since you are creating the tween variables inside the grow() and shrink() functions, their scope is only within that function. When the function completes, the variables created inside the function become eligible for garbage collection. Your tween objects will be destroyed if garbage collection occurs even if those tweens have not finished their tweens (and the "complete" event will never fire). By moving the tween variables outside of the functions in your example (or making them class members in a class), you are moving the scope to the parent object so the tween will exist as long as that parent exists. The changes to garbage collection are one of the most important but probably least understood changes from AS2 to AS3. As a developer, you might have a lot of RAM so garbage collection is not frequent (or non-existent as long as there's enough memory to hold everything), but in production your users might experience strange behavior as items are garbage collected to free up RAM but those items are referenced elsewhere since you thought they still existed and the code works fine for you. This is one complaint you see from AS3 developers a lot where they blame Adobe for making changes that cause Flash to no longer be platform independent, but it's an important feature that needed to be added to make Flash more robust.

wmid
thanks. that was it. :)
TheDarkInI1978
wpjmurray thanks you for the good explanation. I'm aware of garbage collection, but completely miss the problem that the scope of the 2 tween variables can cause.
dome