Показаны сообщения с ярлыком трюки. Показать все сообщения
Показаны сообщения с ярлыком трюки. Показать все сообщения

понедельник, 26 марта 2012 г.

Фильтрация XML (E4X) при помощи регулярных выражений и сложных условий

Заметка в качестве продолжения темы о получении данных из XML.
Для фильтрации XML можно так же использовать регулярные выражения (RegExp) и собственные условия через функции фильтрации (помимо простых сравнений).
Не уверен, что данный синтаксис скушает любая среда разработки (по крайней мере FDT выдает ошибку, хотя синтаксис правильный).
Простой пример. У нас имеется список персонала одного из отделов компании, и нам необходимо узнать, кто из них родился в апреле.

Пример с использованием регулярного выражения: [...]
Читать дальше: Фильтрация XML (E4X) при помощи регулярных выражений и сложных условий

суббота, 24 марта 2012 г.

Как рассказать про вашу игру

Автор оригинальной статьи — Тим Фрэнсис, журналист английского издания PC Gamer, в свободное время занимающийся разработкой indie-игр

В повседневной жизни я — игрожур, но на досуге я сам пишу одну игру (Gunpoint), она даже вышла в финал Independent Games Festival, я немного горжусь этим (до меня выступал создатель Solipskier, объяснявший, почему всем наплевать на IGF, так что мне стало немного легче). Это моя первая игра, к тому же ещё недописанная, поэтому учить вас программированию мне не по статусу. Вместо этого я хочу поговорить о том, как рассказывать о играх. С этим легко накосячить, особенно когда вы находитесь в контексте игры; но описанию нужно уделять большое внимание, если вы не хотите остаться единственным пользователем. Мне повезло — за восемь лет я натренировался рассказывать о чужих играх, так что со своей всё пошло легче.

Даже не ожидайте, что аудитория вашего сайта, интервью или ролика будет состоять исключительно из умных, серьёзных и заинтересованных людей. Потому что в худшем случае это могу прочесть я — а я тот ещё засранец.

Сейчас я расскажу, почему на тупиц типичные методы не действуют, а потом объясню (как весьма опытный засранец), как нужно рассказать про игру, чтобы это понял каждый.
Читать дальше: Как рассказать про вашу игру засранцу

пятница, 23 марта 2012 г.

TheMiner и FlashDevelop

В этом руководстве речь пойдёт о TheMiner‘е (отличный Flash профайлер) и о FlashDevelop‘е (лучшая и бесплатная среда разработки для Action Script / haXe), соответственно подразумевается, что вы с ними знакомы и желаете использовать их совместно. Если не знакомы — рекомендую ознакомиться.
Всего есть два пути использования TheMiner во FlashDevelop:
- Используя TheMiner SWC, как любую другую внешнюю библиотеку.
- Добавляя TheMiner SWF в список профайлеров FlashDevelop.
Почему существует два пути? Потому что у каждого есть сови преимущества и недостатки, и, в зависимости от обстановки, тот или иной путь может оказаться наиболее подходящим.
Итак, давайте попробуем оба пути шаг-за-шагом. Пожалуйста запустите FlashDevelop и откройте \ создайте в нём as3 проект чтобы продолжить.

TheMiner в качестве внешней SWC

1. Для начала, купите TheMiner или скачайте бесплатную версию для некоммерческого использования.
2. Распакуйте скачанный архив, зайдите в папку «SWCs» и выберите подходящую версию (в зависимости от требуемого языка), например TheMiner_en.swc [...]
Читать дальше: TheMiner и FlashDevelop

пятница, 9 марта 2012 г.

Упакованный SWF. Как распаковать?

