воскресенье, 15 мая 2011 г.

Урок 16. Box2d

   Привет! Я уже говорил, что изучаю box2d, но урок по нему не написал, да и вообще я последнее время ничего не писал в блог. Так что попробую рассказать основные принципы создания игр на физическом движке box2d.
    Box2d – абсолютно бесплатный, скачать его можно с официального сайта, там над демкой есть большая кнопка скачать. Там же можно почитать документацию, лучше сразу повесить эту ссылку в закладки т.к. при изучении Вам скорее всего она понадобится много раз. Но перейдём к практике.
    Значит так, все начинается с физического мира, туда мы будем добавлять тела и всякие физические штуки. Создаётся мир так:


gravity=new b2Vec2(0,9.8);
world = new b2World(gravity,true);

Всё! Gravity – это вектор гравитации, а в параметрах мира, корме гравитации мы указали ещё что тела могут “спать”. Это значит, что когда новых контактов с телом не возникает, то оно перестаёт выполнять какие-то расчёты, и игра будет жрать меньше памяти.
    Дальше нам нужно обновление мира, просто вешаем слушатель:

addEventListener(Event.ENTER_FRAME, UpdateWorld);
public function UpdateWorld(e:Event):void
{
world.Step(1 / 30, 10, 10);
…
}

Это очень удобно т.к. если потребуется сделать паузу, то достаточно просто убрать этот слушатель. Параметры 1 / 30, 10, 10 лучше оставить как есть, что они означают, можете почитать в документации. Я написал после world.Step многоточие т.к. там обычно обновляют юзердату тел. Юзердата (userdata) – это мувиклип (точнее содержащая его переменная) физ. тела, то есть в этой функции мы будем обновлять сам мир и обновлять визуальные тела, например, я вместо многоточия обычно пишу что-то такое:

for (var bb:b2Body = world.GetBodyList(); bb; bb = bb.GetNext()) {
var ud=bb.GetUserData();//UserData
if (ud is box){
ud.x=bb.GetPosition().x*pixels_in_a_meter;
ud.y=bb.GetPosition().y*pixels_in_a_meter;
ud.rotation=bb.GetAngle()*(180/Math.PI);
}
else if(ud is …
}

* pixels_in_a_meter=30, но об этом чуть позже.
То есть мы перебираем все физические тела, записываем в переменную юзердату и смотрим, если это коробка, то изменяем координаты и угол поворота.
    Кагбе с этим всё. Уроков по box2d over9000, так что разберётесь)) Но по ходу создания физических игр я написал себе бокс2д хелпер. Это класс, который создаёт тела практически в одну строчку. Я его писал для себя так что не надо меня увольнять из гугла.
ВОТ ОН!!!1
    Как им пользоваться? О_о
Я всё делаю в четыре строки, например, создадим шарик:

var bodyDef=box2dHelper.createBodyDef(100, 50, 2);//x(в пикселях), y(в пикселях), тип
var shape=box2dHelper.createCircleShape(50);//радиус(в пикселях)
var fixtureDef=box2dHelper.createFixtureDef(1, 0.1, 0.1, shape);//плотность,трение, упругость, фигура
var Body=box2dHelper.createBody(world, bodyDef, fixtureDef, 20, this);//мир, определение тела, определение фикстуры, поворот(в градусах), юзердата.

Ну, в комментариях всё написано. Только остаётся непонятным что же такое тип.
    0 – статический, не двигается.
    1 – кинематик, на него действуют силы только те, которые ты сам ему задашь (Прекрасно подходит для создания лифтов, т.к. не действует гравитация и вес пассажира).
    2 – динамичный, всё по нормальному, действуют все силы, ну в общем как в нашем мире)
И ещё я уточнял, что x, y и радиус указываются в пикселях, почему? Если Вы почитаете где-нибудь уроки по box2d, то обязательно встретите такое, что значения в пикселях делят на 30 или реже на 60. Дело в том, что все измерения box2d делает в метрах. И для реалистичности люди делят пиксели на 30. А при переводе из box2d’шных – умножают (чуть выше у меня использовалась переменная pixels_in_a_meter=30, это как раз и есть перевод).
Ну, вроде как всё. Я уже оставлял эту ссылку, но напишу ещё раз лучший блог по box2d.
Cheerio!

2 комментария: