habrahabr

Игры для NES/Famicom/Денди глазами программиста

  • четверг, 10 июля 2014 г. в 03:10:52
http://habrahabr.ru/post/229187/

Это пост про ограничения старых видеоигр. Сам я под NES никогда не программировал, но с архитектурой поверхностно познакомился. Теперь я не могу играть в игры для NES, не задумываясь, как же они устроены. Иногда это на столько вызывает восхищение, что невольно забываешь про саму игру. «Чему же там восхищаться?», — скажете вы. Да просто укладываться во все ограничения NES, но при этом делать игру красивой, — это действительно целое искусство.

Сейчас я постараюсь рассказать об этом вам, максимально всё упростив.

На NES всё отображаемое на экране делится на спрайты и фон. Спрайты — это объекты, которые двигаются по экрану. Как правило, это непосредственно ваш герой и враги. Иногда это ещё какие-то предметы, но тут всё уже сильно зависит от игры. Фон — это собственно то, что находится позади. И у спрайтов, и у фона есть уйма ограничений.

Фон


Фон на NES делится на квадраты размером 8 на 8 пикселей, которые называются тайлами. Итого таких квадратов 30 в высоту и 32 в ширину. При этом фон может плавно двигаться горизонтально и/или вертикально.



Во многих играх, особенно старых, можно заметить, что игра состоит из таких повторяющихся квадратов. Вспомните Super Mario Bros., Bomberman или Battle City. Дело в том, что в память NES можно загрузить одновременно весьма ограниченное количество таких рисунков, поэтому приходилось использовать одни и те же повторно.

Помимо этого существенные ограничения накладывались на цвета. Всего NES может отображать около 53-55 цветов, учитывая повторяющиеся и похожие. По тем временам это было не так уж мало, но всё не так просто. Используются такие штуки, как палитры:

  • Палитра — это набор из четырёх цветов, т.е. какие-то четыре цвета из этих 53-55 цветов
  • Таких палитр для фона может быть только четыре, при этом один цвет в каждой из них должен быть одинаковым
  • Каждая группа из четырёх тайлов (2x2) отображаемых на экране может быть ассоциирована с одной из этих палитр


Это может быть не так просто понять с первого раза. Попробую объяснить на пальцах. Взгляните ещё раз на картинку выше. Каждый квадратик раскрашен не более, чем в четыре цвета. При этом они делятся на три типа: чёрно-бело-голубые, черно-зелёно-голубые, чёрно-коричневые. Возможно, что используется и четвёртый, но я не заметил.

Проиллюстрирую наглядно:



Цвет помеченный звёздочкой постоянно меняется, так монетки и вопросики мерцают. Да, монетки — это часть фона. И именно поэтому облака и кусты — это один и тот же рисунок: тайл один, палитра выбрана разная. Сэкономили немного памяти, но ведь совсем незаметно с первого взгляда :)



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

Спрайты


Если вы разобрались с ограничениями фона, со спрайтами всё будет легко. Суть в том, что это движущиеся на экране объекты размером 8x8 или 8x16 пикселей. Причём они все одновременно должны быть либо 8x8, либо 8x16, что накладывает несколько других ограничений. В лучшем случае (зависит от размера) всего их может быть аж 64, но на одной строке может отображаться не более восьми, даже если соответствующая область спрайта прозрачная, поэтому слишком много подвижных объектов не сделаешь. Правда, некоторые игры всё-таки делают, заставляя один из спрайтов исчезать на долю секунды, что приводит к неприятному мерцанию. Наверняка многие замечали такое. На цвета наложены примерно те же самые ограничения, что и для фона, но для спрайтов даются отдельные четыре палитры, один из цветов при этом считается за прозрачность. То есть получаем всего три цвета + фон…



Луиджи же — это просто Марио с другой палитрой. Обратите внимание — у Марио рукава, глаза, волосы и усы одного цвета. Именно поэтому у Луиджи глаза, волосы и усы стали зелёными.



Как же так получается?


А теперь взгляните на игры для NES, учитывая описанные выше ограничения. Как же так получается, что фон может быть только из 13 цветов, но многие игры запомнились очень красочными? Как же при таких маленьких спрайтах мы сражались с огромными боссами? Игры начинают выглядеть совсем иначе.

Например, Chip and Dale 2:



Всё весьма красочно и разноцветно, при этом разработчики вписываются во все ограничения.

Как только мы доходим до второй половины уровня, появляются новые цвета:



Просто в момент, когда мы переходим в другую локацию, и экран темнеет, в память загружается уже новые палитра и тайлы. Так создаётся впечатление, что игра гораздо более красочная, чем она есть на самом деле: эти самые 13 цветов достаточно часто меняются от уровня к уровню.

Выше я описал, что фон может делиться на две части, которые движутся отдельно. Именно так сделана начальная заставка, где летит дирижабль Толстопуза:



Колючая проволока внизу движется с одной скоростью, фон с другой, сам дирижабль — это спрайт, который движется с третьей скоростью. Так создаётся иллюзия объёма.

Бывают и совсем другие приёмы. Посмотрите внимательно знаменитую заставку Megaman 2:

Окна и выступы — это спрайты, а само здание представляет из себя фон из просто вертикальных линий, движение которых отследить невозможно:



На самом деле здание движется с той же скоростью, что и город на фоне, но это незаметно. При этом за счёт движения окон складывается впечатление, что здание движется всё-таки гораздо быстрее, а это соответственно создаёт ощущение того, что оно ближе.

Кстати, некоторые спросят, почему у самого Мегамена так много цветов? Да просто на самом деле он состоит из нескольких спрайтов: лица и тела, которые накладываются друг на друга:



А теперь подумайте — как же делались большие подвижные боссы, учитывая все ограничения на количество спрайтов? Ответ прост: такие боссы обычно на самом деле являются фоном. Именно поэтому при битве с ними фон зачастую либо чёрный, либо просто одноцветный. Вот пример из тех же Chip and Dale 2:



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

В некоторых играх вроде Jurassic Park делают ещё хитрее:



Босс — это всё-таки фон, а вот кустики и камни на фоне — это спрайты. То есть всё шиворот навыворот! И да, спрайт может быть позади фона. Именно поэтому когда персонаж проходит через кусты, они иногда просвечивают сквозь него.

Кстати, у этой же игры в заставке надпись «Ocean» большая, движется в разные стороны с разной скоростью, а потом и вовсе отображается волнами:

Тут всё совсем хитро. Игра отслеживает момент, когда на экране телевизора дорисовывается сканлайн (горизонтальная линия), после чего сдвигает фон по горизонтали. Таким образом можно получить эффект вроде горизонтальных волн.

Продолжать можно очень долго. Любая достаточно серьёзная игра напичкана самыми разными такими «фокусами», которые выжимали из NES гораздо больше, чем было задумано изначально. Надо сказать, что многие из этих ограничений можно было снять, установив в картридж с игрой дополнительные чипы. И это весьма активно делали, в итоге картриджи могли весьма сильно отличаться с аппаратной точки зрения, но тогда нужно было не забывать и об итоговой цене производства, поэтому разработчики не очень сильно себя баловали.

Не стоит забывать и про ограниченные звуковые возможности, но это не так наглядно. Скажу лишь то, что для создания приятной музыки при помощи такого железа действительно нужно было обладать музыкальным талантом. Game Boy был уже немного более продвинутым в этом плане и в результате породил целый музыкальный жанр и свою культуру.

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

upd: Огромное спасибо товарищу VEG за многие уточнения!