Привет, друзья!
В этом посте я хотел бы рассказать о том, что из себя представляет упакованный SWF и как его можно распаковать динамически и статически.
Итак, что же такое упакованный SWF?
Если Вы никогда ранее его не видели, не поленитесь скачать простой классический пример упакованного SWF:
http://codestage.ru/files/flood/security/packed.swf
Запустив SWF, вы увидите немного текста в левом верхнем углу. Однако, если вы попробуете декомпилировать этот файл, то вы не увидите кода, который этот текст показывает.
Стоит отметить, что если бы в упакованном SWF были ещё какие-нибудь ресурсы (изображения, звуки, шрифты и т.д.), то их вы бы тоже не увидели. Это из-за того, что оригинальный SWF находится внутри того SWF что вы скачали и декомпилировали, и часто в зашифрованном виде.
Обычно все, что вы можете получить из таких SWF с помощью декомпиляторов — это код распаковщика\расшифратора и, возможно, сам зашифрованный SWF в виде набора байт (зависит от того, умеет ли используемый вами декомпилятор отображать тэг DefineBinaryData).
Такая «упаковка» на самом деле достигается с помощью простого Flex тэга [Embed].

Динамическая распаковка (dumping)

Динамическая — значит для распаковки потребуется исполнение SWF во Flash Player’е (далее — FP).
Т.к. FP не умеет проигрывать зашифрованную неведомо как SWF, то логично что перед проигрыванием, SWF должна расшифровываться и загружаться уже в чистом виде (например, с помощью Loader.loadBytes()).
Что более важно, распакованный и расшифрованный SWF будет в памяти все время, пока он исполняется FP’ром.
И это наш шанс достать его!
Существует два основных способа сделать это.
1) Динамическая распаковка с помощью утилит
Используя сторонние или даже самописные утилиты для поиска SWF в памяти процесса FP. Это самый быстрый, самый простой и обычно самый эффективный способ. Но он не вызывает ощущения что вы — тру крякер ;)
Существуют различные платные и бесплатные утилиты для этих целей.
Одна из наиболее продвинутых — это SWF Revealer, бесплатная утилита для владельцев лицензий на ASV. В некоторых случаях, она может обходить проверки на домен (которые не дают распаковаться и расшифроваться SWFке) и заставлять SWF запускаться в вашей среде.
Также достаточно легко гуглятся разные бесплатные дамперы.
2) Ручная динамическая распаковка
Поиск SWFки вручную, с помощью нахождения CWS (сжатый SWF) или FWS (несжатый SWF) заголовков, которые являются началом любого SWF. Если вы никогда не пробовали такой способ, я очень рекомендую попробовать! Он не только позволит немного подтянуть ваши скиллы в hex, но и подарит вам ощущение, что вы тру-крякер!)
Для поиска заголовков можно использовать любой HEX редактор, который умеет читать память процессов и имеет функцию поиска.
Если вы хотите искать упакованный SWF в памяти FP в котором проигрывается файл-пример по ссылке выше, то стоит начать с поиска FWS подписи (несжатый SWF) — просто ищите строку ‘FWS’, т.к. перед исполнением FP разжимает SWF, если он был сжат.
Если вы будете запускать и искать SWF в браузере, то закройте все лишние вкладки, чтобы снизить количество лишних SWF в памяти.
Обычно при таком поиске вы найдете несколько заголовков в памяти, т.к. сам FP держит там разные служебные SWF, например ту, что показывается после входа в полноэкранный режим.
Так что если вы сомневаетесь, то лучше проверить все найденные заголовки.
Итак, что же делать с найденным заголовками, спросите вы? Как их проверить, как узнать, где заканчивается SWF?
Пожалуйста, взгляните на этот скриншот:

Это заголовок одной из SWF в памяти FP при проигрывании файла-примера, найденный поиском по строке ‘FWS’ (совершенно случайно это оказался заголовок искомого упакованного файла, который мы и хотим найти ;) )
Что же дальше? А дальше необходимо посмотреть какой длины получается найденный SWF. Длина расположена в 4 байтах начиная с 4го: [...]

Читать дальше: Упакованный SWF. Как распаковать?

воскресенье, 15 января 2012 г.

Nape и Starling вместе? Это возможно!

Привет, друзья!

Некоторые из вас уже наверняка пробовали использовать быстрейший flash 2D физический движок Nape вместе с GPU 2D фреймворком Starling и заметили, что свойство Body.graphic является flash.display.DisplayObject и не может быть приравнено к экзмепляру starling.display.DisplayObject.

В итоге, некоторые просто использовали более медлительный Box2D, некоторые самостоятельно контролировали отрисовку физических тел в виде DisplayObject’ов движка Starling, вожможно, некоторые даже сделали то же самое, что сделал я, но никому не показали. Мне нравится свойство Body.graphic — оно очень удобное и мне хотелось бы помочь всем as3 разработчикам использовать его в полную силу и для DisplayObject’ов Starling’а.

