Войти
Box2DФорумОбщее

Предотвращение движения объекта в противоположную сторону при столкновении

#0
11:55, 26 авг. 2013

Всем доброго утра!

Нужно реализовать физику в платформере. В игре планируется делать не только прямоугольные поверхности, поэтому решил воспользоваться Box2d версии 2.2.1. Для начала изобразил тестовую сценку:

+ Показать

В данной сцене используется 4 статических объекта и 1 динамический. Первый статический объект является ограничителем перемещения за левый край экрана. Вот так вот я его описал:

+ Показать

Далее описал правый ограничитель:

+ Показать

Всё это я указывал с учётом строго фиксированного размера клиентской части окна - 800x600. Далее я описал поверхность земли:

+ Показать

Затем горку:

+ Показать

И наконец я описал динамический объект:

+ Показать

Вот теперь мне надо заставить всё это работать. Пробовал разные способы. На применении импульсов не прокатило, так как объект начинает двигаться медленно и со временем набирает скорость. Мне же нужно чтобы было всё так, как это устроено в том же Mario. То есть нажал кнопку, персонаж мгновенно начинает двигаться. Отпустил кнопку, он тут же останавливается. И скорость не изменяется в момент движения. В текущий момент реализовал перемещение вот так вот:

+ Показать

То есть в первый момент нажатия устанавливаю силу, а в момент отжатия её убираю. Персонаж двигается как надо. Но когда он сталкивается с каким-то из объектов, он начинает двигаться в противоположную сторону сам. И заглушить его перемещение я могу только если нажму двигаться снова в сторону столкновения. Получается что в момент столкновения его сила инвертируется. Да и собственно так он и на горку никогда не заберётся.

Как мне реализовать такое его перемещение, чтобы он не отскакивал от препятствия, а просто прижимался к ним, и чтобы при этом он мог карабкаться по горке?

Спасибо за внимание!


#1
12:13, 26 авг. 2013

s3dworld, Я не совсем понял, зачем у тебя так сложно сделано перемещение персонажа)
Попробуй сделать так: если нажата кнопка направо, то pBodyEnemy -> SetLinearVelocity(b2Vec2(10.0f,0.0f)), если ты кнопку отпустил, то pBodyEnemy -> SetLinearVelocity(b2Vec2(0.0f,0.0f)); то же самое и с перемещением направо, только не 10.0f, а -10.0f.
Чтобы персонаж двигался ещё и в воздухе, то в функции SetLinearVelocity во втором аргументе напиши не 0.0f, а pBodyEnemy -> GetLinearVelocity().y

#2
14:35, 26 авг. 2013

VoinC++
Спасибо большое!

Только вот он совсем не взбирается на горку. Как его заставить это делать?

#3
14:54, 26 авг. 2013

s3dworld, он не забирается на неё, потому что соскальзывает? Если так, то измени силу трения, то есть fixtureDefEnemy.friction;
Напиши поподробнее, если не получится...

#4
15:53, 26 авг. 2013

VoinC++
У меня сила трения установлена в 0.0f:

fixtureDefEnemy.friction=0.0f

А то иначе он по земле перемещается пошагово. То есть установил я 0.1f, нажал вправо, он переместился немного и остановился, потому что движения затухает из-за трения. Но такими вот постоянными нажатиями я могу дойти до горы и он по ней начнёт карабкаться.

А вот когда установлено 0.0f, он отлично идёт по земле, а когда подходит к горе, не скользит. Он приподнимается на чуть-чуть и просто в этом месте замирает. То есть можно спуститься, но выше нельзя. Вот максимум куда он забирается:

+ Показать
#5
15:59, 26 авг. 2013

VoinC++
А вот кстати обманул на счёт выше не поднимается. Поднимается, только если постоянно нажимать клавишу.

#6
16:47, 26 авг. 2013

s3dworld
> А то иначе он по земле перемещается пошагово. То есть установил я 0.1f, нажал
> вправо, он переместился немного и остановился, потому что движения затухает
> из-за трения.
Как скорость может затухать, если её применяешь к персонажу каждый раз :)? Просто мне кажется, что ты применяешь скорость не всегда, когда зажата кнопка, а только один раз, когда её нажал... У меня в игре(тоже платформер) персонаж легко забирается на такие горки таким способом.
Почитай http://suvitruf.ru/2012/12/22/2764/ там вроде бы то, что тебе надо

#7
16:52, 26 авг. 2013

VoinC++
Понял, не правильно почитал твой первый пост. Сейчас попробую.

#8
17:14, 26 авг. 2013

VoinC++
Отлично, заработало. Сделал так:

+ Показать

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

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

Есть у меня ещё несколько вопросов, связанных с Box2d. Скажем, как реализовать в игре такие объекты, на которые можно запрыгивать, при этом можно и насквозь их проходить. Представим что в комнате стоит стол. Мы можем пройти мимо него. А можем на него запрыгнуть. Как такое делается? Пока в голове только такое решение: включать столкновение со столом в момент, когда персонаж летит вниз. То есть каждый раз такие объекты то вносить на проверку на столкновения, то исключать. Не знаю на сколько данное решение верное.

Ну и представим что нам нужно лазить по лестнице. Как такое сделать? Мой вариант: устанавливаем лестницу как сенсор. Когда до неё дотронулись, для персонажа отключаем гравитацию. Но опять же, это мой вариант, которые только в теории. Может делают по другому.


Кстати, в новой версии Box2D так же присутствует ограничение на размер динамических объектов от 10 сантиметров до 10 метров?

Я смотрю в новой версии была убрана установка размеров мира. То есть он обрабатывает всё, а нам самим нужно объекты пробуждать и вводить в сон?

#9
17:46, 26 авг. 2013

Хотя появилась ещё проблема. Заметил когда переместил горку левее. В общем чем выше трение, тем он как-то сигает и может оказаться в воздухе возле горки. А чем ниже трение, тем он начинает скользить по горе. Хочется чтобы он и в воздухе не был и по горе не спускался сам. Как это сделать? Ниже видео, показывающее как он вообще там себя ведёт (на дефекты в отображении персонажа не обращать внимание, это так получилось при конвертировании видео):

+ Показать
#10
1:44, 27 авг. 2013

s3dworld
Односторонние платформы (столы) я реализовывал с помощью фильтров.
объект состоит из трех слоев: платформа и два сенсора. Сенсоры слушают касания. Нижний при касании меняет фильтр так, чтобы объект проходил, верхний - наоборот, но при условии, что объект не касается нижнего.

Немного возни с фильтрами и все работает отлично.
У разных односторонних платформ, находящихся рядом друг с другом должны быть разные биты фильтров.

Тут следует быть внимательным, так как на разные объекты платформа должна реагировать независимо.
В твоем варианте один недочет: персонаж может лететь вниз в тот момент, когда платформа на уровне пояса, тогда он застрянет.

Вариант с гравитацией на лестнице тоже неудачный. Лучше Joint. Prismatic подойдет.

Чтобы персонаж адекватно поднимался в горку лучше сделать его «колобком» вместо прямоугольника. Либо прикрепить круглые ноги снизу.

Box2DФорумОбщее

Тема в архиве.