Я читал об обнаружении столкновений в играх на stackoverflow и других сайтах. Многие из них говорят о BSP, ограничивающих точках, интеграции и т. Д. Однако на NES им удалось обнаружить столкновения полов и стен в играх, и мне трудно поверить, что они проделали много вычислений для обнаружения столкновений со стенами.
Я предполагаю, что мой вопрос: учитывая уровень, состоящий только из плиток, как они обнаруживают столкновения со стенами и полом в таких играх, как Mario и Megaman, у которых была небольшая вычислительная мощность?
- Проследили ли они путь движения и определили ближайшую соединительную плитку? (немного поисков) (априори)
- Они определили столкновение с полом, а затем выяснили, как лучше всего отрегулировать персонажа? (posteriori) Это рискованно с переменными временными шагами, вы могли бы перепрыгнуть через плитку, если бы вы были достаточно быстры. Хотя я предполагаю, что временные интервалы игр NES были синхронизированы с частотой обновления телевизора.
- Всегда ли гравитация влияет на вашего персонажа, когда вы находитесь на земле? Или вы просто «выключаете» его, когда твердо настроены ходить по плитке? А как насчет того, чтобы спуститься с края обрыва? В противном случае вам понадобится какой-то способ определения плитки под вами.
- Если вы столкнулись с плиткой, могли бы вы просто найти край этой плитки и переместить своего персонажа в сторону от нее (в зависимости от направления движения)?
- а как насчет наклонных плиток, как в super metroid и mario?
- А как насчет «платформ», где вы можете перепрыгнуть через дно и приземлиться наверху. Как бы вы справились с столкновениями с этими плитками, если бы делали это «апостериори»?
Я написал код столкновения, который в основном является «априорным», поскольку он ищет первую плитку, по которой вы попадете в определенном направлении. Мне просто интересно, есть ли способ лучше. (возможно, просто используя обнаружение столкновений постфактум)
например, код для проверки столкновения плиток при движении вниз (я проверяю вертикальное, а затем горизонтальное движение):
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