Представляю вашему вниманию модифицированные swc движка Nape (release и debug) Milestone 7.2 «r3″ для FP 10+, (возможно, не полностью) совместимые со Starling.

Всё, что я там изменил — заменил класс Body.graphic flash.display.DisplayObject на Dynamic (* в as3) и удалил конвертацию в градусы свойства Body.graphic.rotation. В моём случае, этого было достаточно.
Теперь я могу использовать Nape как обычно, с обычными DisplayObject’ами, что очень здорово!
Да, там наверняка есть ещё какие-нибудь несовместимые вещи со Starling, но в моём случае Nape работает без ошибок и проблем не возникает.

Качайте и используйте эти swc со Starling в своё удовольствие!
debug swc
release swc

Мне понравилось приключения с компиляцией caxe и flib под Windows в MinGW, это было здорово!
Чтобы скомпилировать swc под Windows, надо: [...]

Читать дальше: Nape и Starling вместе? Это возможно!

четверг, 15 декабря 2011 г.

Делаем правильные swc библиотеки

Flex пока еще не отпускает меня, и приходится с ним возиться. Для начала, надо отметить, что Flex фреймворк в целом хорошая штука. Местами даже изящная штука (это я следую американскому стилю, которому меня научил Яков Файн: сперва похвалить, потом поругать).

Но вот в некоторых других местах Flex сделан весьма по-идиотски, и доставляет кучу эмоций. Видать весьма разнородная по техническому уровню команда над ним работала. И вот компиляторами точно занимались криворукие индусы.

Давеча я убрал maven/flexmojos из своих проектов, и заменил их ручной конфигурацией проекта в IDEA и ant скриптами. Надо сказать, что так проще и лучше. Во всяком случае, для меня этот вариант явно комфортнее.

Теперь, в отличие от варианта c flexmojos, проект действительно легко подымается с нуля на машине нового разработчика, сразу собирается и запускается. Все swc зависимости лежат прямо в папке libs в самом проекте. А все настройки IDEA комитятся в репозиторий вместе с кодом проекта (ну почти все, кроме workspace.xml).

Имея такую благостную картину, я решил взяться за проблему, которая уже давно мне докучает.

У нас есть ряд модулей (swc библиотек), которые написаны на чистом AS, не имеют никаких зависимостей от Flex SDK, и используются во многих проектах. Несмотря на то, что зависимостей нет, compc все равно старательно сует внутрь swc файла кучу классов из sdk. В результате модуль получается привязанный к конкретной версии sdk. И попытка использовать его в проекте с другим sdk может давать непредсказуемые эффекты, вплоть до того, что проект просто не соберется.

Стало быть, задача в том, чтобы убедить compc не пихать внутрь swc ничего лишнего, кроме классов и ресурсов самого модуля. Увы, адобовские инженеры постарались, чтобы задача эта оказалась нетривиальной.

Читать дальше: Делаем правильные swc библиотеки

пятница, 26 августа 2011 г.

Бот для Flash-игры / Внедряемся в Flash


В рамках недели ботов для браузерных игр.

Эта неделя богата на статьи о ботах для бразуерных игр.
Во всех статьях для управления ботом использовался AutoIT. Это простой и хороший способ чтобы начать делать бота «в лоб», он не требует никаких знаний об игре, кроме как знания правил и графического интерфейса. Для серверной части игры такой бот вообще будет выглядеть как обычный пользователь, если не брать во внимание невероятную усидчивость и производительность такого игрока.

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

В первой статье я наткнулся на комментарий со ссылкой на пост Adobe Profiler Fail, что побудило меня исследовать эту возможность в целях автоматизации действий в Flash-играх.

Читать дальше: Бот для Flash-игры / Внедряемся в Flash

понедельник, 11 июля 2011 г.

Генетические алгоритмы для флешеров

