Я проверяю столкновение для персонажа платформера, как показано в # 1. Красные точки - это проверенные пиксели, а серые линии обозначают оси, к которым они относятся. Мне нравятся результаты, которые я получаю от проверки столкновения таким образом (в отличие от, скажем, ограничивающего прямоугольника). Все работает именно так, как я хотел бы, за исключением одной проблемы: обнаружение раздавливания.
На следующих изображениях голубой прямоугольник представляет землю, оранжевый прямоугольник - объект, а стрелки указывают направление движения.
Простое решение для определения, когда игрок сокрушен, состоит в том, чтобы видеть, срабатывают ли точки столкновения на противоположных сторонах. Если они есть, игрок сокрушен. В # 2 вы можете увидеть нормальный сценарий разгрома. Игрок заземлен, а верхние точки столкновения пересекаются с падающим объектом. Это вызывает влюбленность.
№ 3, 4 и 5 представляют проблемные сценарии. В # 3 игрок движется к объекту, который движется вверх. Правая точка столкновения поражает объект, вызывая столкновение и останавливая игрока.
Теперь, если объект продолжает двигаться вверх, а игрок продолжает двигаться вправо (как показано на # 4), объект очищает точку столкновения правой стороны игроков, и игрок перемещается вправо. Но теперь, сделав это, объект пересекает верхнюю точку столкновения, вызывая нежелательное вертикальное раздавливание.
Аналогичный сценарий показан в # 5. Два объекта находятся достаточно далеко друг от друга, чтобы очистить нижние точки столкновения, позволяя игроку упасть, но не настолько, чтобы позволить точкам бокового столкновения очиститься, вызывая нежелательное горизонтальное раздавливание.
Я ломал голову над решением, но ничего из того, что я придумал, не сработало особенно хорошо, поэтому мне интересно, есть ли у кого-нибудь идея или понимание того, как решить эти проблемы.
Чтобы устранить некоторую путаницу, красные точки столкновения должны были находиться внутри спрайта, а серые линии использовались только для обозначения соответствующей оси для каждой точки столкновения. Например, если спрайт персонажа был простым зеленым квадратом, точки столкновения выглядели бы примерно так:
Пусть точки «теста на раздавливание» находятся внутри серого прямоугольника, показанного на вашем изображении № 1, то есть убейте игрока, только если вы обнаружите попадание в один из пикселей.
источник
Как кто-то, кто вырос на платформеров 80-х, мой первый комментарий заключается в том, что точки контакта должны быть точно на спрайте, а не где-то за его пределами. Было немного опыта, более расстраивающего, чем смерть, когда оружие / сокрушитель / враг явно находились в нескольких пикселях от вашего персонажа - и именно такой опыт останавливает людей.
Имея это в виду, идея иметь отдельные точки для горизонтального и вертикального столкновения просто не летает. Таким образом, ваши случаи 3 и 5 не существуют.
Что касается обнаружения столкновений, как уже было сказано, вам нужно учитывать направление движения, и у вас есть две оси движения для рассмотрения. Если дробилка не работает, игрок не должен идти вперед - он должен действовать как стена. Таким образом, с горизонтальными и вертикальными точками обнаружения в одном месте, вы не можете получить случай 4, даже если вы не добавите направление движения в микс.
Движущаяся вверх дробилка добавляет дополнительную сложность. Если это так быстро, что у игрока нет шансов убежать, тогда ОК. Но если он будет медленнее, игрок будет ожидать, что сможет перебежать над поднимающейся платформой и спрыгнуть с другой стороны. Спрайт игрока поднимается вверх по дробилке, и обнаружение раздавливания происходит на потолке .
источник
Вы можете сделать объект «более твердым», чем земля, что означает, что, при столкновении, игрок толкается «в» землю, а не в толкается «в» движущийся объект.
Это предполагает, что игрок не может толкнуть себя «в» объекты или землю.
источник
Если вы можете обнаружить перекрытие объектов, не дожидаясь их отображения, простой подход состоит в том, чтобы обрабатывать движение игрока и других объектов независимо, по одному пикселю за раз, с последующей отдельной проверкой столкновений. Если игрок движется свободно и в результате такого движения столкнется со своим объектом, отведите его назад. Если в результате движения объекта происходит столкновение с объектом, проверьте, может ли игрок двигаться в том же направлении, что и этот объект. Если так, переместите игрока. Если нет, обработайте ситуацию «раздавливания» соответствующим образом (повредите или убейте игрока и / или переместите сталкивающийся объект назад, в зависимости от контакта).
Кстати, если только ограниченное количество комбинаций фигур может столкнуться, может быть полезно предварительно рассчитать битовые карты «обнаружения столкновений», чтобы, если пиксель был установлен в первом спрайте со смещением (x1, y1) и во втором со смещением (x2, y2) секунды пиксель со смещением (x1-x2, y1-y2) будет установлен на карте столкновений. Такая предварительно рассчитанная карта столкновений позволит обнаруживать столкновения между двумя спрайтами, проверяя состояние одного пикселя в карте столкновений.
источник
Требуется два объекта, чтобы раздавить игрока. Ваше обнаружение раздавливания должно проверять, находится ли игрок между двумя объектами, расстояние между ними равно размеру игрока, а расстояние уменьшается.
источник
Я нахожусь рядом, чтобы работать до сих пор. Он не требует «внешней» информации о движении дробилок и решает проблему ложных срабатываний. Когда ложный положительный результат обнаружен, он рассматривается как столкновение (и это действительно так):
Идея такова: зачем проверять, движется ли дробилка, когда мы действительно заботимся о том, движется ли персонаж. Оба могут ответить, если раздавливание является ложноположительным, вызванным собственным движением персонажа или истинным раздавлением движением объекта дробилки.
Если персонаж движется и раздавлен (столкновения на противоположных сторонах для входящего кадра), тогда снова проверьте на раздавливание в последнем кадре / координатах итерации:
Если не подтверждено снова, то это происходит из-за собственного движения персонажа, и персонаж должен быть возвращен к последним координатам кадра / итерации, как при столкновении
Если раздавливание подтверждено во второй раз, тогда продолжайте раздавливание.
источник