воскресенье, 29 июля 2012 г.

NME и HTML5: ready or not?

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

В начале этой недели я в очередной раз попытался скомпилировать простую демку для HaxeFlixel в html5 и сразу же наткнулся на проблему: метод draw() класса BitmapData не учитывал параметры matrix (трансформация положения и формы) и colorTransform (цветовая трансформация), в то время как отрисовка графики в движке полностью строится на двух методах (draw() и copyPixels()). Но за что я люблю NME, так это за отзывчивость разработчиков, и буквально за три дня описанная проблема была исправлена. После этого я занялся непосредственно попыткой скомпилировать демку FlxInvaders в js-код. Сам процесс занял около 6 часов и состоял в основном в дописании параметров условной компиляции (ничего сложного), сам код практически не изменился. И вот, наконец, мне удалось запустить ее, но результат не впечатлил: всего 15-16 фпс против желаемых 30.
После этого началось небольшое исследование + экспериментрирование:
  • где-то полгода назад я услышал о Jangaroo -- специальном SDK, позволяющем компилировать AS3-код в JS, примерно тогда же встретил демку Jumper -- платформер, написанный на AS3 с использованием Flixel и портированный с помощью Jangaroo на html5. То есть успешные попытки портирования Flixel на html5 уже есть, и довольно давно. Так вот, вспомнив об этой технологии, решил поискать еще примеров по ней. Гугл выдал мне следующую страницу, содержащую несколько ссылок по данному предмету, в том числе и на демку FlxInvaders, которая у меня в Хроме выдает в среднем 42-43 фпс, т.е. почти в три раза быстрее.
  • увидев такую разницу в производительности, у меня возникло две мысли: а) мой порт тормозной и б) Jeash тормозной. С первой я спорить не стану, т.к. Flixel использует отрисовку всей графики в одну битмапдату (что является аналогом использования только одного элемента Canvas в JS), а это не самая эффективная техника (но Jangaroo умудряется выдавать при этом гораздо лучший результат), то вторая требовала более подробного изучения.
  • и один день я посвятил данному вопросу. Написал несколько пару простых демок, суть их такова: имеем приложение размером 800х600, в него рисуются спрайты, в каждый из которых вложена битмапа с одним и тем же изображением (30х30 px). В итоге имеем, что при 30 фпс я могу отрисовать 110-120 таких спрайтов, а при 60 — только 45. И это в Хроме, в ФайрФоксе и IE все хуже. Мне такие результаты совсем не нравятся, и Jeash (я так считаю) еще не готов для написания "серьезных" игр (под серьезными здесь я понимаю игры с большим количеством движущихся и трансформируемых объектов).
В итоге родилась следующая, так сказать, "мысль": переписать под себя класс BitmapData (ориентируясь на его текущую реализацию и версию Jangaroo), т.к. практически весь вывод графики в HaxeFlixel зависит от него. Но это, опять же, в отдаленной перспективе, т.к. в приоритете система слоев для C++, которая все так же находится в ранней стадии разработки, а затем stage3D-версия.

UPD: Совершенно забыл приложить скомпилированную версию демки и исходники теста производительности отрисовки спрайтов

среда, 25 июля 2012 г.

Happy Birthday to HaxeFlixel

В этот день год назад я создал на гитхабе репозиторий для HaxeFlixel. За прошедшее время было многое сделано, но в планах на будущее проекта у меня запасено еще на столько же времени, и даже больше. Спасибо Адаму Солтсману за оригинальный Flixel, спасибо Николя Каннасcу за язык Haxe и спасибо Хью Сандерсону, Джошуа Гранику и другим разработчикам за библиотеку NME!!!

среда, 18 июля 2012 г.

О возможном решении проблемы порядка отрисовки графики в HaxeFlixel