Пишет makc3d:
Давным давно в далёкой галактике Балаклаве, как раз перед тем, как уехать с ITSea 2011, я с Ростом пытался убедить знающих людей сделать доклад о генетических алгоритмах, однако все они отказались под предлогом того, что в этой теме слишком много математики. Разумеется, объяснить принципы генетических алгоритмов вполне возможно и без математики - как говорится, на пальцах - что я и попытаюсь сделать в этом посте.

Итак, генетические алгоритмы для чайников флешеров - что это такое и с чем его едят? Этод метод придумали ленивые математики, которые не хотели решать свои задачи в лоб. Вместо поиска решения задачи в явном виде они решили поручить компьютеру перебрать массу случайных вариантов в надежде, что какой-нибудь из них окажется близок к решению. А когда встал вопрос, как именно компьютер должен это делать, они решили не париться и просто скопировать процесс, хорошо зарекомендовавший себя на протяжении миллиардов лет.

Давайте рассмотрим этот процесс на примере решения следующей простой задачи: в начале координат стоит пушка и стреляет под углом 45° снарядом с начальной скоростью v; т.е. уравнения движения снаряда имеют знакомый из школьного курса вид x = vt/√2 и y = vt/√2 - gt²/2. Необходимо найти такое значение v, при котором снаряд упадёт на заданном расстоянии. Эта задача легко решается в явном виде, но в целях этого поста представим себя очень ленивыми математиками и используем генетический алгоритм.

Для этого мы создадим популяцию виртуальных существ, смысл жизни которых состоит в поиске решения нашей задачи [...]

Генетические алгоритмы для флешеров

среда, 13 апреля 2011 г.

Текстурирование спрайтов с помощью (dis)placement map

Текстурирование спрайтов с помощью (dis)placement map
Недавно, ковыряя с целью исследования один чужой проект, наткнулся на весьма любопытную и в то же время — очень простую технологию. Сразу скажу, что ковырял я флэшку, но данная технология может быть использована не только во флэше, а вообще — где угодно.

Если коротко, то технология позволяет иметь одну отрендеренную анимацию и накладывать на нее разнообразные скины, тем самым получая внешне различные объекты.

Суть в том, что в изучаемой мной игре есть большое количество анимированных спрайтов человечков (как я изначально считал — заранее отрендеренных). Человечки разные (по-разному одетые, разных цветов и т.п.).

Читать дальше: Game Development / Текстурирование спрайтов с помощью (dis)placement map

пятница, 8 апреля 2011 г.

Биндинг в ActionScript проектах. Часть 3

Биндинг в ActionScript проектах. Часть 3:

В предыдущих статьях мы рассмотрели возможности биндинга в плане привязки метатега [Bindable] к различным элементам нашего кода и кастомизации срабатывания биндинга с помощью событий. На этом возможности биндинга не ограничиваются. Подписка на события биндинга в методах BindingUtlis.bindProperty и BindingUtlis.bindSetter также дает большое количество возможностей для его реализации.

Для того чтобы слушать изменения свойства или метода, помеченного как [Bindable], необходимо использовать один из методов BindingUtlis.bindProperty или BindingUtlis.bindSetter.

public static function bindProperty (site:Object, prop:String, host:Object, chain:Object, commitOnly:Boolean = false, useWeakReference:Boolean = false):ChangeWatcher
public static function bindSetter   (setter:Function,          host:Object, chain:Object, commitOnly:Boolean = false, useWeakReference:Boolean = false):ChangeWatcher

Единственное принципиальное отличие этих двух методов заключается в том что в первом случае в результате срабатывания биндинга меняется значение указанного свойства prop в объекте site, во втором вызывается метод setter для обработки результата. В остальном эти два метода принимают одинаковые параметры и дальнейшее повествование будет иметь одинаковый смысл для обоих случаев.

Параметр host

Параметр host это объект в котором находится параметр или цепочка параметров за которыми необходимо следить.

Параметр chain

Итак, и метод bindProperty и bindSetter имеют обязательный параметр сhain типа Object, который может принимать следующие значения:

chain в виде строки

Определяет имя привязываемого свойства:

1
BindingUtils.bindSetter(onPropChange, host, "prop");

До сих пор мы в качестве chain всегда передавали именно строку и об использовании данного параметра в таком качестве можно прочесть в предыдущих статьях;

chain в виде массива

Непустой массив, содержащий последовательность свойств за которыми необходимо следить:

