Erіn Catto - Box2D v 2 стр 6.

Шрифт
Фон

После выполнения расчета шага физики можно обработать все тела и соединения. Скорее всего, вы будете проверять позиции тел, чтобы иметь возможность обновить позиции объектов в игре и прорисовать их на экране. Можно выполнять расчет шага физики в любом месте игрового цикла, но следует быть осторожным с порядком выполнения операций. Например, если необходимо в текущем кадре создать новое тело и сразу проверить пересечение объектов с ним, то нужно сначала создать тело, расположить его в нужном месте мира, запустить расчет шага физики, и только потом проверять произошло ли столкновение.

Как уже обсуждалось в уроке Heiioworid, следует использовать фиксированную длительность шага. Использование больших шагов повысит производительность в приложениях с низкой частотой кадров. Но не стоит использовать шаг длиннее 1/30 секунды. Обычно 1/60 секунды достаточно для высококачественного моделирования.

Количество итераций определяет, сколько раз будут произведены расчеты над всеми телами и соединениями в мире. Большее число итераций всегда обеспечивает лучшее качество моделирования. Но не стоит сочетать маленький шаг с большим количеством итераций. 60Гц (Герц) и 10 итераций гораздо лучше 30Гц и 20 итераций.

Примечание переводчика

Дело здесь в том, что при делении очень маленького числа (длины шага) на очень большое (кол-во итераций) мы кроме всего прочего можем вообще ноль получить.

Пример погрешности при работе с маленькими числами:

float А = 0.0001f; int В = А*10000;

В MSVS2008 на стандартных настройках В равно 0 а совсем не 1.

kkray

4.3.2. Просмотробъектовмира

Как упоминалось ранее, мир является "контейнером" для всех объектов и соединений. Поэтому, из мира можно получить список всех тел и соединений мира, а затем сделать что-нибудь с каждым из них. Например, следующий код заставляет все тела "проснуться":

for (b2Body* b = myWorld->GetBodyList(); b; b = b->GetNext()) {

b->WakeUp() ; }

К сожалению, в жизни не все так просто. Например, следующий вариант кода будет работать неправильно:

for (b2Body* b = myWorld->GetBodyList(); b; b = b->GetNext())

{

GameActor* myActor = (GameActor*)b->GetUserData(); if (myActor->IsDead() )

{

// ОШИБКА: после этой операции GetNext возвратит мусор

myWorld->DestroyBody(b); } }

В этом коде все будет работать правильно только до момента удаления тела. После удаления тела, указатель на следующее тело (который хранится внутри тела) станет неправильным. Поэтому функция b2Body::GetNext() вернет указатель на мусор. Во избежание этого, необходимо сохранять указатель на следующее тело перед удалением, как в примере ниже.

b2Body* node = myWorld->GetBodyList(); while (node)

{

b2Body* b = node;

node = node->GetNext();

GameActor* myActor = (GameActor*)b->GetUserData(); if (myActor->IsDead())

{

myWorld->DestroyBody(b);

} }

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

b2Body* node = myWorld->GetBodyList(); while (node)

{

b2Body* b = node;

node = node->GetNext();

GameActor* myActor = (GameActor*)b->GetUserData(); if (myActor->IsDead())

{

bool otherBodiesDestroyed = GameCrazyBodyDestroyer(b); if (otherBodiesDestroyed)

{

node = myWorld->GetBodyList();

} } } Здесь, функция GameCrazyBodyDestroyer производит удаление тела и/или других тел,

поэтому, если удаляется несколько тел, то указатель node на следующее тело может оказаться неправильным и надо начинать просмотр тел с начала.

4.3.3. ААВВ запросы

Иногда требуется определить все фигуры находящиеся

в определенном регионе. Класс b2World содержит такую функцию и скорость ее работы высока. Функция принимает в качестве параметров ААВВ в мировых координатах и возвращает массив всех фигур, которые пересекаются с ААВВ (или находятся полностью в нём). Слово "пересекаются" не совсем правильно, так как проверка на пересечение происходит между ААВВ региона и ААВВ самих фигур. Например, следующий код находит все тела находящиеся в ААВВ и будит их.

Ь2ААВВ aabb;

aabb.lowerBound.Set(-1.Of, -1.Of); aabb.upperBound.Set(1.Of, 1.Of); const int32 k_bufferSize = 10; b2Shape *buffer[k_bufferSize];

int32 count = myWorld->Query(aabb, buffer, k_bufferSize); for (int32 1=0; 1 < count; ++1)

{

buffer[1]->GetBody()->WakeUp();

}

Глава 5. Тела

Содержание

5.1. О телах 5.2. Определение тела 5.2.1. Масса 5.2.2. Позиция и угол 5.2.3. Торможение 5.2.4. Параметры сна 5.2.5. Снаряды 5.3. Фабрика тел 5.4. Использование тел 5.4.1. Данные о массе 5.4.2. Информация о состоянии тела 5.4.3. Положение и скорость 5.4.4. Силы и импульсы 5.4.5. Преобразование координат 5.4.6. Списки

5.1. Отелах

У тел есть положение и скорость. К ним можно применять силы, моменты и импульсы. Тела могут быть статичными или динамичными, статичные тела никогда не перемещаются и не взаимодействуют с другими статичными телами.

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

Ваша оценка очень важна

0
Шрифт
Фон

Помогите Вашим друзьям узнать о библиотеке