Продолжаем тему Flash разработки. Сегодня на очереди три маленькие хитрости, которыми я поделюсь. Если кто не знает, то мы решили стартовать серию сообщений вопрос-ответ по флеш... у нас полная демократия - кто угодно может спросить что-то интересующее его из мира флеш, а я постараюсь ответить :)
Сегодня в номере:
|
BlendMode - будьте аккуратны с этим зверем
Начну с того, что расскажу, что графические объекты могут по-разному накладываться и смешиваться на экране. Режимов много: Add, Alpha, Darken, Difference, Erase, Hardlight, Invert, Layer, Lighten, Multiply, Normal, Overlay, Screen, Shader, Subtract. И каждый служит для своих целей.
Особенно этими штуками часто пользуются художники, добиваясь потрясающих цветов и переходов.
Но я из этих всех способов наложения объектов при программировании использую лишь Normal и Layer. Выставляется это дело просто:
MyDisplayObject.blendMode = BlendMode.LAYER;
Название "нормальный" говорит само за себя, и я в основном этим режимом и пользуюсь, однако есть у него один недостаток. Накладываем несколько объектов, а затем изменяем прозрачность у их родителя... ба-бах, и вылезают артефакты, которые совсем не хотелось бы, чтобы они вылезали. Выглядит это так:
Видите? На средней картинке объекты стали прозрачными "по отдельности" и выглядит это надо сказать ужасно. Перехлест тайлов травы стал очень темным, а через голову девочки можно увидеть травинки, да и вообще цвет лица теперь с зеленцой! А вот режим Layer (справа) лишен вышеописанного недостатка, все выглядит как надо, зато у него есть другой недостаток :)
Итак, плавное появление диалогов и элементов уровня я делал через Layer, а затем обнаружил катастрофическое падение производительности при таком режиме. Я показывал целый уровень, со всякими объектами, анимациями, кнопками и прочим. И обнаружил слайдшоу, всего 5-7 фпс. На самом деле я довольно долго ломал голову, что же я такое натворил, а потом отключил Layer и обнаружил, что этот зверь оказался прожорливее, чем я мог себе представить. В итоге - оставил везде режим Normal, и просто увеличил скорость перехода от одного экрана к другому, чтобы игрок не успел заметить артефакты прозрачного наложения.
Как я храню несколько анимаций в одном мувике
Совсем недавно в своих играх мы начали применять покадровую анимацию. Зверушка моргает глазами, прыгает, кушает и так далее - все это рисуется по кадрам, и при воспроизведении зверек оживает.
Так вот при создании анимации всяких игровых элементов возникает вопрос о том, как всем этим барахлом манипулировать. Сейчас я расскажу о способе, которым пользуюсь на данный момент, затрону плюсы и минусы.
Итак, анимация одного персонажа полностью лежит в одном мувике. Первые десять кадров - прыжок, следующие пятнадцать кадров бег, затем карабкается, еще двадцать кадров стреляет и так далее. Ставим текстовые метки на кадрах и вуаля - теперь мы можем легко найти первый кадр нужной анимации! В итоге остается один вопрос - как осуществлять навигацию по кадрам? Да все просто:
var fSuperMan = new mcSuperMan; fSuperMan.gotoAndPlay('fly');
На последнем кадре каждой анимации ставлю stop(), что обеспечит остановку проигрывания анимации. Также номер кадра можно и вручную отслеживать по значению fSuperMan.currentFrame.
Итог:
- можно хранить все анимации героя в одном клипе
- насколько я понял, так намного проще анимировать художникам
- все-таки текстовые метки довольно удобны, можно, к примеру, рандомно выбирать анимацию из текстового списка
всякие полезные параметры stage'а
Как-то раз один из спонсоров попросил, чтобы игра нормально скейлилась, сохраняя пропорции и вообще свой игровой вид. Оказалось, есть параметр scalable, который как раз отвечает за это все безобразие. Примеры:
stage.scaleMode = StageScaleMode.EXACT_FIT; // искажает пропорции, но масштабируется до окна stage.scaleMode = StageScaleMode.NO_SCALE; // ничего не скейлится :)
Наверняка многие видели надоедливый желтый прямоугольник, который появляется при нажатии клавиши tab? Он раздражает не только игроков, но и многих спонсоров... Отключается легко:
stage.stageFocusRect = false;
При добавлении в игру всяких окошек, менюшек и тому подобных интерактивных кнопок, клавиатурные клавиши перестают работать, сталкивались? На самом деле просто фокус ввода уходит с элемента, для которого был привязан слушатель KeyboardEvent'а. Чтобы вернуть все как было, достаточно выполнить:
stage.focus = MyInteractiveObject;
сразу после пропадания вышеназванных менюшек, ставших причиной бага.
При переносе проектов с FlashDevelop на FlashBuilder и обратно, у меня иногда возникают проблемы во всяких там настройках, таких как разрешение флешки и фреймрейте. Чтобы постоянно не лазить в настройки проекта, для установки фреймрейта я пользуюсь такой строчкой, дописав ее, допустим, в самое начало прелоадера:
stage.frameRate = 35;
В общем-то и все, что мне приходит на ум сейчас, наверно :)
На этом сегодняшний выпуск завершен, ждите продолжения в ближайшее время! Не скучайте, товарищи и приятного вам дня!
Использую для установки фреймрейта тег SWF=) Получается что-то вроде такого(так же можно задавать ширину, высоту и цвет фона):
ОтветитьУдалитьpackage
{
import flash.display.Sprite;
[SWF(width="800", height="600", backgroundColor="#FFFFFF", frameRate="60", wmode="direct")]
public class Preloader extends Sprite
{
public function Preloader()
{
//bla bla bla
}
}
}
о! клево! буду знать! я такую штуку только для размеров использовал...
Удалитьеще такая штука, что у спонсоров постоянно разные фпс на мувиках сплешей, и приходится программно выставлять фреймрейт до/после проигрывания их мувика.
Привет.
ОтветитьУдалитьНе мог бы ты в след. выпуске показать свой звуковой менеджер?
Как звук и музыка останавливаются при паузе?
ок! сделаю!
Удалитьспасибо за наводку!
Насчёт кадровых меток:
ОтветитьУдалитьЯ тоже поначалу разделял так анимацию, но это было лишь пока я юзал графику в векторе.
Когда я начал её кэшировать (растеризовать), то метки отпали(даже пришлось тратить время на переделку уже готовой графики заточенной под метки, ну и код тоже соответственно), поэтому пришёл к единственному удобному решению - хранение анимаций в разных MC.
Ну а для художников с этим никаких проблем - сначала они рисуют всё как удобно(например в 1 MC), а потом разносят кадры как надо(по разным MC).
многие при растеризации сохраняют метки... чтобы унифицировать переходы.
Удалитьа я до сих пор не умею растеризовать анимацию... в новой игре хочу попробовать!
Спасибо за блог и еще один источник вдохновенния и полезных советов.
ОтветитьУдалитьПомоги пожалуйста в следующем выпуске начинающему флешеру с вопросом создания задержки между выстрелами и правильным созданием/удалением массивов пуль или с класами в разрезе этого вопроса. Делаю простую аркадку, там лягушка стреляет огненними шарами, пиробластами и заморозкой. Игрок должен переключать "режимы патронов" выбирая нужный ему в даной ситуации. Возникла проблема с реализацией этой стрельбы. П.С. Спасибо за блог и держу кулаки за твои следующие игры.
спасибо!
Удалитьпо поводу пуль - не знаю, когда выйдет следующий выпуск FAQ, поэтому дополнительно распишу сейчас, я бы делал так:
1. базовый класс TBaseGun, от него наследуем TFireBallGun, TBlastGun, TFrozenGun и всякое такое... главное - у них должен перекрываться метод Shoot(), при этом создаваться объекты типов TFireBallBullet, TBlastBullet, TFrozenBullet соответственно...
2. собственно, дополнительно реализуем сами классы пуль (Bullet-ы из предыдущего пункта). Каждый из них при столкновении делает что-то свое. Кто-то наносит урон, кто-то замораживает, кто-то поджигает и так далее.
3. если пуль очень много на экране (более 20 одновременно), то можно реализовать пул объектов (слова для поиска: аккумулятор объектов, пул объектов, заранее созданный вектор). это для того, чтобы не было тормозов.
тема интересная - спасибо за наводку! постараюсь осветить ее в следующем выпуске!
p.s. простите за префикс "T" в названиях классов, у меня жгучая привычка так делать :)
Работаю в флеш кс 5 (со временем планирую освоить флеш девелоп). Столкнулся с проблемкой, --> если даже простому шейпу-мувиклипу программно или класическим твином задать движение на сцене, то наблюдаются маленькие но вначале заметные глазу рывочки в движении. Как можно это устранить? На 35 фпс это меньше заметно, но все равно..
ОтветитьУдалитьпривет!
Удалитьсделай пробный fla и пришли мне на почту lampogolovii@mail.ru, я гляну... причин может быть много (от первого рендера, до установленного cacheAsBitmap)