1
BindingUtils.bindProperty(this, "prop", host, ["a", "b", "c"]);

Массив в качестве цепочки крайне удобен и используется достаточно часто. Цепочка свойств должна быть указана в виде ["a","b","c"] что будет соответствовать привязке свойства host.a.b.c. Может возникнуть вполне резонный вопрос: “Почему в качестве host не указать сразу host.a.b, а свойство за которым следить не передать в качестве строки "c"?

1
BindingUtils.bindProperty(this, "prop", host.a.b, "c");

Цепочкой целесообразно пользоваться когда в ней встречаются изменяющиеся свойства тоже помеченные метатегом [Bindable]. Утилиты биндинга автоматически будут распознавать изменение любого из таких свойств в цепочке и нам не понадобится городить биндинг в биндинге, следить чтобы экземпляры ChangeWatcher были отписаны и т.п.

Представим что у нас есть класс Model в котором есть свойство item типа Item [...]

четверг, 31 марта 2011 г.

Как добавить практически любой шрифт в ваш Flash-проект - бесплатная утилита от MotoCMS

Как добавить практически любой шрифт в ваш Flash-проект - бесплатная утилита от MotoCMS:

Пишет Николай Внимательный:

Проблема использования большого количества разнообразных шрифтов, в одном флэш-проекте стоит достаточно остро. Нам всем хочется, чтоб создаваемые нами сайты радовали своих посетителей многообразием шрифтовой палитры.

Font embedding

Речь идет о том, что в сети достаточное количество разнообразных бесплатных шрифтов, но не всегда они подготовлены для дальнейшего использования в наших флеш-проектах.

Продолжение - Как добавить практически любой шрифт в ваш Flash-проект [...]

Быстрое внедрение шрифтов [Embed]

Быстрое внедрение шрифтов [Embed]:

Уже ни раз писалось о встраивании шрифтов, поэтому я не буду описывать весь процесс а покажу лишь простой и удобный прием на примере кода.

package assets {
 import flash.display.Sprite;
 import flash.system.Security;
 import flash.text.Font;
 import flash.utils.describeType;
 
 public class FontsAsset extends Sprite {
  [Embed(source="../../../res/fonts/MyriadPro-Semibold.otf", mimeType="application/x-font-truetype", fontName="MyriadSemibold", unicodeRange="U+0020-U+002F,U+0030-U+0039,U+003A-U+0040,U+0041-U+005A,U+005B-U+0060,U+0061-U+007A,U+007B-U+007E,U+02C6,U+02DC,U+2013-U+2014,U+2018-U+201A,U+201C-U+201E,U+2020-U+2022,U+2026,U+2030,U+2039-U+203A,U+20AC,U+2122,U+0401,U+0410-U+044F", embedAsCFF="false")]
  // Uppercase [A..Z] ; Lowercase [a..z] ; Numerals [0..9] ; Punctuation [!@#%...] ; Basic Latin ; chars="АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюя"
  public static var MyriadSemibold : Class;
 
  [Embed(source="../../../res/fonts/MyriadPro-Regular.otf", mimeType="application/x-font-truetype", fontName="MyriadRegular", unicodeRange="U+0020-U+002F,U+0030-U+0039,U+003A-U+0040,U+0041-U+005A,U+005B-U+0060,U+0061-U+007A,U+007B-U+007E,U+02C6,U+02DC,U+2013-U+2014,U+2018-U+201A,U+201C-U+201E,U+2020-U+2022,U+2026,U+2030,U+2039-U+203A,U+20AC,U+2122,U+0401,U+0410-U+044F", embedAsCFF="false")]
  // Uppercase [A..Z] ; Lowercase [a..z] ; Numerals [0..9] ; Punctuation [!@#%...] ; Basic Latin ; chars="АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюя"
  public static var MyriadRegular : Class;
 
  public function FontsAsset() {
   Security.allowDomain("*");
   var xml : XML = describeType(this);
   for (var i : uint = 0; i < XMLList(xml["variable"]).length(); i++) {
    Font.registerFont(this[XMLList(xml["variable"])[i].@name]);
   }
  }
 }
}

