1. Что такое Haxe?
2. Что такое Flixel?
- отображение на экране тысяч объектов;
- объединение объектов в группы (например, для обработки столкновений между группами);
- встроенная простая система столкновений между объектами;
- системы частиц;
- создание уровней с помощью tilemap’ов (для этого существует ряд редакторов, лучшим считается dame-editor);
- дополнительные классы для отображения текста, работы с сохранением игр, скроллинга игрового мира;
- классы для работы с клавиатурой и мышью;
- утилиты для работы с цветом и геометрическими преобразованиями.
В число «продвинутых» особенностей движка входят:
- возможность записи и воспроизведения игрового процесса;
- встроенный визуальный отладчик;
- система камер, позволяющая создавать игры в режиме split-screen (и не только);
- функция поиска пути в плиточном мире;
- простая система многократного использования объектов (object recycling).
3. Flixel + Haxe = HaxeFlixel
Началом следующего этапа в создании порта стала новость о выходе новой версии библиотеки NME 3.0 (начало октября), которая обещала более простой процесс кроссплаторменной разработки и множество улучшений в работе. Почитав на официальном форуме в списке рассылки о преимуществах новой версии этой библиотеки, решил интегрировать их, чтобы была возможность писать игрушки под мобилы (так, ради интереса, смартфона-то у меня и нет). Это было несложно: те места, которые не хотели компилироваться на c++, я просто комментировал так, чтобы они исполнялись только на flash-платформе. Тогда из порта пришлось выбросить сохранения игр. Где-то за неделю я управился и оставил на форуме haxenme.org сообщение о своем порте. Ответы не порадовали: для меня оказалось новостью, что операции с битмапами (а они являются основой системы рендеринга flixel) выполняются на cpu (а он, на телефонах слабоват) и простые демки дико тормозили (ну вот такой я нуб-самоучка). Кроме опроса на форуме, проводились тесты и на компьютере, они тоже дали неутешительный результат – программы, скомпилированные под с++, работали даже медленнее, чем во flash-player’e. После этого начались поиски наиболее оптимальных методик для работы с графикой. Слава Богу, что эту работу до меня уже сделали члены haxe-сообщества: для быстрой обработки графики предлагалось использовать операции drawTriangles и drawTiles. С первой Вы, скорее всего, знакомы, т.к. она присутствует во флэше (для тех, кто не знает: с помощью этой команды можно нарисовать треугольник, используя в качестве «текстуры» любую битмапдату). Вторая операция – нововведение в NME, она аналогична drawTriangles, но отрисовывает уже прямоугольник (пока что работает только в c++). Первоначальная реализация данного метода была довольно негибкой: можно было задавать только положение такого прямоугольника, поэтому я решил использовать drawTriangles и посвятил пару недель экспериментированию. Но результаты меня не устраивали, ведь drawTriangles не позволяет задавать цветовую трансформацию отрисовываемой текстуры, а я очень этого хотел (иначе пришлось бы сделать еще одно «обрезание» моему порту). И тут вышел первый релиз-кандидат NME 3.1, в котором появилась возможность кроссплатформенной работы с LocalSharedObject (т.е. вернулась возможность сохранять игры на всех поддерживаемых платформах), улучшенная работа с ассетами (шрифтами, графическими, звуковыми и текстовыми файлами), а также (барабанная дробь) расширение функционала метода drawTiles – теперь он позволяет задавать тайлам масштаб, поворот, прозрачность и цветовую трансформацию. Радости моей не было предела, начался новый этап экспериментирования с этим методом. С нюансами его работы разобраться удалось не сразу. Оказалось, что работать с ним нужно аккуратно, т.к. если пытаться использовать одну и ту же битмапдату в качестве «текстуры» для двух разных tileSheet’ов (объектов для отрисовки тайлов), то «волшебным» образом пропадали прозрачность и цветовые трансформации. Но оно и к лучшему, т.к. это заставило более внимательно относиться к ресурсам, не создавая «дублирующих» объектов. Таким образом, я пришел к идее класса-менеджера, отвечающего за работу всех tileSheet’ов – он является центром всей новой системы рендеринга. Если в оригинальном Flixel’е каждый объект непосредственно рисуется на битмапдате камеры, то в новой системе каждый объект передает в менеджер свои данные (положение, поворот, масштаб и т.д.), и только после того, как все объекты передадут свои данные, идет отрисовка всех тайлов. С этой особенностью связана еще одна проблема – проблема сортировки глубины отрисовки объектов. Если в оригинальном Flixel’е порядок отрисовки можно изменить отсортировав массив самих объектов (отрисовка ведется в порядке их расположения в таком массиве), то в новой системе объекты отрисовываются пакетно, т.е. все объекты, имеющие в качестве графического представления одну и ту же битмапдату, отрисовываются за одну операцию. Эту проблему удалось решить частично за счет:
- возможности отдельной сортировки объектов, делящих между собой одну и ту же битмапдату (т.е. уже имеющимися средствами flixel);
- а также возможности сортировки самих tileSheet’ов в менеджере (для этого были добавлены соответствующие методы для получения текущей глубины отрисовки tileSheet’а и ее изменения).
Разработав основу новой системы, я провел несколько тестов и увидел значительный прирост в производительности, т.к. теперь операции отрисовки в с++ программах стали осуществляться с помощью gpu. Убедившись, что теперь можно показать предварительный результат работы, я снова написал на форум; отзывы показали, что работа не была потрачена впустую (это было в начале декабря). Эти отзывы придали мне новых сил, и я с удвоенным рвением продолжил доработку системы рендеринга, попутно заборов еще парочку багов.
Теперь немного о грустном. К сожалению, в NME еще не все так гладко (хотя в последнее время библиотека очень сильно преобразилась в лучшую сторону), например, есть некоторые проблемы с клавиатурой, когда нажатия на разные клавиши выдают одинаковые значения кодов (keyCode), поэтому пока что неправильно работают клавиши цифрового блока, а также F1-F12. Также для звука на с++ приходиться конвертировать файлы в wav-формат (а это дополнительный объем), если же использовать mp3, то одновременно получается воспроизводить только один звук. Кроме того, под c++ реализован еще не весь flash api, и мне пришлось писать свою упрощенную реализацию метода hitTest для битмапдаты. Некоторые методы класса BitmapData работают не так, как на флэше, из-за чего возникают артефакты – здесь тоже пришлось писать свою реализацию (для зеркального отражения битмапдаты).
Но, как я уже сказал раньше, библиотека постоянно улучшается, и я надеюсь, что эти проблемы скоро уйдут в небытие.
Ах да, чуть не забыл дать ссылку на репозиторий проекта: https://github.com/Beeblerox/HaxeFlixel
А также скомпилированная на c++ демка (под Windows): https://github.com/downloads/Beeblerox/HaxeFlixel/ModeDemo20122011.zip