Nape 2 — немного глубже в новшества фигур и тел

В новой версии API для фигур и тел значительно расширились.
Я не буду описывать все, выберу только те моменты, которые мне показались самыми значительными.

Фигуры (Shape)
Теперь фигуры можно двигать, вращать в теле как угодно, масштабировать и даже делать какие либо трансформации.
Появился метод copy, который делает копию фигуры, теперь будет значительно легче организовать пулл с фабрикой :)
И последний и возможно главный призер, это свойства для воды (fluidProperties). Да-да в новом нейпе есть, наконец то, вода! (об этом немного позже)
Еще одно упрощение было сделано. Из API удален метод updateShape, а его функциональность автоматизирована и скрыта от пользователя.

Тела (Body)
В телах также много изменений — было добавлено много новых свойств (напр. kinematicVel, kinAngVel, surfaceVel …), некоторые были переименованы.
Также добавлена целая куча методов, которые облегчают жизнь (напр. для работы с шейпами тела — те же повороты, масштабирования …, определения всевозможных импульсов и т.д.)
Остановлюсь на нескольких.

1. Свойство graphic.
Изменился тип этого свойства. Теперь это свойство имеет динамический тип. Для корректного просчета и отображения подразумевается, что передаваемый объект должен обладать свойствами x, y, а также rotate, который должен принимать градусы.
Но если это не так то смотрим на…

2. Новое свойство — graphicUpdate.
Это свойство типа Function, которому можно присвоить собственный хендлер обновления позиции и поворотов для графики.
Представьте, что вы пишете игру с помощью Stage3d. Для этого вы используете уже готовые фреймворки типа Starling, Genome2d или ND2D.
Напр. вы используете Starling. В этом фреймворке (как и у других названых) нету привычной иерархии DisplayObject.
Благодаря тому, что свойство graphic теперь динамического типа вы можете ему присвоить визуальный объект старлинга. А так как этот объект принимает для свойства rotation радианы вам нужно это отдельно обработать.
И вот вы пишите приблизительно такой код:

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; //Body использует радианы и старлинг объект тоже, потому ничего конвертировать не надо
}

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

3. Новое поле compound типа Compound.
Что это такое?
Compound - новый тип участника взаимодействий. До этого были только Shape и Body. (Есть базовый класс Interactor от которого наследуются Shape, Body, Compound).
Compound, это такое тело, которое может содержать другие тела (Body) и соединения.
Для чего это нужно? Например, для вашей игры вы создали машинку (напр. вот такую). Для этого вам надо по крайней мере три тела и четыре соединения. Вам надо как то менеджировать эту машинку. Если надо удалить машинку из мира, то надо удалять все тела и соединения. Для этого пишутся обычно врапера типа Actor и каким то образом обеспечивается хранение информации о телах и соединениях. Также пишется метод который будет удалять эти все тела из мира (так происходило в старой версии и так происходит (если я не ошибаюсь) в Box2d и теперь).
С новым типом Compound все меняется. Создаваемые тела и соединения для сложных физ объектов просто добавляются в Compound и потом вы работаете с ним как с единым тело.
Надо удалить машинку из мира? Нет проблем! Одним движение вы удаляете машинку полностью из мира. Надо переместить или повернуть машинку на сцене? Это делается на столько просто как будто работаете с одним Body.
Также, есть метод copy, который делает полною копию Compound со всеми составляющими.
Также, можно обрабатывать события взаимодействия между этими сложными телами.
Это тело мы еще рассмотрим в будущем.

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

Поделиться в соц. сетях