В одном из предыдущих сообщений я писал об одном из вариантов решения проблемы порядка отрисовки графики (draw order problem) -- для этого планировалось использование текстурных атласов и введение идеи слоев. Как уже было сказано, у данного решения есть существенное достоинство -- сокращение вызовов методов отрисовки графики, когда число вызовов таких операций за кадр будет равно числу слоев. Это значит, что если все используемые в игре изображения могут уместиться в одном атласе (размером, например, 1024*1024 пикселя), то метод drawTiles() будет вызываться только один раз за кадр. Кроме достоинств есть, конечно же, и недостатки -- повышенное потребление видеопамяти, т.к. 100% упаковка графики в атласы (когда используется вся площадь атласа и нет пустых "пятен") практически недостижима и требует от разработчиков дополнительного внимания (Возможно, что для упрощения работы с атласами, позже будут внедрены парсеры распространенных форматов, например, формат фреймворка Sparrow).
Для реализации данного способа решения уже имеются некоторые наработки -- класс для генерации текстурных атласов на лету я уже портировал на Haxe. Так что, скорее всего, данный метод будет реализован в первую очередь.
После некоторых экспериментов и размышлений я пришел ко второму возможному решению данной проблемы, не требующему использования текстурных атласов. Дело в том, что когда я только начинал портировать Flixel на Haxe, класс TileSheet у меня работал несколько иначе, чем сейчас. Возможно, что у меня тогда руки были кривее и я неправильно его использовал, или что поведение данного класса действительно изменилось. Но факт остается фактом: открылись некоторые новые для меня стороны данного класса, а именно то, что за один кадр можно неоднократно вызывать метод drawTiles() для одного и того же экземпляра TileSheet без появления артефактов. А когда я пытался сделать так в конце прошлого года, то переставали работать цветовые трансформации тайлов.
Теперь же есть возможность вызывать для каждого из изображений в слое метод drawTiles(), и, таким образом, достичь (или почти достичь) желаемого эффекта. Конечно же, при таком решении будет использоваться пакетная отрисовка графики, но в пределах каждого из слоев, иначе эффект от использования класса TileSheet будет равен нулю (т.к. чем больше вызовов метода drawTiles(), тем ниже производительность).
Возможно, что конечный результат будет комбинировать оба решения проблемы, я еще не решил окончательно. Но в первую очередь, как уже писал, я займусь вариантом с использованием атласов.

UPD:  Вспомнил еще об одной особенности работы класса TileSheet, о которой я раньше не знал (или она появилась позже, чем я с ней экспериментировал). Оказывается, что после создания экземпляра TileSheet, возможно изменять его битмапдату-источник, и данные изменения будут отображаться при отрисовке. Раньше же я такого не мог достичь (может быть это было еще одним проявлением моей криворукости). Эта особенность значительно упрощает работу с атласами, т.к. теперь нет необходимости пересоздавать их каждый раз при добавлении в них новых изображений (здесь, конечно же, опять возникает проблема неэффективного использования атласов, т.к. при создании атласов желательно сортировать по размеру входящие в них изображения, иначе в атласе будет полно "белых пятен").

вторник, 17 июля 2012 г.

Хорошее начало недели

Вчера, в понедельник, вышла новая версия Haxe 2.10. Главными ее нововведениями являются:
- поддержка языков C# и Java (пока что в состоянии бета-версии);
- уменьшение размера сгенерированного Javascript-кода;
- C++ дебаггер, о котором авторы обещают скоро написать поподробнее;
- переработка макросов, которые должны стать более понятными новичкам;
- множество улучшений в языке;
- и, конечно же, багфиксы.
Интересным фактом, связанным с этой версией, является то, что за период ее разработки (примерно 3 месяца) было сделано 693 ревизии.
Что ж, теперь будем ждать следующего релиза, на этот раз уже версии 3.0.
А сегодня, во вторник, вышла новая версия библиотеки NME 3.3.4 с улучшенной поддержкой BlackBerry, iOS и HTML5, а также с множеством исправлений ошибок.
К этим событиям я решил приурочить выход небольшого обновления для HaxeFlixel, содержащего:
- новый логотип;
- порт плагина FlxKongregate, позволяющего работать с API данного сервиса (только для Flash);
- порт плагина StarfieldFX - эффект звездного неба (фона);
- исправление нескольких ошибок.
И теперь я с уверенностью могу сказать, что HaxeFlixel поддерживает Haxe 2.10.
Скоро напишу о том, что я пытаюсь улучшить в движке. А пока что это все, о чем хотел рассказать вам сегодня.