Собственно встроить шрифтов можно сколько угодно, в коде ничего менять не придется кроме добавления строк описывающих само встраивание.
Чтобы шрифты отображались в самом приложении достаточно будет в конструкторе создать новый экземпляр FontsAsset.

new FontsAsset();

Конечно не стоит забывать о использовании textField.embedFonts.

[...]

среда, 30 марта 2011 г.

ВКонтакте и бонусы за приглашенных друзей

ВКонтакте и бонусы за приглашенных друзей:

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

Бонусы за друзей все так же можно начислять, достаточно посмотреть на этот вопрос с другой стороны.
Многие приложения, будь то фейсбук или вк, используют следующие механики поощрения за приглашения друзей:

  1. определенные игровые итемы можно получить только от друзей
  2. друзья раз в сутки могут присылать итемы которые дают энергию (или её аналог)
  3. друзей можно нанимать в качестве помощников, что будет приносить бонусы

и т.д.

Все эти способы не противоречат правилам.

вторник, 22 марта 2011 г.

Биндинг в ActionScript проектах. Часть 2

Биндинг в ActionScript проектах. Часть 2:

Рамки использования метатега [Bindable] значительно шире указнных в статье Биндинг в ActionScript проектах. Часть 1. В данной статье расскажу о том куда можно применить данный метатег и о возможностях биндинга в случае использования собственных событий.

Куда можно воткнуть метатег [Bindable]?

Метатег [Bindable] можно использовать в следующих местах:

1. Перед свойством.

Свойство может быть как public, так и protected или private.

Например:

1
2
[Bindable]
public var text:String;

О биндинге применительно к свойствам уже говорилось в первой части. Компилятор автоматически преобразует свойство, помеченное тегом [Bindable] к геттеру/сеттеру с отсылкой события.

2. Перед определением класса

1
2
[Bindable]
public class SomeClass extends EventDispatcher

Это равносильно тому, что мы бы проставили метатег [Bindable] для каждого из public свойств этого класса. Private и protected или свойства из другого пространства имен автоматически не будут помечены как [Bindable]. Если нужно забиндить не public свойства к ним нужно дописывать метатег [Bindable] самостоятельно.

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

3. Перед get или set методом

Метатег [Bindable] так же можно использовать если свойства у класса оформленны в виде get/set методов:

1
2
3
4
5
6
7
8
private var _text:String;
[Bindable]
public function get text():String{
    return _text;
}
public function set text(value:String):void{
    _text = value;
}

Компилятор позволит вам поставить его как возле геттера, так и возле сеттера. Но! Как изветсно если мы для свойства напишем только сеттер то оно будет доступно только для записи (write only), если же напишем только геттер то только для чтения (read only). С помощью BindingUtils “забиндиться” на свойство доступное только для записи невозможно, но сделать это для свойства, доступного только для чтения – вполне.  Я настоятельно рекомендую всегда писать тег [Bindable] только рядом с геттером, это позволит видеть событие (см. ниже) и избежать путаницы и ошибок.

Если указан только геттер и свойство доступно только для чтения, целесообразно использовать биндинг только совместно с событиями (см. раздел “Кастомные события”), иначе биндинг сработает только во время инициализации, а среда разработки будет выдавать предупреждения.

4. Перед методом

1
2
3
4
5
[Bindable(event="bindFunctionChange")]
public function bindFunction(prop:int):String{
    ...
    return someString;
}

Так же как и в случае со свойством доступным только для чтения, метатег для метода имеет смысл указывать только вместе с событием. Ниже можно посмотреть пример использования.

Кастомные события

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

Итак о событиях. Рассмотрим их при использовании с геттером. Представим что нам необходимо задать в каких конкретно случаях будет срабатывать биндинг, или чтобы он сработал после того как мы выполним все необходимые оперции в сеттере. Для этого в нашем метатеге мы можем указать событие в результате которого сработает биндинг [...]

четверг, 17 февраля 2011 г.

Биндинг в ActionScript проектах. Часть 1

Биндинг в ActionScript проектах. Часть 1:

