Actionscript 3.0 Tween Error

Я пытаюсь (пока безуспешно) программно увеличивать и уменьшать масштаб объекта на сцене. есть кнопка Grow (grow_btn) и кнопка Shrink (shrink_btn), которые со временем увеличивают и уменьшают свойства scaleX и scaleY выбранного объекта (redObject, greenObject или blueObject).

проблема, с которой я сталкиваюсь, кажется случайной, когда иногда меняется только одно из свойств (scaleX или scaleY), а другое - нет. Кроме того, целевой и исходный размеры для функций анимации не корректируются должным образом. Например: 1.0 почти в два раза больше объекта на сцене.

//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);
    }

3 ответа

Решение

Переместите объекты анимации за пределы функций слушателя и не используйте разные объекты анимации как для grow(), так и для shrink(). Я думаю, что ваша проблема в том, что вы не уничтожаете предыдущую анимацию перед тем, как применить новую анимацию, чтобы они наступали друг на друга.

var tweenScaleX:Tween;
var tweenScaleY:Tween;

Ваши методы grow() и shrink () должны использовать эти две переменные анимации вместо создания в методе переменных анимации (что делает их доступными для сборки мусора, когда функция завершена, даже если анимация не завершена). При вызове grow() tweenScaleX и tweenScaleY назначаются новые объекты анимации. Если щелкнуть кнопку сжатия до завершения grow(), начнется метод shrink (), и анимации, назначенные во время grow(), будут по существу "уничтожены", чтобы освободить место для новых сокращенных анимаций.

Кроме того, ваша проблема может быть связана с сборкой мусора в AS3. В первом ответе говорилось, что код работает нормально, но сборка мусора отличается от компьютера к компьютеру из-за производительности и доступности памяти. Приложение Flash, интенсивно использующее память, будет выполнять сборку мусора чаще, но на коробке с большим объемом памяти и производительностью это может вообще не произойти. Как я упоминал выше, поскольку вы создаете переменные анимации внутри функций grow() и shrink (), их область действия находится только внутри этой функции. Когда функция завершается, переменные, созданные внутри функции, становятся пригодными для сборки мусора. Ваши объекты анимации будут уничтожены, если сборка мусора произойдет, даже если эти анимации еще не завершены (и событие "завершить" никогда не сработает). Перемещая переменные анимации за пределы функций в вашем примере (или превращая их в члены класса в классе), вы перемещаете область видимости в родительский объект, чтобы анимация существовала до тех пор, пока существует этот родительский объект. Изменения в сборке мусора являются одним из наиболее важных, но, вероятно, наименее понятных изменений от AS2 к AS3. Как разработчик, у вас может быть много оперативной памяти, поэтому сборка мусора происходит не часто (или вообще отсутствует, если достаточно памяти, чтобы вместить все), но в процессе работы ваши пользователи могут столкнуться со странным поведением, так как элементы собирают мусор для освобождения ОЗУ, но эти элементы упоминаются в другом месте, так как вы думали, что они все еще существуют, и код прекрасно работает для вас. Это одна жалоба, которую вы часто видите от разработчиков AS3, когда они обвиняют Adobe в том, что она внесла изменения, из-за которых Flash перестает быть независимым от платформы, но это важная функция, которую необходимо добавить, чтобы сделать Flash более надежным.

Ваш код правильный. Работает как надо. Проверьте масштаб ваших видеоклипов на панели преобразования, они должны быть установлены на 100 100.

Не объявляйте объекты анимации внутри функций, они очищаются CG до окончания анимации. Объявите их глобально.

НЕПРАВИЛЬНО:

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);
}

ПРАВИЛЬНЫЙ:

var tweenGrowX:Tween;
var tweenGrowY:Tween;
function grow(e:MouseEvent):void
{
    tweenGrowX = new Tween(selectedObject, "scaleX", None.easeIn, 1.0, 2.0, 3.0, true);
    tweenGrowY = new Tween(selectedObject, "scaleY", None.easeIn, 1.0, 2.0, 3.0, true);
}
Другие вопросы по тегам