Всем доброго утра!
Нужно реализовать физику в платформере. В игре планируется делать не только прямоугольные поверхности, поэтому решил воспользоваться Box2d версии 2.2.1. Для начала изобразил тестовую сценку:
В данной сцене используется 4 статических объекта и 1 динамический. Первый статический объект является ограничителем перемещения за левый край экрана. Вот так вот я его описал:
Далее описал правый ограничитель:
Всё это я указывал с учётом строго фиксированного размера клиентской части окна - 800x600. Далее я описал поверхность земли:
Затем горку:
И наконец я описал динамический объект:
Вот теперь мне надо заставить всё это работать. Пробовал разные способы. На применении импульсов не прокатило, так как объект начинает двигаться медленно и со временем набирает скорость. Мне же нужно чтобы было всё так, как это устроено в том же Mario. То есть нажал кнопку, персонаж мгновенно начинает двигаться. Отпустил кнопку, он тут же останавливается. И скорость не изменяется в момент движения. В текущий момент реализовал перемещение вот так вот:
То есть в первый момент нажатия устанавливаю силу, а в момент отжатия её убираю. Персонаж двигается как надо. Но когда он сталкивается с каким-то из объектов, он начинает двигаться в противоположную сторону сам. И заглушить его перемещение я могу только если нажму двигаться снова в сторону столкновения. Получается что в момент столкновения его сила инвертируется. Да и собственно так он и на горку никогда не заберётся.
Как мне реализовать такое его перемещение, чтобы он не отскакивал от препятствия, а просто прижимался к ним, и чтобы при этом он мог карабкаться по горке?
Спасибо за внимание!
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
VoinC++
Спасибо большое!
Только вот он совсем не взбирается на горку. Как его заставить это делать?
s3dworld, он не забирается на неё, потому что соскальзывает? Если так, то измени силу трения, то есть fixtureDefEnemy.friction;
Напиши поподробнее, если не получится...
VoinC++
У меня сила трения установлена в 0.0f:
fixtureDefEnemy.friction=0.0f
А то иначе он по земле перемещается пошагово. То есть установил я 0.1f, нажал вправо, он переместился немного и остановился, потому что движения затухает из-за трения. Но такими вот постоянными нажатиями я могу дойти до горы и он по ней начнёт карабкаться.
А вот когда установлено 0.0f, он отлично идёт по земле, а когда подходит к горе, не скользит. Он приподнимается на чуть-чуть и просто в этом месте замирает. То есть можно спуститься, но выше нельзя. Вот максимум куда он забирается:
VoinC++
А вот кстати обманул на счёт выше не поднимается. Поднимается, только если постоянно нажимать клавишу.
s3dworld
> А то иначе он по земле перемещается пошагово. То есть установил я 0.1f, нажал
> вправо, он переместился немного и остановился, потому что движения затухает
> из-за трения.
Как скорость может затухать, если её применяешь к персонажу каждый раз :)? Просто мне кажется, что ты применяешь скорость не всегда, когда зажата кнопка, а только один раз, когда её нажал... У меня в игре(тоже платформер) персонаж легко забирается на такие горки таким способом.
Почитай http://suvitruf.ru/2012/12/22/2764/ там вроде бы то, что тебе надо
VoinC++
Понял, не правильно почитал твой первый пост. Сейчас попробую.
VoinC++
Отлично, заработало. Сделал так:
Взбирается на гору хорошо. Но при нажатии на спуск, он начинает скользить и по ней сам спускается. Изменение трения помогает решить проблему со спуском не с верхушки, то есть нажму влево, он будет спускаться пока держу. Но стоит мне забраться на саму верхушку, и раз нажать влево, то он тут же скатится в самый низ. В по идее мне хотелось бы чтобы он ни при каком условии не скользил по горе сам. То есть чтобы именно игрок управлял уровнем расположения на горе.
В общем решил проблему подбором значения трения. Если слишком маленькой, скользит. Если слишком большое, он даже на ровной поверхности подпрыгивает.]
Есть у меня ещё несколько вопросов, связанных с Box2d. Скажем, как реализовать в игре такие объекты, на которые можно запрыгивать, при этом можно и насквозь их проходить. Представим что в комнате стоит стол. Мы можем пройти мимо него. А можем на него запрыгнуть. Как такое делается? Пока в голове только такое решение: включать столкновение со столом в момент, когда персонаж летит вниз. То есть каждый раз такие объекты то вносить на проверку на столкновения, то исключать. Не знаю на сколько данное решение верное.
Ну и представим что нам нужно лазить по лестнице. Как такое сделать? Мой вариант: устанавливаем лестницу как сенсор. Когда до неё дотронулись, для персонажа отключаем гравитацию. Но опять же, это мой вариант, которые только в теории. Может делают по другому.
Кстати, в новой версии Box2D так же присутствует ограничение на размер динамических объектов от 10 сантиметров до 10 метров?
Я смотрю в новой версии была убрана установка размеров мира. То есть он обрабатывает всё, а нам самим нужно объекты пробуждать и вводить в сон?
Хотя появилась ещё проблема. Заметил когда переместил горку левее. В общем чем выше трение, тем он как-то сигает и может оказаться в воздухе возле горки. А чем ниже трение, тем он начинает скользить по горе. Хочется чтобы он и в воздухе не был и по горе не спускался сам. Как это сделать? Ниже видео, показывающее как он вообще там себя ведёт (на дефекты в отображении персонажа не обращать внимание, это так получилось при конвертировании видео):
s3dworld
Односторонние платформы (столы) я реализовывал с помощью фильтров.
объект состоит из трех слоев: платформа и два сенсора. Сенсоры слушают касания. Нижний при касании меняет фильтр так, чтобы объект проходил, верхний - наоборот, но при условии, что объект не касается нижнего.
Немного возни с фильтрами и все работает отлично.
У разных односторонних платформ, находящихся рядом друг с другом должны быть разные биты фильтров.
Тут следует быть внимательным, так как на разные объекты платформа должна реагировать независимо.
В твоем варианте один недочет: персонаж может лететь вниз в тот момент, когда платформа на уровне пояса, тогда он застрянет.
Вариант с гравитацией на лестнице тоже неудачный. Лучше Joint. Prismatic подойдет.
Чтобы персонаж адекватно поднимался в горку лучше сделать его «колобком» вместо прямоугольника. Либо прикрепить круглые ноги снизу.
Тема в архиве.