День добрый :)

Сегодня я хочу поделиться с вами историей о том, как я писал игру для этой консоли: Пост: Ретро-консоли, часть 7. Fairchild Channel F


Предисловие

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

В общем, чтобы упростить материал, я решил не приводить примеры кода и по минимуму использовать специфические технические термины.

Вместо этого я хотел бы показать вам весь процесс пошагово, начиная от идеи и заканчивая итоговым продуктом :)

Пример отличной пошаговой инструкции :)
Пример отличной пошаговой инструкции :)



Идея

Итак, начнем с того, что вообще можно сделать. Технические ограничения у меня очень жесткие:

  • Процессор медленный, 8-битный, простенький. Он даже не умеет умножать\вычитать. 
  • Оперативной памяти буквально пару десятков байт
  • Рисование на экране не просто медленное, а ОЧЕНЬ медленное
  • Рисовать можем в область 100x60 пикселей (даже у моего первого мобильного телефона экран был больше) и только тремя цветами
  • Размер игры не может превышать 2 килобайт

Да уж, GTA сделать не получится) Даже Марио это недостижимый уровень.
Ну и ладно, тогда буду делать что-то попроще.

Так как это был мой первый опыт с этой системой, то мне хотелось просто сделать какой-то завершенный продукт. После определенных размышлений я решил сделать клон игры про динозаврика из Хрома

Игра, которая появляется в Хроме, если у вас пропал интернет
Игра, которая появляется в Хроме, если у вас пропал интернет



План

Теперь нужно определиться с тем, что именно нужно сделать. Я набросал такой вот список задач:

  • Фон (небо и земля)
  • Динозаврик (с анимацией бега\прыжка)
  • Кактусы (и столкновения с ними)
  • Очки (в текущей игре и максимальный результат)
  • Смена дня и ночи (+ солнце и луна)
  • Звуки
  • Птеродактили / приседания под ними



Создаем небо и землю. 

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

Для отрисовки фона мне доступны три цвета: светло-синий, светло-зеленый и серый. Не сложно догадаться какой из них я выберу :D

GIF
Такой вот результат) На данный момент игра весит 11 байт


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

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

Похоже на игру?) А между прочим она весит уже 66 байт
Похоже на игру?) А между прочим она весит уже 66 байт



Динозаврик!

Пришло время заняться главным героем (я так и не придумал ему имя). На этом этапе я хотел просто вывести его на экран и подвигать в разные стороны.

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

  • во-первых, он рисуется очень медленно. К сожалению, он слишком большой (кажется 16x16 пикселей), по этому придется его упростить в будущем
  • а во-вторых, честный способ рисования не подходит. Под честным я подразумеваю удаление его со старой позиции и рисование в новой. Из-за такого подхода очень сильно видно мерцание
GIF
Гифка немного искажает реальное изображение, но мерцание всё еще заметно. В жизни оно гораздо сильнее видно


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

GIF
Мерцание ушло, но возникла новая проблема :)


 А чтобы при движении не оставалось шлейфа, то я просто увеличил ширину "спрайта" на 1 пиксель в каждую из сторон. Именно на такое расстояние может двигаться динозаврик за одно обновление кадра.
Плюс сразу добавил анимацию. Она очень простая, это просто два разных "спрайта", в каждом из которых поднята вверх разная нога)

GIF
Топ топ топ...


"Спрайтами" я называю их лишь условно. Потому что, по факту это не спрайты)
Показать как выглядит динозаврик на самом деле? Вот, смотрите: 

Wake up, Neo
Wake up, Neo


Ладно, может не совсем так, но достаточно похоже))

Если отдалиться и прищуриться, то даже можно его разглядеть
Если отдалиться и прищуриться, то даже можно его разглядеть


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

GIF
Вииииии


На данном этапе я окончательно убедился в том, что с такой скоростью это неиграбельно. А это еще даже нет других обьектов, типа кактусов и птиц :( 
В ходе экспериментов пришлось понизить детализацию (хотя казалось бы, куда уж меньше) до размера в 8x9 пикселей.
Также решил поменять ему цвет, чтобы оставить зеленый для кактусов. Плюс так он будет меньше сливаться с травой

GIF
Во, теперь я доволен скоростью :)



Кактусы

С ними всё не очень сложно. Они не имеют анимаций, никуда не прыгают и не требуют какой-то детализации. 
Для начала я создал три разных варианта. Рисуются они по очереди. На данных момент я не придумал как рисовать их случайным образом. Никаких генераторов случайных чисел в приставке нет( 
Но ничего, решу этот вопрос когда-то в будущем) 

GIF
Гифка уже перестала передавать плавность движений. Но поверьте на слово, она там есть)


Выглядит уже почти как настоящая игра. Но в ней не хватает одной важной детали -- обработки столкновений. На данный момент динозаврик может просто пройти мимо кактуса)

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

GIF
Теперь можно проиграть!


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

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