Подтвердить что ты не робот

Как старые игры сталкивались с обнаружением столкновений со стенами, полами и потолками?

Я читал об обнаружении столкновений в играх на 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
4b9b3361

Ответ 1

Для типов игр эпохи NES, о которых вы говорите, все было 2D. Это само по себе упрощает многие вещи.

Некоторые машины той эпохи (особенно с аппаратными спрайтами, такими как Commodore 64) имели аппаратное обнаружение столкновения. Большинство игр, которые не полагались на обнаружение столкновения оборудования, либо использовали ограничительную рамку, либо маску попадания (1-битное растровое изображение спрайта).

В любом случае обнаружение столкновений обычно делалось "апостериорным", за исключением особых случаев, подобных краям мира. В некоторых играх на самом деле были ошибки, когда вы слишком быстро двигались, когда попадаете в что-то, вы можете пройти через него. (На самом деле, обзоры ранних 80 игр часто комментируют, насколько точным было обнаружение столкновения.)

Для платформеров вы обычно проверяете, не был ли символ "заземлен" перед применением силы тяжести.

Односторонняя платформа не слишком сложна для решения после того, как вы знаете вектор скорости спрайта, поэтому вы можете использовать это, чтобы определить, должно ли регистрироваться столкновение.

Ответ 2

Здесь есть статья, в которой подробно рассматривается программирование игровой платформы Nintendo Entertainment System (NES).

Возможно, я не искал правду, потому что раньше не наткнулся на эту статью.

Ответ 3

В таких играх, как Super Mario World (SNES), игра хранила уровни в формате памяти, что позволяло легко находить местоположение Mario X/Y, преобразовывать его в адрес плитки, а затем проверять плитки сразу вокруг этого адрес. Так как уровни всегда были фиксированной шириной (хотя область, которую вы могли просматривать, менялись), она упрощала адресацию, поскольку она всегда была фиксированным смещением от положения марионеточного изображения, например. Адрес + 1 для плитки рядом с марио, адрес + 0x300 для плитки под ним и т.д.

Ответ 4

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

Например, в Super Mario Bros. коллизия с врагами проверяется только через каждый второй кадр. Коллизия с флагштоком конца уровня происходит только один раз каждые 27 кадров. Существует также ограничение на максимальное количество объектов, проверяемых на столкновения, что, как известно, позволяет вам проходить через некоторые атаки браузера в конце игры, не умирая.

Другим примером является порт PC Engine от Gradius. Вместо того чтобы использовать более дорогое обнаружение попадания в ограничивающую рамку, он использует систему листов. Каждый объект сокращается до номера плитки, состоящего из позиции X и Y, округленной до кратного 8 и объединенного в одно число. Если два объекта занимают один и тот же тайл 8х8, считается, что они столкнулись. Он менее точен, но склоняется в пользу игрока, поэтому представляет собой приемлемый и забавный компромисс.

Ответ 5

Я знаю, это старая тема, но я в этом отчаялся.

Сукаса, не могли бы вы объяснить, как именно было сделано следующее?

"Это позволило легко взять местоположение Mario X/Y, преобразовать его в адрес плитки"

Если бы вы могли объяснить логику только потому, что я не знаю внутреннюю работу SNES. Я хочу понять логику, потому что все, что я пробовал в моей программе, не работает. Хотя я был очень логичным, лол.