Я читал об обнаружении столкновений в играх на stackoverflow и других сайтах. Многие из них рассказывают о BSP, ограничивающих элипсах, интеграции и т.д. Однако на NES им удалось выявить столкновение с столбиком и столкновением в играх, и мне трудно поверить, что они сделали много расчетов для обнаружения столкновений на стене.
Я думаю, мой вопрос, учитывая уровень, состоящий только из плиток, как они обнаружили столкновения со стенами и полами в играх, таких как Марио и Мегаман, которые не имели достаточной вычислительной мощности?
- Они следовали по пути движения и определили ближайшую соединительную плитку? (бит поиска) (априори)
- Определяли ли они столкновение с полом, а затем выясняли лучший способ настройки персонажа? (posteriori) Это рискованно с переменными временными отметками, вы могли бы перепрыгнуть через плитку, если бы вы были достаточно быстры. Хотя я предполагаю, что временные метки игр NES были синхронизированы с частотой обновления ТВ.
- Тяжесть всегда влияет на вашего персонажа, когда вы на земле? Или вы просто "выключаете его", когда вы полны решимости идти по плитке? Как насчет того, когда вы сходите с края скалы? Вам понадобится какой-то способ определения плитки под вами в противном случае.
- Если вы столкнулись с плиткой, вы бы просто нашли край этой плитки и переместили своего персонажа в сторону (в зависимости от направления движения)?
- как насчет наклонной плитки, как в супер-метрополии и марио?
- Как насчет "платформ", где вы можете прыгать через дно и приземляться сверху. Как вы столкнетесь с столкновениями с этими плитами, если вы делаете это "posteriori"?
Я написал код коллизии, который в основном "априори", поскольку он ищет первый фрагмент, который вы нажмете в определенном направлении. Мне просто интересно, есть ли лучший способ. (вместо этого, возможно, использовать обнаружение столкновений после факта)
например, код для проверки столкновений черепицы для перемещения вниз (я проверяю vert, а затем горизонтальное перемещение):
def tile_search_down(self, char, level):
y_off = char.vert_speed
assert y_off > 0
# t_ are tile coordintes
# must be int.. since we're adding to it.
t_upper_edge_y = int( math.ceil((char.y+char.h) / self.tile_height ) ) #lowest edge
while (t_upper_edge_y*self.tile_height) < (char.y+char.h+y_off): # lowest edge + offset
t_upper_edge_x = int( math.floor(char.x/self.tile_width) )
while (t_upper_edge_x*self.tile_width) < (char.x+char.w):
t_x = t_upper_edge_x
t_y = t_upper_edge_y
if self.is_tile_top_solid(t_x, t_y, plane):
char.y = t_y*self.tile_height - char.h
char.vert_speed = 0.0
char.on_ground = True
return
t_upper_edge_x += 1
t_upper_edge_y += 1
char.y += y_off