Не так давно начал обкатывать физические движок Box2D, который в libGDX входит. Довольно не мало проблем с ним возникло. Последние дни мучился с различными силами.
Сразу стоит сказать, что движок охрененный. Точно довольно физику тел моделирует. Но огромная проблема возникает в подборе коэффициентов различных. В последние дни пытался разобраться с силой трения и с гравитацией. Вектор действия силы притяжения можно задать при создании мира (com.badlogic.gdx.physics.box2d.World), а именно world = new World(new Vector2(0, -20), true). Мы указали что силы притяжения действует сверху вниз, как и в реальном мире.
Допустим, если мы хотим поменять силу притяжения, действующую на объект, то можно коэффициент воздействия этой силы поменять. Как пример setGravityScale(-1). Теперь если сила действует вниз, то объект будет притягиваться вверх =D
Тут больше проблема чисто в подборе коэффициентов. А вот с трением посложнее. По умолчанию сила трения нулевая. Я использовал в мире движущиеся платформы. При нулевом трении, персонаж не будет двигаться вместе с платформой, а будет оставаться на месте, как бы скользить. Логично предположить, что надо выставить трение побольше. Я смотрел мануалы забугорные…На какой-то из сборок либы, всё работал норм, у меня почему-то нет. Вроде всего-то надо установить трение побольше для персонажа.
playerSensorFixture.setFriction(200f);
Трение то устанавливается, но не работает на платформе. Честно говоря долго провозился. Решил пойти другим путём. В Box2D можно получить список всех контактов объектов.
List<Contact> contactList = world.getWorld().getContactList();
Я сделал метод, который проверяет, находится ли персонаж на земле. И добавил в этот метод проверку на движение. Если перс стоит, то меняю трение контакта.
private boolean isPlayerGrounded() { world.groundedPlatform = null; List<Contact> contactList = world.getWorld().getContactList(); for(int i = 0; i < contactList.size(); i++) { Contact contact = contactList.get(i); if(contact.isTouching() && (contact.getFixtureA() == world.getPlayer().playerSensorFixture || contact.getFixtureB() == world.getPlayer().playerSensorFixture)) { Vector2 pos = world.getPlayer().getPosition(); WorldManifold manifold = contact.getWorldManifold(); boolean below = true; for(int j = 0; j < manifold.getNumberOfContactPoints(); j++) { below &;= (manifold.getPoints()[j].y < pos.y - 0.5F); } if(below) { if(contact.getFixtureA().getUserData() != null && contact.getFixtureA(). getUserData().equals("p")) { world.groundedPlatform = (MovingPlatform)contact.getFixtureA(). getBody().getUserData(); if (!keys.get(Keys.LEFT) && !keys.get(Keys.RIGHT)) contact.setFriction(20F); else contact.setFriction(0F); } if(contact.getFixtureB().getUserData() != null && contact.getFixtureB(). getUserData().equals("p")) { world.groundedPlatform = (MovingPlatform)contact. getFixtureB().getBody().getUserData(); if (!keys.get(Keys.LEFT) && !keys.get(Keys.RIGHT)) contact.setFriction(20F); else contact.setFriction(0F); } // return true; } return false; } } return false; }
Ключевое здесь: contact.setFriction(20F). Теперь работает. Но всё равно это уже какой-то костыль получается)
Однако как йода ты мысли свои излагаешь :)
Когда-то прикола ради так писал и говорил. Привык потом. Теперь уже это привычка (:
Трение не работает, т.к. у платформы трение 0. Общий коэффициент трения вычисляется как корень из произведения коэффициентов двух тел. Поэтому твой герой не тёрся об платформу.
Здравствуйте.Вы не сталкивались с проблемой,когда объекты проникают, а не задерживаются?Я столкнулся с этой проблемой и не понимаю почему так происходит.
У меня есть 2 тела — static и dynamic.
Первое(static) можно двигать,а второе падает сверху(dynamic).Если первое тело не двигать,то второе падает в первое и все нормально,но если его двигать,то оно начинает проникать сквозь второе(динамическое) тело.С чем это может быть связано?
Если мне память не изменяет, то у static тел массы нет. Может в этом дело. Попробуйте сделать его dynamic.
Я давно уже с Box2D не работал. Без кода вряд ли что-то путное могу подсказать.
Нет,я уже пробовал,это не помогает.
И стало только хуже,теперь проникает и через низ,а не только через боковые грани =)
А вы эту статью смотрели? Если не боитесь, можете скинуть свой проект мне на мыло, я могу посмотреть на выходных.
Конечно,я с нее и начинал.Я только вместо стандартных тел использовал программу
http://www.aurelienribon.com/blog/projects/physics-body-editor/
P.S. Вы не знаете как сильно параметр
body.setBullet(true); может влиять на все это?
setBullet(true) указывает, что расчёты по этому телу будут более точные.
Не думаю, что дело в нём.