Опубликовать в LiveJournal
Опубликовать в Google Plus
  • Iktash

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

  • ggman

    Очень круто. Все сразу понятно. Когда продолжение? Хотелось бы больше узнать про соиденения.

  • VirtualMaestro

    Рад, что материал понятный :)
    Продолжение пишется потихоньку, некоторые моменты ждут уточнение от Луки, некоторые ожидают его окончательного решения по важным вопросам.
    Например, только вчера он реализовал и объявил о том, что убрал колбеки с движка и теперь обработка столкновений будет происходить только через хендлеры :)

  • ggman

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

  • Krauser

    Здравствуйте.
    Уж не знаю, ответите ли, пишу на удачу.
    Выискиваю способ, где описано, как создать тело какой-нибудь такой формы:
    http://cs311228.vk.me/v311228626/85f/AaTcllU0Eok.jpg

    Я довольно тщательно собирал информацию по построении тел в Nape на русском языке (с английской документацией у меня туго, как и с английским форумом Nape, куда я тщетно отписывался по тому же вопросу). Но везде натыкался на ресурсы как создавать простые квадраты, круги, треугольники, ромбы, прямоугольники или пентагоны.
    Сейчас 2013′й, вышла новая версия Nape, и ситуация для новичка как я, который копает с моего же фронта — усложнилась в разы. Нестандартные фигуры, как я выяснил, оказывается, в новой версии прописываются по-другому. Поэтому я стал терпеть фиаско за фиаско, натыкаясь на старье, пытаясь найти нужную информацию по вопросу.
    Вы не могли бы помочь мне измученному с этим?

    То есть, допустим, я создаю квадратное тело:

    var sampleBody : Body;
    sampleBody=new Body(BodyType.DYNAMIC,new Vec2(x,y));
    var block:Polygon = new Polygon(Polygon.box(60, 60));
    sampleBody.shapes.add(block);

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

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

    • VirtualMaestro

      Привет. Быстренько накидал и получилось, что то типа так (раньше не пробовал, но думаю, что правильно).

      Ссылка на код: http://pastebin.com/e0pA7ZkZ

      И вот что получилось

      • Krauser

        Спасибо, что так быстро отозвались!
        Флеш отписывает ошибку:
        … 1046: Type was not found or was not a compile-time constant: Vec2.

        Не принимает эту строчку:
        var vertecies:Vector. = new [

        Код заношу во FlashDevelop — синтаксис строки, вроде, подсвечивает как следует, то есть, знает о чем речь идет. Но все-равно подозреваю, что «недоимпортнул» нужную библиотеку. Не могли бы вы скинуть, что у Вас в imports?

        • VirtualMaestro

          Vec2 (с большой буквы) это класс нейпа представляющий вектор — nape.geom.Vec2

          • Krauser

            Уф, спасибо большое. В моем проекте ошибка не пропала, но если создавать с нуля — Ваша фигура появляется, все отрабатывает хорошо. Видимо, что-то в моем коде блокирует Vec2.

            Vec2 я писал с большой буквы. Видимо ваша система комментариев подхватывает то, что заключено в угловые скобки и меняет символы на маленькие. Она и в конце закрывающие тэги поставила, смотрю.

            Вы, случаем, не знаете способа построить фигуру в обход Vec2? Упорно конфликтует.

          • VirtualMaestro

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

          • Krauser

            разобрались, слава богу. видимо, конфликтовало то, что у меня по умолчанию компилирует под 9′й флеш-плеер. 10′й нормально Vec2 берет

            вообще, и под девятый проходит, если строку
            var vertecies:Vector. = new [
            заменить на задание массива:
            var vertecies:Array = [

            ну, главное, заработало
            спасибо большое, еще раз! успехов Вам!

          • Krauser

            Можно еще поинтересоваться, как, с таким вариантом построения тела, ему физические свойства можно присваивать? Такие как эластичность, сила трения и т.д.

            Всмысле, с примитивами, я пользовал этот способ:

            napeBallBody=new Body(BodyType.DYNAMIC,new Vec2(x,y));
            var circle1:Circle=new Circle(19);
            circle1.material.elasticity=0.5;
            circle1.material.density=1;
            napeBallBody.shapes.add(circle1);

            Со способом, который предложили Вы, за любое вмешательство в код своими *.material.*-приставками, я получаю ошибку:
            1119: Access of possibly undefined property material through a reference with static type nape.phys:Body.

            Полагаю, что изменения нужно внести в цикл:

            while (listIterator.hasNext())
            {
            geomPoly = listIterator.next();
            body.shapes.add(new Polygon(geomPoly));
            }

            Конкретнее в строчку:
            body.shapes.add(new Polygon(geomPoly));

            Какие вот, и как, чтобы правильно — ума не приложу, теряюсь. Помогите, пожалуйста.

          • Krauser

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

          • VirtualMaestro

            в строке

            body.shapes.add(new Polygon(geomPoly));

            вторым параметром добавлять материал (для каждого шейпа создавать новый или если нужен одинаковый для всех создать вне цикла и присваивать каждому шейпу)
            Пример:

            body.shapes.add(new Polygon(geomPoly, new Material(0.1, 2.0, 3.0, 4, 0.01)));

          • Krauser

            спасибо :)