Как заменить изображение в более крупной анимации, используя AS3? - PullRequest
0 голосов
/ 04 марта 2011

Мы делаем Flash браузерную игру с несколькими довольно сложными анимациями. Наш дизайнер делает анимацию во Flash Professional, пока я все готовлю и добавляю логику через AS3 (используя FlashDevelop).

В одной из наших более сложных анимаций «бонусный предмет» перемещается по экрану. Он перемещается туда-сюда, есть специальные эффекты и, как таковой, он исчезает на несколько кадров, а затем появляется снова.

Из AS3 мы хотим иметь возможность динамически решать, какой бонусный элемент (например, гриб или звезда) включить в анимацию. Мы не хотим просить нашего дизайнера повторить всю анимацию для каждого из наших бонусных предметов.

Вот что мы попробовали:

Создание двухкадрового (1 грибовидный, 1 звездный) видеоклипа «BonusItem» во FlashPro и экспортировано для ActionScript. Создал сложный анимационный мувиклип в FlashPro и добавил мувиклип BonusItem в соответствующие кадры. Дали экземпляру BonusItem имя экземпляра во всех необходимых ключевых кадрах. Экспортирован весь видеоклип для ActionScript (экспортируется как «ComplexAnimation»).

Намерение:

Намерение состояло в том, чтобы сделать это:

var complexAnimation:ComplexAnimation = new ComplexAnimation();
complexAnimation.bonusItem.gotoAndStop("star"); // Frame labels have been added in FlashPRo.
this.addChild(complexAnimation);

Это будет воспроизводить сложную анимацию со звездой, и мы можем легко вызвать gotoAndStop («гриб»), чтобы воспроизвести ту же анимацию с грибом.

Проблемы:

Первая проблема заключалась в том, что complexAnimation.bonusItem был нулевым в строке 02 выше. Я решил это, обработав ADDED_TO_STAGE для complexAnimation и поместив строку 02 выше в обработчик.

Следующая проблема заключалась в том, что каждый раз, когда мувиклип bonusItem начинал анимацию движения, или если он не присутствовал в некоторых кадрах и впоследствии повторно добавлялся, атрибут / ссылка complexAnimation.bonusItem переназначался новому экземпляру bonusItem. Затем мне нужно было найти способ узнать, когда это произошло, и вызвать gotoAndStop («звезда») для нового экземпляра.

Я нашел два способа сделать это:

1) Прослушивать ДОБАВЛЕННЫЕ события в complexAnimation с target.name из «bonusItem». Немного дерьмо в строго типизированном языке - прибегать к сопоставлению строк, но это работает. Кстати, при возникновении события ADDED новые ссылки на объекты фрейма по-прежнему равны нулю.

2) Прослушивать события FRAME_CREATED. Это происходит позже, чем ДОБАВЛЕНО в момент инициализации новых ссылок на фреймы. Таким образом, я могу проверить, не является ли complexAnimation.bonusItem ненулевым, затем вызвать для него gotoAndStop ("star"). Одна проблема с этим заключается в том, что вызов gotoAndStop фактически запускает другое событие FRAME_CREATED для запуска, поэтому мне нужно защититься от бесконечного зацикливания. Опять же, это работает, но я не испытываю к этому особого чувства.

Вывод:

Ну, на самом деле у меня нет другого заключения, кроме того, что я очень усердно работаю, чтобы сделать что-то относительно простое. Я надеюсь, что есть более простой и надежный подход. У меня сильное чувство, что я схожу с ума. Кто-нибудь знает лучший способ сделать это?

Ответы [ 2 ]

0 голосов
/ 09 марта 2011

Я думал, что обновлю этот пост нашим текущим (и, надеюсь, долгосрочным) решением.

Прежде всего, я допустил ошибку в сообщении выше:

Следующая проблема заключалась в том, что каждый раз, когда мувиклип bonusItem начинал анимацию движения, атрибут / ссылка complexAnimation.bonusItem переназначался новому экземпляру bonusItem.