Перед разработчиками часто встает вопрос о взамодействии различных классов в приложении. Как классы приложения будут обмениваться информацией между собой, сообщать о тех или иных изменениях? Это должно происходить своевременно. Для этих целей во Flex-фреймворке есть замечательный инструмент, значительно облегчающий жизнь разработчику – биндинг (binding). И как оказалось этой возможностью можно с успехом пользоваться и без использования Flex-фреймворка. Начиная с какой-то-там одной из третьих версий SDK адобовцы постарались максимально изолировать биндинг и все что с ним связано, и теперь его использование добавляет приложению считанные килобайты.

Как бы мы сделали

Немного отвлечемся и поговорим о частном случае. Когда же нам может все это дело пригодиться? Например, при разработке с использованием паттерна MVC встает вопрос о своевременном реагировании компонентов отображения на изменения в модели.

Как известно в MVC классы модели ничего не должны знать и не иметь ссылок ни на классы контроллера, ни на классы отображения. А вот на модель имеют ссылку и контроллер и отображение. Контроллеру нужна ссылка для того чтобы изменить модель, отображению – чтобы отреагировать на изменения. С изменением модели вроде все понятно – нужно поменять свойство. Но как отображение узнает о том что данные были изменены, чтобы самому измениться? Как правило для этих целей используются события. Мы создаем в модели сеттер на нужное нам свойство и в тот момент когда свойство меняется – посылаем соответствующее событие:

1
2
3
4
5
6
7
8
9
private var _text:String;

public function set text (value:String):void{
    if (value == _text){
        return;
    }
    _text = value;
    dispatchEvent(new Event("textChanged"));
}

Класс отображения имея ссылку на модель может поймать данное событие и отреагировать на него соответствующим образом. Все вроде хорошо, но есть ряд неудобств:

  1. Для каждого свойства в модели придется писать геттер/сеттер. А это много рутинной писанины, класс начинает пухнуть.
  2. При большом количестве свойств в модели будет либо расти количество типов событий, либо придется делать кастомное событие и передавать дополнительно что же именно изменилось и новое значение. В любом случае неудобно.

Как это делается с помощью биндинга

А как же все таки было бы здорово просто написать в классе отображения: “при изменении вот этого свойства вон в том экземпляре класса изменить вот это свойство” или вот так: “при изменении вот этого свойства вон в том экземпляре класса вызвать вот этот метод для обработки”. Так вот стандартный флэксовый биндинг работает именно так.

Давайте посмотрим как это будет выглядеть непосредственно в коде. То свойство за которым нам необходимо пристально следить нужно пометить как bindable. Делается это очень просто, с помощью метатега [Bindable]:

1
2
3
4
5
6
7
8
9
package{
    import flash.events.EventDispatcher;

    // Класс который использует метатег [Bindable] должен обязательно расширяться от EventDispatcher
    public class ClassWithTextProperty extends EventDispatcher{
        [Bindable]
        public var text:String;
    }
}

В классе который должен следить за свойством text в другом классе будет написано следующее [...]

Сортировка массива объектов по нескольким полям

Сортировка массива объектов по нескольким полям:

Иногда возникает необходимость отсортировать некоторый массив объектов сразу по нескольким полям. Например, есть список пользователей. Каждый из них в текущий момент может быть в онлайне. Наша задача - отсортировать список таким образом, чтобы сначала показывались по алфавиту пользователи в онлайне, а за ними - те, кто в оффлайне. Это можно сделать так:

 
package {
import flash.display.Sprite;
import flash.utils.getTimer;
 
public class VectorSorting extends Sprite {
 
    private var players:Vector.<Player> = new Vector.<Player>();
 
    public function VectorSorting() {
        // Заполняем массив данными
        addPlayers(50);
 
        // Выводим начальный массив
        playersTrace();
 
        // Засекаем время
        var current:int = getTimer();
 
        // Cортируем массив
        players.sort(
            function(a:Player, b:Player):Number {
                if (a.online == b.online) {
                    return a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1;
                } else {
                    return a.online ? -1 : 1;
                }
            }
        );
 
        // Выводим время, затраченное на выполнение сортировки
        trace("Сортировка заняла",String(getTimer()-current),"миллисекунд");
 
        // Выводим отсортированный массив
        playersTrace();
    }
 
    /**
     * Вывод содержимого массива
     */
    private function playersTrace():void {
        trace("--------------------------");
        for each (var player:Player in players) {
            trace(player.toString());
        }
        trace("--------------------------");
    }
 
    /**
     * Заполнение массива начальными данными
     */
    private function addPlayers(numPlayers:int):void {
        for (var i:int = 0; i < numPlayers; i++) {
            var rName:String = "Player " + String(int(Math.random() * 100));
            var rOnline:Boolean = Boolean(Math.random() > .5);
            var currentPlayer:Player = new Player(i, rName, rOnline);
            players.push(currentPlayer);
        }
    }
}
}
 