суббота, 14 июля 2012 г.

Новый логотип для HaxeFlixel

Хочу поделиться небольшой новостью (и большой радостью для меня): наконец-то у HaxeFlixel появился свой логотип:
Flixel + Haxe = HaxeFlixel
Я давно думал о создании чего-нибудь подобного, но мои художественные способности и лень мешали реализации. Данный логотип придумал и нарисовал австралийский программист Крис, скрывающийся под ником Impaler.

Огромное спасибо тебе, Крис!

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

В ближайшее время ждите новых новостей!

суббота, 7 июля 2012 г.

HaxeFlixel 1.05

С момента записи о планах на версию 1.02 прошло уже два месяца. За это время успело выйти несколько обновлений, о которых я, к сожалению, не писал, а сегодня вышла 1.05. Что же мы имеем на текущий момент:
- все, что было запланировано для версии 1.02;
- исправлено несколько ошибок (самой важной из которых считаю исправление работы звука под android);
- классу FlxSprite добавлен метод loadFrom(), позволяющий использовать в текущем спрайте графику из другого спрайта. Этот метод является еще одним шагом к решению проблемы порядка отрисовки графики. О дальнейшем ходе возможного решения данной проблемы напишу чуть позже в этом посте;
- интрегрирована система tween-анимации из HaxePunk -- теперь у всех подклассов FlxBasic доступны методы addTween(), removeTween() и clearTweens(), а также у класса FlxG появилось статическое свойство tweener, которое может использоваться как глобальный инструмент для анимации. Базовым классом для таких анимаций является класс org.flixel.tweens.FlxTween (в оригинале назывался просто Tween), его возможные вариации (подклассы) находятся в пакетах org.flixel.tweens.*. Для справки о применении tween-анимаций посмею направить вас изучать соответствующие туториалы FlashPunk'а. Если же кому-нибудь будет интересно рассмотреть данный вопрос отдельно, то пишите о этом в комментариях
- добавлена базовая поддержка мультитача и джойстиков. Джойстики поддерживаются только на c++ и толком еще не тестировались, поэтому мне нужна ваша помощь в этом деле (опять же заинтересовавшихся прошу писать в комменты -- тестовый пример вышлю);
- поддержка новой версии языка Haxe 2.10. На самом деле я еще не совсем уверен, что закончил ее, т.к. иногда приложение вылетает с ошибкой, но эта проблема может быть вызвана еще и нестабильностью SVN-версии HXCPP и возможной неполной совместимостью с NME. Так что здесь надо будет подождать их официального выхода, там посмотрим.
Об остальных менее важных изменениях можно прочитать в списке изменений.
Теперь о дальнейших планах. Если вы иногда просматриваете список текущих проблем на ГитХабе, то уже сами все знаете:
- решение проблемы порядка отрисовки графики для c++. Здесь, я думаю, поможет использование текстурных атласов, о реализации которых я писал в одном из предыдущих постов, а также внедрение идеи "слоев", когда у каждого из слоев будет свой атлас. В каждом из таких атласов может находиться одно или несколько изображений для спрайтов и прочих графических классов (их будет нужно добавлять на этапе создания текущего стейта). Сам класс слоя будет подклассом FlxGroup (я думаю дать ему имя FlxLayer). Таким образом, спрайты в слое будут отрисовываться в таком же порядке, как они находятся внутри группы (их порядок в группе можно менять), также можно будет менять порядок отрисовки слоев. Графика в каждом слое будет отрисовываться за один присест. Такая "концепция" может помочь уменьшить вызов операций отрисовки графики, но также может иметь и отрицательные стороны, например, повышенное использование графической памяти.
- о создании stage3d версии я все еще думаю, но теперь мне эта идея не кажется такой простой. Так что ее вы увидите еще не скоро.
- также все чаще думаю о поддержке платформы html5, но пока что особых успехов не достиг. Буду пробовать дальше после выхода новой версии NME.
- добавление новых фич классу FlxTilemap, например, поддержки масштабирования (данная фича может быть полезна для использования тайловой карты в качестве фона)
- портирование экспортеров из редактора карт Dame для их использования с HaxeFlixel. Это должно облегчить создание уровней для игр, не прибегая каждый раз к ручному редактированию классов, получившихся на выходе из редактора.
- создание github-сайта для проекта, но эта идея пока что из разряда мечтаний.
- доработка поддержки мультитача -- касается классов, поддерживающих события мыши (FlxButton, FlxExtendedSprite и др.).
- небольшая кучка других изменений / "улучшений".
Как видно работы еще полно, этого развлечения мне надолго хватит. Ежели вам захочется увидеть реализованной какую-либо еще фичу, прошу запостить ее все там же или написать о ней в комментариях здесь.
На этом смею закончить. Надеюсь, в следующий раз напишу что-нибудь поинтереснее.

