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

# пост обновлён (см. ОБНОВЛЕНО #3)

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

Некоторые из вас уже наверняка пробовали использовать быстрейший 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, надо:
1. Скопилировать caxe из исходников (лишь один раз).
2. Скопилировать flib из исходников (лишь один раз).
3. Использовать препроцессор caxe на .cx исходниках, чтобы получить haxe (.hx) исходники (каждый раз при компиляции swc).
4. Скомпилировать haxe исходники в swc файлы (каждый раз при компиляции swc).

Исходнии Nape’а обновляются довольно регулярно, по-этому держать эти swc синхронизированными с исходниками я не буду, при желании, Вы сможете сами всё скомпилировать, к тому же возможно, поддержка сторонних рендер-фреймворков будет реализована официально!

ОБНОВЛЕНО:
Что касается ручного контроля отрисоки DisplayObject’ов Starling’а, то это делается весьма просто:

// где-нибудь в вашем коде
var someBody:Body = new Body(BodyType.DYNAMIC, new Vec2());
someBody.userData = someStarlingSprite;

// в каком-нибудь игровом цикле, например, там, где вы вызываете Space.step()
var len:uint = _napeSpace.bodies.length;
var i:uint;
var body:Body
var sprite:Sprite;

for (i = 0; i < len; i++ )
{
body = _napeSpace.bodies.at(i);
sprite = (body.userData as Sprite);
sprite.x = body.position.x;
sprite.y = body.position.y;
// ограничиваем значение +-360тью и
// конвертируем градусы в радианы (в старлинге поворот в радианах)
sprite.rotation = (body.rotation*180/Math.PI)%360;
}

Вот и все!
Этот подход может быть более медленным по сравнению с позиционированием и вращением графики прямо в Body, т.к. в данном случае вам придётся пробегаться по всем экземплярам Body и вызывать некое колдичество методов и геттеров каждый кадр,.
Однако, этот способ позволяет использовать последние официальные Nape swc с любыми сторонними рендер-фреймворками, такими, как Starling, и это здорово!

ОБНОВЛЕНО #2
Nape только что обновился, и теперь с ним можно использовать DisplayObject’ы Staling’а вот так:

//...
body.graphic = starling_display_object;
body.graphicUpdate = _updateGraphic;
//...
private function _updateGraphic(b:Body)
{
b.graphic.x = b.position.x;
b.graphic.y = b.position.y;
b.graphic.rotation = b.rotation; //оставляем радианы, т.к. старлинг их и использует
}

Lee Brimelow недавно сделал новый туториал «Starling Physics Using Nape» где он демонстрирует этот подход на примере проекта с падающими мячами. Спасибо, Lee!

Спасибо автору Nape, Luca Deltodesco!

ОБНОВЛЕНО #3
Из-за найденного бага во Flash Player Runtime (http://jpauclair.net/2012/02/25/epic-memory-track-down/), строго рекомендуется переписать код метода _updateGraphic таким образом:

//...
body.graphic = starling_display_object;
body.graphicUpdate = _updateGraphic;
//...
private function _updateGraphic(b:Body)
{
var gr:DisplayObject = b.graphic;
gr.x = b.position.x;
gr.y = b.position.y;
gr.rotation = b.rotation; //оставляем радианы, т.к. старлинг их и использует
}

Это обезопасит вас от того бага и не позволит памяти в вашем приложении циклично расти и очищаться.

Комментарии

Nape и Starling вместе? Это возможно! — 2 комментария

  1. Лучше всего предложить это изменение самому автору. Он человек вменяемый и вполне возможно примет твое изменение.

  2. Да, мы обсуждаем как сделать лучше, чтобы всем было хорошо =)