class Player {
    public var id:int;
    public var name:String;
    public var online:Boolean;
 
    public function Player(id:int, name:String, online:Boolean) {
        this.id = id;
        this.name = name;
        this.online = online;
    }
 
    public function toString():String {
        return "Player{id="+String(id)+",name="+String(name)+",online="+String(online)+"}";
    }
}

понедельник, 31 января 2011 г.

/* Закомментированные хитрости */

/* Закомментированные хитрости */: "

Пишет Dan:
Счастливые родители:

// - однострочный комментарий, компилятор игнорирует все остальные символы до конца строки
/* - начало многострочного комментария, компилятор игнорирует все символы пока не встретится
*/ - конец многострочного комментария

Разномастные дети:

//* - однострочный комментарий, который можно превратить в начало многострочного удалением одного слеша
/**/ - безопасный конец многострочного комментария: даже если не было начала, то не будет ошибки компиляции
/*/ - или начало, или конец многострочного комментария, по обстоятельствам

читать далее [...]

вторник, 25 января 2011 г.

Политика безопасности во Flash Player. Наиболее частные столкновения.

Политика безопасности во Flash Player. Наиболее частные столкновения.:

Часто вы сталкивались с ситуацией, когда ваш код не работает по непонятным причинам? Вам кажется, что всё уже проверено сотни раз и вы с уверенностью говорите себе, что здесь нет ошибок, и уже готовы биться головой о клавиатуру :) Спешу вас утешить, скорее всего ошибка не в коде.

В чем же дело?

А дело может быть в том, что вы нарушаете политику безопасности Flash Player, сами того не зная. Иногда Flash Player просто промолчит об этом :)

Как это предупредить?


Если что-то не работает, а по логике должно - идите в справку. Там кроются все ответы на ваши вопросы. Вообще справка должна быть неотъемлемым инструментом разработчика.

В этом посте я хочу рассказать о наиболее частых нарушениях политики безопасности, с которыми мы сталкиваемся.

Загрузка контента с доменов отличных, о того с которого запущена страница с .swf-файлом

*.load();

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

BitmapData.draw();[...]

воскресенье, 2 января 2011 г.

Добавление графики нашему механизму

Добавление графики нашему механизму:

Расширим предыдущий пример, добавив к нему графику и дополнительные возможности.
Код данного примера будет довольно сильно переработан.
1. Чтобы добавить графику, нужно сначала ее нарисовать. Здесь я не стал сильно мудрить, а просто взял картинку из предыдущего поста и разбил ее на несколько частей:

Корпус двигателя
Коленвал с маховиком
Шатун
Поршень

Сохранять эти изображения нужно в формате png, поддерживающем прозрачный фон.

2. Создаем новый AS3 проект во FlashDevelop, задавая размеры выходного файла равными 192х410 пикселей. Переносим файлы изображений деталей двигателя в папку lib нашего проекта.

3. В данном примере мы разделим кода на 3 логические части: первая будет отвечать за расчет положений механизма (своего рода модель), вторая – за отображение механизма на экране (вид) и третья – выполняет роль инициализатора приложения (создает модель и виды механизма) и контроллера для модели.

3.1. Сначала разберемся с кодом модели механизма, за нее будет отвечать класс MechModel [...]

среда, 8 декабря 2010 г.

Авто-ориентирование мобильного приложения

Авто-ориентирование мобильного приложения:

Проблема

Правильное расположение приложения при повороте экрана устройства.

Решение

Добавить в файл application.xml, после тега <initialWindow>:

<autoOrients>true</autoOrients>

Повесить на stage слушателя StageOrientationEvent, перед этим проверить, что включена автоматическая ориентация [...]

Читать дальше: Авто-ориентирование мобильного приложения