Обновление компонента BitmapFont

Наконец-то у меня дошли руки до доработки компонента для работы с растровыми шрифтами. Итак, что же нового было добавлено:
- самое главное изменение -- это добавление поддержки широко распространенного формата AngelCode. А самое важное это то, что для создания шрифтов в таком формате существует ряд специализированных программ (так что добавление нового шрифта значительно упрощается). Самой простой из них является BMFont (бесплатная, работает под Windows), позволяющий создавать шрифты на основе установленных в системе. К сожалению, настроек внешнего вида шрифтов в ней "кот наплакал" (размер, толшина обводки, сглаживание, использовать ли курсив или полужирное начертание), но это лучше чем ничего. Есть еще гораздо более продвинутая программа под Mac OS - Glyph Designer, но за нее просят порядка 30 американских президентов. Эти программы наиболее распространенные, но можно найти и другие.
- вторым, но уже совсем небольшим, изменением является добавление опции "useColor" (для AS3-blit и Haxe версий), или "useTextColor" (для AS3-Flixel версии) объектам класса PxTextField. Данное свойство имеет смысл использовать, если вы загружаете шрифт, созданный в программе Glyph Designer. Дело в том, что в этой программе есть возможность задавать основной цвет символов шрифта, а также задавать его обводку другим цветом. Но если загрузить такой шрифт в мой компонент когда свойство "useColor" имеет значение "true" (устанавливается по-умолчанию), то цвет шрифта будет трансформирован в соответствии со значением свойства "color" объекта PxTextField. Установив значение свойства "useColor" в "false", такой трансформации происходить не будет и шрифт будет выглядеть так, как вы это настраивали в программе.
- Так как в описываемый компонент была добавлена поддержка нового формата, то пришлось изменить немного способ работы со шрифтами. Если раньше, чтобы создать шрифт, нужно было писать код подобный следующему:
_font = new PxBitmapFont(fontBitmapData, fontString);
то теперь, в зависимости от того, в каком формате загружается шрифт, используется следующий синтаксис:
_font = new PxBitmapFont().loadPixelizer(fontBitmapData, fontString); // для загрузки шрифта в старом формате, взятом из движка Pixelizer,
или
_font = new PxBitmapFont().loadAngelCode(fontBitmapData, xmlFontData); // для загрузки шрифта в формате AngelCode, где xmlFontData -- XML данные шрифта.
(Если что-то непонятно, то рекомендую посмотреть пример, там все предельно просто и понятно)

В заключение хочу обратить внимание, что поддержка формата AngelCode в компоненте имеет некоторые ограничения / накладывает некоторые требования:
- как видно из используемого синтаксиса, все символы встраиваемого шрифта должны быть в одном графическом файле;
- поддерживается только xml формат *.fnt файлов (как самый простой для разбора);
- если вы планируете использовать свойство "color / textColor" для цветовой трансформации текста, то в опциях эспорта шрифта используйте опцию "White text with alpha" ("Белый текст с програчным фоном").


Теперь о дальнейших планах:
- планирую добавить поддержку "типов" текстовых полей. Думаю, что будет два типа -- динамические (как сейчас) и поля ввода. За основу возьму эту серию уроков по созданию компонентов для FlashPunk.
- возможно, что сделаю поддержку stage3D, но это в крайне отдаленной перспективе, т.к. еще очень много планов по развитию HaxeFlixel, но о них в следующий раз.
На этом все. До скорых встреч :)


P.S.: скачать компонент BitmapFont вы можете с github-репозитория "проекта"