Nano Hash - криптовалюты, майнинг, программирование

Родительские тела Box2D

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

 *** error for object 0xf572ef0: incorrect checksum for freed object - object was probably    modified after being freed.
 *** set a breakpoint in malloc_error_break to debug

Этого не происходит, когда тела имеют единственное крепление.

Чего я пытаюсь добиться, так это, например, если персонаж берет предмет, преобразования становятся дочерними для родителя. Итак, мы бы получили:

 Parent_R + Child_R
 Parent_P + Child_P

Поскольку я нахожусь в контексте физического движка, я бы предположил, что есть способ создать отношения родитель/потомок между объектами. Я мог бы просто отделить объект (скажем, тот, который ранее падал) от физического мира и рассматривать его как чистый игровой объект спрайта. Это включало в себя довольно много движений вперед и назад (например, воссоздание приспособления/тела при возвращении в физический мир). Вот мой код:

void GameObject::AttatchToBody(GameObject& obj1, GameObject& obj2, b2World& world)
{
    b2PolygonShape boxShape;
    boxShape.SetAsBox(obj2.width, obj2.height);

    b2FixtureDef boxFixtureDef;
    boxFixtureDef.restitution = 0.2f;
    boxFixtureDef.friction = 0.3f;
    boxFixtureDef.shape = &boxShape;
    boxFixtureDef.density = 1 / (obj2.width + obj2.height);

    obj2.fixture = obj1.body->CreateFixture(&boxFixtureDef);
    obj2.body = obj1.body;

}

Любая помощь приветствуется!

10.12.2013

Ответы:


1

Я не видел никаких родительских отношений в Box2d, кроме отношения тело/крепление.

Мне кажется, что у вас есть obj1 и obj2, ссылающиеся на один и тот же объект, выделенный в памяти Box2d (тело). Когда вы удаляете объект obj1, например, вы, вероятно, удаляете прикрепленное к нему тело (выполняя что-то вроде world->DestroyBody(...)). При следующем обновлении box2d вы ссылаетесь на объект, который вы не выделили и приказали уничтожить (системе Box2d). Возможно в этом проблема?

Я также вижу, что вы делите прибор между obj2 и obj1. Что происходит, когда obj1 возвращается системой box2d (т. е. вы уничтожаете тело obj1)? Это не кажется правильным... система ничего не знает о ваших родительских отношениях, а C++ не имеет встроенной системы подсчета ссылок. Это также может быть проблемой.

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

Тем не менее, я считаю, что вы хотите, чтобы все они двигались, как если бы они были прикреплены. Насколько мне известно, есть только два способа заставить два тела вести себя как «одно целое».

Вариант №1. Первый — использовать соединение между ними. Я сделал это в игре, где космический корабль врезался в оружие, чтобы подобрать его. Когда корабль это сделал, я создал призматический шарнир, чтобы казалось, что орудие «установлено» перед кораблем. Это код, который я использовал для его прикрепления:

void BulletLauncherEntity::CreateJointConnection()
{
   Entity* owner = GetOwner();
   Body& ownerBody = owner->GetBody();

   // We put the position of this at the tip of the
   // owner.
   float32 launcherDist = 0.5*(owner->GetScale())*Constants::SCALE_TO_METERS_RATIO();
   float32 launcherSize = 0.5*GetScale()*Constants::SCALE_TO_METERS_RATIO();
   // Joint along axis of entity
   b2PrismaticJointDef jointDef;
   // Note that the "Initialize" function in the
   // jointDef did not really give us what we wanted.
    jointDef.bodyA = &ownerBody;
    jointDef.bodyB = &GetBody();
    jointDef.localAnchorA = Vec2(launcherDist-launcherSize,0);
    jointDef.localAnchorB = Vec2::Zero();
    jointDef.localAxisA = Vec2(1,0);
    jointDef.referenceAngle = 0;

   jointDef.lowerTranslation = -launcherDist;
   jointDef.upperTranslation = 0.5*GetScale()*Constants::SCALE_TO_METERS_RATIO();
   jointDef.enableLimit = true;
   jointDef.maxMotorForce = 2.0;
   jointDef.motorSpeed = 0.25;
   jointDef.enableMotor = true;
   jointDef.collideConnected = false;
   ownerBody.GetWorld()->CreateJoint(&jointDef);
}

Также можно использовать сварной шов.

ОДНАКО, согласно руководству, использование сварных соединений не создаст "жесткого" соединения. У него есть некоторая мягкость, потому что ограничения должны выполняться во время столкновений.

ИЗ РУКОВОДСТВА:

Сварное соединение пытается ограничить все относительные движения между двумя телами. См. Cantilever.h на испытательном стенде, чтобы увидеть, как ведет себя сварной шов. Заманчиво использовать сварной шов для определения разрушаемых конструкций. Однако решатель Box2D является итеративным, поэтому соединения немного мягкие. Поэтому цепочки тел, соединенных сварными швами, будут изгибаться. Вместо этого лучше создавать разрушаемые тела, начиная с одного тела с несколькими креплениями. Когда тело ломается, вы можете уничтожить приспособление и воссоздать его на новом теле. См. пример Breakable на тестовом стенде.

Я не пытался проверить это или посмотреть, насколько «жесткими» являются другие типы суставов. Когда я использовал призматический шарнир, он показался мне довольно прочным. Но иногда его «вталкивают» во время столкновений.

Вариант 2. Прикрепите его как крепление непосредственно к корпусу. Я думаю, вам придется создать, уничтожить старый корпус и создать новый набор креплений только для этого.

Это помогло?

10.12.2013
Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

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

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

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

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..