Быстрый, удобный и мощный физический движок с открытым исходным кодом. Под катом — ссылки, небольшой туториал и пример использования.
Ссылки
Сам проект Box2D находится по этому адресу — http://www.box2d.org/, там можно почитать о его возможностях, пообщаться на форуме и т.д.
С него был сделан AS3 порт, домашняя страница — http://box2dflash.sourceforge.net/. На ней выложен клип, показывающий возможности этого движка. Кстати, всех с пятницей )
Использование (самое базовое)
1. Создаём «мир», все расчёты происходят только в пределах этого мира, объект, выходящий за его границы, выпадает из расчётов. Так что делаем с запасом (WIDTH и HEIGHT — размеры окна):
// world bounding box
var worldAABB : b2AABB = new b2AABB();
worldAABB.lowerBound.Set(-WIDTH, -HEIGHT);
worldAABB.upperBound.Set(2*WIDTH, 2*HEIGHT);
// create world. zero gravity + use "sleeping" for objects
m_world = new b2World(worldAABB, b2Vec2.Make(0, 0), true);
* This source code was highlighted with Source Code Highlighter.
2. Добавляем объект в мир.
Объект характеризуется двумя составляющими.
Первая — геометрическое представление объекта (его «поверхность»). Каждый объект может состоять из нескольких shape, которые представляют собой выпуклые многоугольники или окружности (но ничего не мешает расширить базовый shape и написать свой собственный).
Здесь же задаётся плотность, сила трения и т.д.
// shape definition
var bodyShapeDef : b2PolygonDef = new b2PolygonDef();
// as rectangle
bodyShapeDef.SetAsBox(w/2, h/2);
// density
bodyShapeDef.density = 1.0;
// friction
bodyShapeDef.friction = 0.3;
* This source code was highlighted with Source Code Highlighter.
Вторая — сам объект, его положение, масса, момент инерции и т.д.
Описание объекта:
// object definition
var bodyDef : b2BodyDef = new b2BodyDef();
// world position
bodyDef.position.Set(xc, yc);
// linear "friction with world"
bodyDef.linearDamping = 0.3;
// angular "friction with world"
bodyDef.angularDamping = 0.3;
* This source code was highlighted with Source Code Highlighter.
Создание объекта (он автоматически регистрируется в мире). Задание ему ранее созданного геометрического представления, и (очень удобно) автоматический расчёт всех физических параметров на основе его плотности и формы.
// create object from definition
var body : b2Body = m_world.CreateBody(bodyDef);
// create object shape from shape definition
body.CreateShape(bodyShapeDef);
// calculate mass, center of mass and inertia
// based on shape
body.SetMassFromShapes();
* This source code was highlighted with Source Code Highlighter.
Есть ещё третья (необязательная) составляющая объекта — его представление на экране. На начальных этапах разработки можно воспользоваться классом b2DebugDraw, который показывает все объекты, связи между ними и т.д. Но как связать, к примеру собственный MovieClip и физический объект?
Самая часто используемая практика — воспользоваться полем userData созданного объекта.
Запоминаем экранное представление в этом поле:
// save screen object in userData field
body.SetUserData(bodyDisplayObject);
* This source code was highlighted with Source Code Highlighter.
3. Эмуляция
Тут всё просто. У мира есть функция Step, которая принимает время шага в
// calculate physics
// using 10 steps of physics for each frame
m_world.Step(dt, 10);
// loop for all physic objects
for(var body : b2Body = m_world.GetBodyList(); body; body = body.GetNext())
{
// if userData is not a shape, then skip this object
if(!(body.GetUserData() is Shape))
continue;
// update screen object to be equal physical object
body.GetUserData().x = body.GetPosition().x;
body.GetUserData().y = body.GetPosition().y;
body.GetUserData().rotation = body.GetAngle() * 180.0 / Math.PI;
}
* This source code was highlighted with Source Code Highlighter.
Пример
Написал небольшое приложение в попытках создать змею. 80 прямоугольников связаны попарно RevoluteJoint'ами, с ограничением вращения в +-20 градусов. При движении мышкой головной сегмент змеи получает импульс в направлении курсора, в результате вся змея ползёт. Также в мире расставлены объекты, чтобы было вокруг чего ползать.
По клику приложение переключается между собственным рисованием и b2DebugDraw.
приложение — http://www.rexxar.ru/snake/
исходники — http://www.rexxar.ru/snake/src.zip
Ещё один тест — показывает точки соударений. По клику создаётся новый прямоугольник и падает на землю.
приложение — http://www.rexxar.ru/phys/.
Вывод
Разбор движка и написание примеров заняло буквально несколько часов, очень простой, удобный, быстрый и мощный инструмент для эмуляции физики. Буду использовать.