Это было неверно.Flash действительно назначал новый экземпляр BonusItem, но он был вызван ключевым кадром слоя Mask, а не анимацией движения.

Я стремился избежать какой-либо логики, основанной на сравнении строк, но вВ конце концов я проглотил свою гордость, чтобы облегчить жизнь.

Наш дизайнер предоставляет имена всех соответствующих объектов (вещи, которые нам понадобятся для доступа из AS3) на каждом ключевом кадре на временной шкале.Если объект вложен в другие объекты, наш конструктор также должен назначить имена экземпляров этих родительских объектов.Мы должны согласовать эти имена экземпляров, чтобы dev знал, как называются методы доступа - нам бы все равно пришлось это делать.Наш конструктор также все еще должен «Export For Actionscript» класс для каждого соответствующего фрагмента ролика (например, BonusItem).

В AS3 мы используем Robotlegs для внедрения зависимости и в качестве основы нашегоMVC Framework.Роботлегс предлагает отделить логику для конкретного приложения от логики для конкретного представления.Это позволяет нам указать логический класс (называемый посредником), который будет связан с каждым из наших представлений.Таким образом, мы можем сделать следующее отображение:

BonusItem -> BonusItemMediator

Это означает, что каждый раз, когда Flash создает BonusItem на временной шкале, Robotlegs каким-то образом узнает об этом и создает новый экземпляр BonusItemMediator (который мы пишем сами и имеем полноеконтроль над).Кроме того, Robotlegs может легко дать нам ссылку из нашего BonusItemMediator на связанный экземпляр представления (экземпляр BonusItem).Так что внутри моего BonusItemMediator я могу спросить ссылку на представление, каково его имя экземпляра.Я также подхожу к его родителям на сцену и записываю каждое из их имен, чтобы сгенерировать результирующую строку имен экземпляров, которые однозначно определяют этот экземпляр BonusItem.например,

"game.complexAnimation.bonusItem"

Как только я это узнаю, я могу убедиться, что bonusItem показывает правильное изображение (звезда или гриб) со следующим кодом:

var frameLabelName:String myGameModel.whatTheHellShouldThisBeShowing("game.complexAnimation.bonusItem");
this.view.gotoAndStop(frameLabelName); // where view is the BonusItem instance

Так что теперь независимо от того, как иликогда Flash, по-видимому, случайным образом решает уничтожить и воссоздать мой bonusItem, я услышу об этом и смогу убедиться, что новый экземпляр BonusItem отображается в правильном кадре.

Основным недостатком этого решения является то, что мы полагаемсяна сравнения строк.Наш дизайнер мог легко набрать имя экземпляра, и мы не услышали бы об этом, пока этот код не был запущен во время выполнения.Конечно, тесты снижают этот риск, но я все еще чувствую, что мне жаль, что я использую строго типизированный язык, но потом не использую проверку типов во время компиляции.

0 голосов
/ 05 марта 2011

Если у вас есть объект, который существует на временной шкале, и у него есть имя экземпляра, и вы должны иметь возможность сохранять ссылку на него на протяжении всей временной шкалы, то он должен существовать накаждый кадр (и в том же слое!) мувиклипа.Я допускаю, что ваши обходные пути сделали работу, но вы уже испытали боль, связанную с этим.

Путь наименьшего сопротивления заключается в том, чтобы объект всегда существовал.Если пользователь не должен его «видеть», просто спрячьте его где-нибудь за кадром.Просто убедитесь, что он всегда существует, непрерывно, на этом временном слое от кадра 1 до финального кадра.

Другая вещь, которую я бы предложил, это прекратить глубокое вложение фрагментов ролика в надежде использовать эти вложенныеклипы как государственные представления.Это одна из вещей, которую, к сожалению, было очень легко сделать в дни AS2, но она оказалась непрактичной до безумия в AS3.Все, что глубже 1 слоя, попадает на опасную территорию.3 слоя глубины, и вам нужно пересмотреть свою стратегию.Возможно создание экземпляров различных экземпляров мувиклипа из библиотеки и динамическое добавление / удаление вместо использования фреймов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...