Статьи по c++

C++ Box2D в двух словах

В этой статье описывается библиотека Box2D для C++, которая используется для моделирования физики в реальном времени в 2D играх.

Физика 2d с помощью библиотеки Box2d

Box2d – это библиотека, написанная на C++, которая позволяет создавать очень реалистичные симуляции двухмерного мира.


Его преимущества – скорость и тот факт, что его можно использовать без каких-либо (выдающихся) навыков физики 😛
Он также имеет порты для других языков (включая Java, JavaScript и Flash).

С помощью Box2d было написано множество игр, включая очень популярную Angry Birds! (Когда вы немного узнаете о боксе, вы поймете, что они вовсе не так уж усердно над ним работали. Все благодаря Box2d!).

Библиотеку можно скачать отсюда: https://code.google.com/p/box2d/downloads/detail?name=Box2D_v2.3.0.7z&can=2&q=

Более новые версии библиотеки могут быть размещены на других серверах.

Несколько базовых определений

  • Жесткое тело – тело, которое не может изменить свою форму. Все тела, моделируемые Box2d, являются жесткими телами.
  • ограничение (сустава) – действие, которое ограничивает движение тела в той или иной степени
  • Статическое тело – тело, не имеющее массы (или имеющее бесконечную массу). На него не действуют никакие силы (включая гравитацию). Он сталкивается с динамическими телами. Он не может самостоятельно изменить свое положение.
  • Кинематическое тело – тело, не имеющее массы (или имеющее бесконечную массу). На него не действуют никакие силы (включая гравитацию). Он сталкивается с динамическими телами. Когда ему придается скорость, он не меняет своей скорости.
  • Динамическое тело – “нормальное” тело. Оно имеет массу, на него действуют все силы, оно сталкивается со всеми другими телами

Ваша первая симуляция!

Простейший пример симуляции Box2d.

Программа имитирует падение блока на платформу, висящую в воздухе.

Обсуждайте в комментариях.

#include <Box2d/Box2d.h> // прикрепляем заголовок // не забывайте о правильных либах! int main() { b2World world( b2Vec2( 0.0f, - 10.0f ) ); // создадим мир с гравитацией 10, направленной вниз. //// // теперь мы создадим "землю" как статичное тело - она будет "висеть" на месте b2BodyDef groundDef; // тела по умолчанию статичны groundDef.position.Set( 0.0f, - 10.0f ); // регулировка положения тела b2Body * ground = world.CreateBody( & groundDef ); // здесь мы создаем тело. Ему еще не присвоена форма. b2PolygonShape groundShape; // и поэтому мы делаем его groundShape.SetAsBox( 100.0f / 2, 20.0f / 2 ); // и задается в виде прямоугольника со сторонами 100 и 20 ground->CreateFixture( & groundShape, 1.0f ); // ...а затем подключаем его к телу. Второй параметр - плотность. //// // мы создаем падающий "блок" как динамическое тело - он сможет нормально двигаться и падать b2BodyDef boxDef; boxDef.type = b2_dynamicBody; // нам нужно сообщить Box2d, что тело должно быть динамическим boxDef.position.Set( 0.0f, 4.0f ); // как и прежде b2Body * box = world.CreateBody( & boxDef ); // любой b2PolygonShape boxShape; boxShape.SetAsBox( 2.0f / 2, 2.0f / 2 ); // как и раньше // Далее мы создадим форму для блока // мы хотим установить дополнительные параметры, такие как трение, поэтому нам нужно использовать более длинный метод, чем раньше b2FixtureDef boxFixDef; // создаем определение фикции (фрагмента тела) boxFixDef.shape = & boxShape; // задаем форму... boxFixDef.density = 1.0f; // ... плотность... boxFixDef.friction = 0.3f; // ... и трение box->CreateFixture( & boxFixDef ); // создаем фикцию. // Отлично, у нас готовы все элементы нашей симуляции! //// float time = 1.0f; // наш мир на секунду смоделирует int steps = 100.0f; // разделим симуляцию на 100 шагов float timeStep = time / steps; // поэтому мы будем обновлять физику каждые 1/100 секунды.. // Эти два значения влияют на точность моделирования. Чем больше число, тем точнее будет физика, но тем медленнее int velocityIt = 8, positionIt = 3; // Автор Box2d рекомендует значения 8 и 3, поэтому мы не будем их менять // Ну, вот и все.! for( int i = 0; i < steps; i++ ) { world.Step( timeStep, velocityIt, positionIt ); // вот волшебная линия. Вот симуляция нашего мира // мы используем уже рассчитанные значения b2Vec2 pos = box->GetPosition(); // получаем положение блока printf( " Шаг %i : %4.2f, %4.2f", i, pos.x, pos.y ); // и распечатываем его } // и все. Класс b2World сам позаботится об удалении наших творений:) }
Code language: PHP (php)

Результат должен быть примерно таким:

Шаг 0 : 0.00, 4.00 Шаг 1 : 0.00, 3.99 Шаг 2 : 0.00, 3.98 ... Шаг 97 : 0.00, 1.25 Шаг 98 : 0.00, 1.13 Шаг 99 : 0.00, 1.01
Code language: CSS (css)

Только эта строка требует обсуждения:

groundShape.SetAsBox( 100.0f / 2, 20.0f / 2 ); // и задается в виде прямоугольника со сторонами 100 и 20
Code language: JavaScript (javascript)

Ну, метод SetAsBox() берет половину длины сторон прямоугольника. Об этом следует помнить.

Как работает Box2d?

Box2d-симуляция представлена миром – класс b2World.

К каждому миру можно добавить тела – класс b2Body (и привязки, но об этом подробнее позже).

Каждое тело состоит из так называемых фикстур – класс b2Fixture

Фигуры – это разные части одного тела. Им можно приписать трение, плотность и сопротивление.

Кроме того, каждый рисунок имеет свою собственную форму.

Фигуры в одном теле не могут перемещаться относительно друг друга.

Это означает, что фикции, прикрепленные к одному телу, движутся вместе.

Все классы Box2d имеют суффикс b2.

Box2d основан на концепции так называемой фабрики.
Это означает, что схема создания ребенка будет выглядеть следующим образом:

Owner wl; // будущий владелец объекта cos classDef cosDef; // класс, содержащий все параметры, необходимые для создания класса Class // заполнение полей cosDef Class * cos = wl.addClass( cosDef ); // и здесь владелец выделяет и создает новый объект Class, используя значение из cosDef //... wl.destroyKlasa( cos ); // после этого владелец уничтожает и разбирается с этим объектом
Code language: JavaScript (javascript)

Симуляция Box2d не является “непрерывной”, а аппроксимируется в дискретные моменты времени с помощью функции b2World::Step().
Обновляет симуляцию на заданное время (приращение времени с момента предыдущего вызова)

Итак, общий план программы, использующей Box2d, выглядит следующим образом:

b2World world( /*...*/ ); // добавление тел, фикций и связей // инициализация других ресурсов программы while( /*...*/ ) // основной цикл { float deltaTime = /*...*/; // приращение времени (в секундах) world.Step( deltaTime, /*...*/ ); // Остальная часть логики программы/игры, рендеринг, обработка событий и т.д. }
Code language: JavaScript (javascript)

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *