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

Отчет за первую половину мая 2012

В предыдущем сообщении я писал о планах на следующий релиз HaxeFlixel. А спустя две недели, наконец, доделал все что планировалось. Дата официального релиза на haxelib пока остается открытой, так как для работы новой версии требуются новые фишки класса TileSheet из библиотеки NME, присутствующие только в SVN-версии. Так что ждем выхода следующей версии NME. А пока что для использования новой версии придется самостоятельно компилировать NME (инструкцию по компиляции можно найти здесь)
Теперь же собираюсь заняться переводом flash-версии Flixel на Stage3D. При работе буду ориентироваться на axel2d, благо что его структура практически совпадает со структурой Flixel. Еще одним инструментом будет портированный на Haxe ассемблер AGAL'а -- наконец-то без ошибок!!!

Следующей новостью является обновление движка Pixelizer до версии 0.4.3 (в основном содержит исправления ошибок). Haxe-порт был обновлен в тот же вечер, что и релиз, и лежит здесь. На него тоже есть некоторые планы -- добавление рендерера на основе класса TileSheet для нативных платформ.

И заметка для себя: покопаться с библиотекой nme-tilelayer от Philippe Elsass -- это обертка для класса TileSheet, предоставляющая базовые методы для работы со списком отображения (display-list), анимациями и трансформациями тайлов. Кроме нативных платформ, она работает на Flash и HTML5 (для этого используются битмапы). Пример использования -- nme-runnermark -- портированный с AS3 на Haxe бенчмарк производительности stage3d-фреймворков (результаты впечатляют).

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

Flixel for Monkey

В этом коротком сообщении хотелось бы рассказать о существовании проекта Flixel for Monkey. Это порт многократно здесь упоминаемого движка Flixel на язык Monkey. О том, что это за язык, вы можете узнать из статьи "О Monkey, откровенно" (автор этой статьи как раз и занимается данным портом). Я хотел бы поблагодарить его за проделанную им работу и за его советы по оптимизации движка. Как оказалось, процесс обнаружения и разрешения столкновений в оригинальном Flixel'e требует некоторой оптимизации -- в классах FlxQuadTree и FlxObject  создается много мусора (объектов типа FlxQuadTree, FlxList и FlxRect), что повышает потребление памяти приложением. Решение данной проблемы простое: кеширование и повторное использование объектов вместо создания новых. Пользуясь этой наводкой, а также сверяясь с исходным кодом порта (синтаксис языка Monkey оказался очень простым и понятным), описанная проблема была решена.
Еще раз хочу сказать спасибо товарищу Devolonter и надеюсь, что он не бросит свою работу.

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

Планы для версии HaxeFlixel 1.02

На прошлой неделе вышло обновление порта Flixel на haxelib до версии 1.01. Основными изменениями в данном релизе были портирование прелоадера (наконец-то) и совместимость с Haxe 2.09.  А сейчас я хотел бы поделиться планами на будущий релиз:
  1. В оригинальной версии движка поддерживается неоднородное масштабирование спрайтов, т.е. спрайту можно задать один масштаб по оси x и другой по оси y. При создании специального рендерера (для C++) на основе класса TileSheet пришлось отказаться от такой фичи, т.к. данный класс поддерживал только однородное масштабирование. Недавно такой функционал был добавлен (пока что только в SVN-репозитории библиотеки), причем теперь можно задавать не просто масштабные коэффициенты и угол поворота каждого тайла, а значения коэффициентов матрицы трансформации, т.е. мы можем еще и зеркально отразить тайл, скосить (skew) его, или совместить все эти трансформации вместе. Пользуясь новым функционалом я хочу вернуть неоднородное масштабирование, а также заново реализовать зеркальное отражение спрайтов (свойство flipped), которое сейчас реализовано путем изменения исходного изображения для спрайта.
  2. В текущей версии движка для C++ наблюдаются проблемы с отрисовкой спрайтов -- для повернутых или масштабированных спрайтов появляются графические артефакты. Эта проблема может быть решена простой модификацией изображения для спрайта -- вставкой "пустых" пикселей между изображениями кадров.
  3. Как я уже писал в предыдущем сообщении, реализация класса FlxText довольно неудачна для C++, и я начал работу над компонентом для работы с растровыми шрифтами. Текущая версия данного компонента для HaxeFlixel пока что работает только на Flash и уже лежит на гитхабе (класс FlxBitmapTextField), остается только реализовать отрисовку на C++ (с этим не должно возникнуть особых сложностей, т.к. подобную задачу я уже решал).
  4. "Улучшение" класса FlxButton. Может быть достигнуто заменой кода, отвечающего за отрисовку текста на кнопке, т.к. сейчас он выводится с помощью класса FlxText, это можно исправить используя разрабатываемый класс FlxBitmapTextField (хотя данное изменение еще под вопросом).
  5. Закончить портирование класса FlxBar (нужен, например, для отрисовки полоски здоровья у героя или врагов) из библиотеки Flixel Power Tools. Хотя данный класс и работает на всех поддерживаемых платформах, есть необходимость его оптимизации для C++, т.к. каждый раз при изменении отображаемого значения создается много мусора, что значительно замедляет работу приложения.
  6. Небольшой рефакторинг: замена объектов типа Dynamic на соответствующие типизированные объекты (там, где это возможно). Например, у кнопок есть свойство onUp, представляющее собой функцию, вызываемую при отпускании левой кнопки мыши, данное свойство должно вместо Dynamic быть Void->Void, т.е. быть функцией без аргументов и возвращаемого значения.
Вот и все планы на следующий релиз (на данный момент). Жду ваших предложений и всегда готов обсудить их в комментариях.

 

 

четверг, 3 мая 2012 г.

Компонент для работы с растровыми шрифтами

Продолжая работу над портом движка Flixel на Haxe, столкнулся с необходимостью оптимизации работы с текстом. Проблема заключается в следующем: стандартный класс движка FlxText сильно завязан на использование метода draw(), и при обновлении текста создается новый экземпляр класса BitmapData, еще одним недостатком является то, что для каждого такого текстового объекта создается свой экземпляр класса TileSheet (если в качестве целевой платформы установлен c++, neko или android). В общем видно, что такая реализация класса для отображения текста довольно неудачна и нужно искать другие решения. И тут на сцену выходят растровые шрифты -- каждый символ такого шрифта представляет собой по-сути простое изображение и работать с ними можно точно также, как и с обыкновенными изображениями. В наборе классов Flixel Power Tools как раз есть такой класс FlxBitmapFont и я его уже давно портировал, но в нем также присутствует довольно раздражающее меня ограничение -- он поддерживает только моноширинные шрифты (все символы таких шрифтов должны иметь одинаковую ширину), а мне же хотелось чего-нибудь более универсального. И недавно мне на глаза попался движок Pixelizer (упоминал его в одном из предыдущих сообщений), в котором очень понравилась реализация такого компонента: в нем уже был такой функционал, как изменение цвета шрифта, обводка и тени, поддержка многострочного текста и др. Встала задача по переводу этого добра на другие рельсы:
  1. Реализация в виде отдельного компонента, не завязанного ни на какой из движков -- такой класс нужен был для того, чтобы наконец-то закончить портирование прелоадера Flixel.
  2. Реализация в виде плагина для Flixel, которую можно использовать непосредственно в играх.
Самая первая версия порта была готова через 1-2 дня, но сразу же вылезли проблемы с производительностью: для отрисовки текста использовался метод draw(), позволяющий задавать тексту цветовую трансформацию и прочие параметры. Нужно было искать другой способ отрисовки. Подумав немного и посмотрев на реализацию спрайтов в Flixel, пришел к следующему решению: на входе имеем набор растровых изображений, представляющих собой исходные изображения символов растрового шрифта, а для того, чтобы отображать масштабированный и "окрашенный" текст создается дополнительный массив трансформированных изображений символов, таким образом, мы можем использовать уже гораздо быстрый метод copyPixels() (после такого преобразования нагрузка на процессор при отрисовке текста снизилась в 2-4 раза).
Завершив с оптимизацией, я приступил к реализации дополнительных "фишек":
  • настройка размера шрифта
  • настройка расстояний как между символами, так и между строками текста
  • настройка переноса слов
На это ушло еще несколько дней, скачать и посмотреть что получилось можно со странички репозитория - https://github.com/Beeblerox/BitmapFont
На данный момент там присутствуют три различные версии описываемого компонента:
  • кросс-платформенная версия под Haxe (данная версия используется в порте класса FlxPreloader). Работает на flash, c++ и neko; должно также работать  на iOS и Android, но не проверялось.
  • версия на AS3
  • версия для Flixel, также на AS3. В ней отсутствует возможность задания фона у текста, от этого функционала пришлось отказаться из-за проблем, которые возникнут при портировании на Haxe. Может быть, когда у метода drawTiles() класса TileSheet появиться возможность задавать масштаб тайлов по обеим осям (данный реквест можете помочь продавить в данной теме на форуме haxenme.org), я введу такой функционал, но пока оставлю так.
В каждой из папок есть примеры использования, так что проблем не должно возникнуть.
Версия для Flixel на Haxe находится в работе (на данный момент работает только под flash) и должна быть готова в течение недели (надеюсь, что так и будет :) ).

Напоследок расскажу как создать свой растровый шрифт, для этого вам понадобятся две вещи:
Пример изображения для растрового шрифта
  1.  Графический файл (обычно в формате png), содержащий изображения символов шрифта. Для того, чтобы программа смогла распознать границы изображений символов шрифта, изображение должно иметь фоновую заливку, а изображения символов не должны содержать данного цвета, плюс между символами дожен быть минимум 1 пиксел и каждый ряд изображений символов должен начинаться с одного уровня (см. рисунок выше) 
  2. Строку, содержащую символы, соответствующие изображению. Например, для приведенного выше изображения данная строка будет иметь вид: " !\"#$%&'()*+,-./" + "0123456789:;<=>?" + "@ABCDEFGHIJKLMNO" + "PQRSTUVWXYZ[]^_" + "abcdefghijklmno" + "pqrstuvwxyz{|}~\\"
Чтобы создать сам шрифт нужна всего одна строчка:
_font = new PxBitmapFont(fontBitmapData, fontString);
где fontBitmapData - изображение символов шрифта, а fontString - строка с символами шрифта.
Для создания текстового поля обязательными являются две строки:
_text = new PxTextField(_font); // непосредственно создание текстового поля
_text.setWidth(100); // задание ширины поля, по-умолчанию равна единице


Думаю, что разобраться со свойствами создаваемого таким образом текстового поля не составит особых затруднений (их названия говорят сами за себя и должны быть знакомы, если вы уже работали со стандартными текстовыми полями), поэтому на этом и заканчиваю. А если возникнут какие вопросы - то добро пожаловать в комменты :)

UPD: Стоило мне вчера написать, что не хватает в методе drawTiles() аргументов, задающих масштабные коэффициенты по обеим осям, как уже сегодня в svn-репозитории NME была добавлена эта возможность -- теперь каждому тайлу можно задавать матрицу 2d-преобразований, т.е. не только масштабы и поворот, но и отражение по оси, наклоны и т.д. Вот такие дела.