vovnet | Дата: Вторник, 26 Июня 2012, 13:29 | Сообщение # 1 |
почетный гость
Сейчас нет на сайте
| Box2D 2.1a Tutorial – Part 2 (Body) Предыдущие уроки: Part1
Итак, в прошлом уроке мы выяснили, что все тела в Box2D являются экземплярами класса b2Body, и создаются при помощи вспомогательных классов b2BodyDef, b2Shape и b2FixtureDef. В этом уроке мы как раз и рассмотрим классы b2BodyDef, b2Shape, b2FixtureDef, их свойства и методы.
Для наших экспериментов возьмем код-заготовку из предыдущего урока:
Code package { import Box2D.Collision.b2Bound; import Box2D.Collision.b2DistanceInput; import Box2D.Dynamics.b2World; import Box2D.Common.Math.b2Vec2; import Box2D.Dynamics.b2BodyDef; import Box2D.Dynamics.b2Body; import Box2D.Collision.Shapes.b2PolygonShape; import Box2D.Dynamics.b2Fixture; import Box2D.Dynamics.b2FixtureDef; import Box2D.Dynamics.b2DebugDraw; import Box2D.Dynamics.Joints.b2MouseJoint; import flash.display.MovieClip; import flash.display.Sprite; import flash.events.Event; [SWF(width = "800", height = "600", backgroundColor="#fafed6", frameRate = "30")] public class Main extends MovieClip { private const PIXELS_TO_METRE:int = 30; // коэффициент преобразования пикселей в метры private var _world:b2World; // игровой мир public function Main() { // создаем мир _world = new b2World(new b2Vec2(0, 10), true); /* * * Тут ваш код * * */ // отображаем все на экране var debugSprite:Sprite = new Sprite(); addChild(debugSprite); var debugDraw:b2DebugDraw = new b2DebugDraw(); debugDraw.SetSprite(debugSprite); debugDraw.SetDrawScale(PIXELS_TO_METRE); debugDraw.SetLineThickness(1.0); debugDraw.SetAlpha(1); debugDraw.SetFillAlpha(0.4); debugDraw.SetFlags(b2DebugDraw.e_shapeBit); _world.SetDebugDraw(debugDraw); // добавляем слушателя addEventListener(Event.ENTER_FRAME, update); } // end Main() public function update(e:Event):void { var timeStep:Number = 1 / 30; var velocityIterations:int = 6; var positionIterations:int = 2; _world.Step(timeStep, velocityIterations, positionIterations); // в версии 2.1 мы должны очистить силы _world.ClearForces(); // отрисовываем _world.DrawDebugData(); } // end update() } }
1. b2BodyDef — это геометрические свойства тел. Далее рассмотрим подробнее все свойства этого класса:
active:Boolean – определяет должно ли тело быть активным при старте. Если установить значение в false, то тело не будет реагировать на столкновения.
allowSleep:Boolean — установка значения этого свойства в false запретит объекту засыпать, когда оно находится в покое. Но это делать не рекомендуется в связи с большой нагрузкой на процессор.
angle:Number — начальный угол поворота тела в радианах.
angularDamping:Number — угловое торможение для снижения угловой скорости тела.
angularVelocity:Number — угловая скорость тела.
awake:Boolean — определяет бодрствует тело или спит при старте. Если установить false для динамического тела, то при запуске приложения это тело будет находится в состоянии покоя, даже будучи подвешенным в воздухе.
bullet:Boolean — устанавливается в true, если необходимо гарантировать, что это тело не пройдет насквозь другого тела.
linearDamping:Number — линейное торможение тела для снижения линейной скорости. Удобно использовать для имитации тела под водой, так как торможение в отличии от трения действует на тело не только в момент соприкосновения с другим телом, а постоянно.
linearVelocity:b2Vec2 — линейная скорость тела.
position:b2Vec2 — позиция тела в мире. Задается при помощь метода Set() принимающего координаты точки в которую подставится центр тела. Координаты относительно Х и Y задаются в метрах!
type:uint — тип тела. Может быть:
Cтатическим = 0 (или b2Body.b2_staticBody). Тело не реагирует при воздействии на него сил или других тел. Такие тела являются нерушимыми объектами.
Кинематическим = 1 (или b2Body.kinematicBody). Тело такое же как и статическое, но ему можно задать линейную и угловую скорость. Подходит для создания движущихся платформ, шестеренок и прочего.
Динамическим = 2 (или b2Body.b2_dynamicBody). Под эту категорию подпадают все остальные объекты, которые могут взаимодействовать между собой.
userData:* - здесь храним любые наши данные, например графическое отображение тела.
Итак, с геометрическими свойствами тела мы разобрались, так что теперь можем создать тело при помощи метода: CreateBody(def:b2BodyDef):b2Body — метод объекта b2World, который принимает объект b2BodyDef и возвращает объект b2Body.
Приведу пример:
Code var _world:b2World = new b2World(new b2Vec2(0, 10), true); // создаем мир var body:b2Body; // в этой переменной будет хранится тело var bodyDef:b2BodyDef = new b2BodyDef(); // создаем объект геометрических свойств тела bodyDef.type = b2Body.b2_dynamicBody; // указываем, что тело будет динамическим bodyDef.position.Set(8, 12); // задаем начальную позицию тела body = _world.CreateBody(bodyDef);
При создании тела, ссылка на объект b2BodyDef не сохраняется, а значит мы можем использовать этот объект для создания множества тел.
2. b2Shape — форма тела. Даже после того, как мы описали геометрические свойства тела и добавили его в мир, мы его не увидим, т. к. у тела нет формы. А без формы тело не может взаимодействовать с другими телами, поэтому давайте опишем его форму.
Тело может иметь форму многоугольника b2PolygonShape или окружности b2CircleShape.
Создаем окружность:
Code // Окружность var circle:b2CircleShape = new b2CircleShape(); bodyDef.position.Set(3, 3); circle.SetRadius(1); body = _world.CreateBody(bodyDef); fixtureDef.shape = circle; body.CreateFixture(fixtureDef);
При создании формы мы можем в конструктор передавать радиус окружности (в метрах), или же ничего не передавать, тогда радиус будет по умолчанию равен нулю. В данном примере я так и поступил. Радиус я указал позже, вызвав у окружности метод SetRadius(), с помощью которого можно задать его. Здесь я использую некий объект fixtureDef, на который пока не обращайте внимание, позже мы рассмотрим и его.
Создаем многоугольник:
Code // Многоугольник var dynamicBox:b2PolygonShape = new b2PolygonShape(); dynamicBox.SetAsBox(1, 1); fixtureDef.shape = dynamicBox; body.CreateFixture(fixtureDef);
Тут мы создаем новый объект типа многоугольник и с помощью метода SetAsBox() задаем ширину и высоту тела.
3. b2FixtureDef — объект этого класса позволяет объединить тело с его формой, а также задать ему некоторые физические свойства.
Итак, мы научились создавать тела, добавлять их в мир, а также создавать для тел форму. Но в Box2D тело и форма разные объекты, и чтобы объединить их в одно целое необходимо воспользоваться классом b2FixtureDef. У объекта этого класса есть свойство shape которому необходимо присвоить объект формы. А после, у объекта тела вызвать метод CreateFixture() в который необходимо передать наш объект типа b2FixtureDef.
Code // соединение тела и формы var fixtureDef:b2FixtureDef = new b2FixtureDef(); fixtureDef.shape = dynamicBox; body.CreateFixture(fixtureDef);
Для наглядности я нарисовал небольшую схемку: Мы начинаем с того, что создаем объект типа b2BodyDef, в котором описываем геометрические свойства тела. Далее у объекта типа b2World вызываем метод CreateBody(), который и создаст в мире тело. Но так как тело будет бесформенное, необходимо создать объект формы. На картинке я просто обозначил форму как Shape, а в реальности требуется создавать форму как окружность, многоугольник, либо же совокупность и того и другого (об этом в следующих уроках). После того как мы создали форму, нам необходимо прикрепить ее к нашему телу, которое находится в мире. Для этого мы создаем вспомогательный объект типа b2FixtureDef в свойствах которого указываем форму и другие физические свойства: трение, плотность, упругость. Теперь у нас есть форма с физическими свойствами, которую необходимо «надеть» на тело. С этой целью у тела вызываем метод CreateFixture() в который и передаем объект b2FixtureDef.
Теперь мы разобрали достаточно, чтобы создавать простые тела. Для закрепления полученных знаний небольшое задание: Отобразите принцип домино как на рисунке:
Скачать эту флэшку.
Следующий урок: Part3
Сообщение отредактировал vovnet - Вторник, 26 Июня 2012, 20:30 |
|
| |