Загрузочный экран игры
Загрузочный экран игры

Идея заняться этим возникла после участия в качестве члена жюри последнего Технотекста (я оценивал статьи из хаба DIY и научпоп). Поначалу для меня было удивительно, зачем тратить столько времени на (казалось бы) странные вещи? Газоразрядная Хабралампа, радиотелескоп в сарае, разработка радиоуправляемой машинки с нуля.

А потом как понял…И сделал игру для дочки. Она несколько раз играла в Lode Runner в эмуляторе, и попросила меня сделать что‑нибудь для нее.

С 1987 года у меня перебывало много компьютеров: «Сура», «БК», «Спектрум», какие‑то древние приставки «Атари» и что‑то еще. ZX Spectrum мне нравился больше всего. Много игр, отличная графика, звук. Даже на бипере!

Его собрал для меня отец, когда мне было лет 11–12. Комплектация была суперской: TR‑DOS, ч/б монитор Корвет, корпус от «Суры» с прекрасной герконовой клавиатурой (это вам не «дубовая» «Дубна»!), два дисковода (тоже от «Суры», емкость дисков 640 КБ, насколько помню).

Естественно, я очень хотел делать игры, но литературу, кроме сборников «500 игр» и книжек по Бейсику, купить или достать было негде. Готовые движки и всякие Wham The Music Box и Laser Basic были уже тогда, но не было знаний, как с ними дружить.

Поэтому, кроме бейсиковских игроподелок с псевдо‑ или «проволочной» графикой, я ничего не успел сделать. Лет в 14 лет мой «Спектрум» сгорел, и мне пришлось пересаживаться на 286 с MS DOS. Я не хотел, честно.

Лет в 15 писал для PC игрушки на Microsoft Quick Basic (порт Defender of the Crown — я тогда не знал, что эта игра написана для персоналок еще в 80-е). У него были классные библиотеки для работы с графикой. Для спрайтов я использовал коды ассемблера. Позже на С++ создал что‑то типа Tapper и прочее очень простое.

Но все же игра появилась 30 лет спустя после того, как я что‑то делал на живом «Спектруме». 

Пару недель я изучал движки, редакторы спрайтов и графики, музыкальные программы. О них есть на Хабре статья Михаила Судакова @mikhailsudakov (Яндекс.Музей).

Из всего, что попробовал, выбрал движок Dizzy SE Валерия Сурженко, графический редактор ZX‑Paintbrush и музыкальный редактор Vortex Tracker II Сергея Бульбы. На сайте автора последняя игра датируется 2020 годом.

Авторы DizzyAge (редактор карт в Dizzy SE): Alexandru Simion и Cristina Simion.

Авторы оригинальных игр и владельцы прав на вселенную Диззи: Oliver Twins и Codemasters.

Скриншот сайта dizzy-se.ru
Скриншот сайта dizzy‑se.ru

Мне удалось связаться с автором. Прилагаю его историю целиком.

Обо мне.
Сурженко Валерий Витальевич. В спектрумовских кругах известен как Hippiman. Живу в южном городе Ростове‑на‑Дону. Сейчас работаю Java‑программистом, занимаюсь разработкой высоконагруженных распределённых бэкенд‑приложений.

Spectrum‑ом и программированием вообще заболел ещё в детстве, когда родители подарили мне на день рождения отечественный 48-килобайтный клон. Какой модели он был, к сожалению, не знаю, так как был он самостоятельно собран одним из знакомых отца.

Клон этот до наших дней не дожил, зато рабочей машинкой у меня сейчас выступает ZX Evolution rev.b. Зверь‑машина, для Baseconf которой мной было разработано несколько игр.

О Dizzy SE
Что вообще такое Dizzy? Это неофициальный маскот ZX Spectrum в странах СНГ. Об огромной популярности этого персонажа можно судить по одному только количеству фанатских игр, выпущенных в 90-е — 2000-е. Было даже несколько попыток сделать редакторы для Dizzy‑игр.

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

Разработка каждой новой игры про Dizzy под ZX Spectrum всегда таила в себе целый ряд сложностей. Исторически движки Dizzy оперировали в качестве игровых объектов таким понятием, как «спрайты». Это не то же самое, что спрайты в современном понимании этого слова. Это понятие ближе к современному термину «префаб». В смысле, это заранее описанный объект со всеми характеристиками и единожды заданной графикой.

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

Другая сложность — это логика. Всё взаимодействие с объектами, будь то диалог с Дензилом или набор воды в ведро, писалось на ассемблере точно так же, как и весь остальной код. Это позволяло вытворять с игрой что угодно — вплоть до переворачивания мира кверху ногами, как в Dizzy 3, но ассемблерный код есть ассемблерный код.

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

С другой стороны, есть открытый движок DizzyAge для создания игр под Windows. Он использует совершенно другой подход — современный. Вся игра разделяется на две части. Движок — единожды скомпилированный, который нельзя и не нужно изменять, и который берёт на себя всю низкоуровневую работу. И саму игру — графику, карты, скрипты и прочее.

Для построения игрового мира DizzyAge использует систему «брашей». Это некая область тайловой карты с уникальными параметрами, то есть тут нет заранее подготовленных объектов. Если нам нужно использовать для какой‑то области карты половинку камня, а не целый, то мы создаём браш из половинки камня. Либо дублировать одно изображение множество раз.

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

Dizzy SE — это перенос идеологии DizzyAge с IBM PC на ZX Spectrum со всеми вытекающими: подход к построению мира на основе брашей, логика на основе скриптов и полная изоляция от аппаратной начинки компьютера ценой потери некоторой гибкости и быстродействия.

Зато вся игра от и до создаётся на ПК в графических интерфейсах, без необходимости вручную что‑то программировать на ассемблере, собирать образы и прочее. Чтобы создать хорошую игру, конечно, всё равно придётся напрячь голову и разобраться, но уже не в архитектуре компьютера и тонкостях вывода графики, а в скриптовании логики и работе с редакторами, что, согласитесь, намного проще.

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

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

Источник: интервью с Валерием Сурженко на idpixel.ru

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

Почему движок и именно этот, а не с нуля:

  • Я вполне понимал на старте объем работы — музыка, загрузочные экраны, спрайты, программная часть. Начал изучать инструменты в январе с большими перерывами, а закончил игру только во второй половине июля.

  • Создать что‑то играбельное на Си или ассемблере с нуля — я бы и за год не справился. Я преклоняюсь перед ребятами, которые это делают. Можно посмотреть, например, работы с конкурса ретро‑игр YRGB

  • У «Спектрума», в отличие от того же Commodore, не было встроенных спрайтов, и уровень программирования для него должен быть действительно высоким. Даже с учетом того, что в Dizzy SE скриптовый язык, для меня это тоже программирование (последние лет 15 я ковыряю только чужие PHP‑коды и это не основная специальность).

  • Мне хотелось сделать несложную игру, которую можно пройти за несколько минут. 

  • Dizzy — беспроигрышный вариант. Здесь и подумать, и попрыгать и в диалогах поучаствовать можно.

Я определил такие критерии:

  • Всего один экран.

  • Максимум характерных черт из игр про Диззи.

  • Красивая графика и анимация.

  • Понятный порядок действий без инструкций.

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

Героев проще представить картинкой (я намеренно взял изображения героев из первых игр):

Экран с меню
Экран с меню

❯ Загрузочный экран

Шаблонный экран движка такой:

Скриншот из шаблонов игры
Скриншот из шаблонов игры

Собственно, до загрузочного экрана не было до конца продуманной идеи. А начинать всегда сложно. Я сделал наброски главного героя, который чистит снег. Несколько раз перерисовывал картинку полностью. В итоге вокруг Диззи начал формироваться загрузочный экран, второстепенные герои и сюжет.

Первые потуги
Первые потуги

Скриншот программы графического редактора:

ZX-Paintbrush
ZX‑Paintbrush

В итоге в игру вошли не только члены семьи Диззи, а еще летучая мышь и белка.

Так бы заставка выглядела на «настоящем Спектруме»
Так бы заставка выглядела на «настоящем Спектруме»

Я знаю, что белка зимой меняет цвет, но сделать хотя бы серую белку на белом фоне не получится. Думаю, многим читателям известна основная проблема графики в «Спектруме»: 2 цвета на знакоместо 8×8 пикселей при разрешении экрана 256×192 и атрибуты яркости и мигания.

❯ Экран меню

Шаблонный экран с меню такой:

Скриншот из шаблонов игры
Скриншот из шаблонов игры

Я решил переделать его и показать сочетания клавиш, так как непонятно, что такое «классика», и какой синклер — I или II. В итоговый экран меню добавил имя дочки, чтобы ей было приятно.

For Sonya
For Sonya

❯ Тайлы

Исходный файл с тайлами выглядит примерно так (на момент написания статьи я успел его испортить немножко):

Скриншот из шаблонов игры
Скриншот из шаблонов игры

А вот то, что получилось у меня:

Я оставил элементы для камина — камни (перекрасил в серый цвет), огонь, плюс дверь, стену, яйцо‑жизнь.

Перерисовал Дейзи (в исходном изображении у нее длинные ноги и каблуки, для зимы не подойдет), дерево для белки с дуплом, нарисовал портрет Дейзи (как в первых сериях Диззи), добавил к люстре анимацию — свечи.

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

Два варианта белки
Два варианта белки
Анимация роста и вращения желудей, которая в итоге не сработала
Анимация роста и вращения желудей, которая в итоге не сработала

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

Самым непростым оказалась анимация дедушки Диззи, которого я решил посадить в кресло‑качалку.

Кстати, есть несколько особенностей работы с тайлами, кроме анимации. Файл с тайлами сделан в формате BMP. Если попробовать работать с ним в ZX‑Paintbrush, слетает таблица цветов, и вы получаете что‑то такое (желтая белка с синим носом):

Потихоньку разбираемся с движком
Потихоньку разбираемся с движком

Поэтому я промучался день, а потом перерисовал исходные тайтлы в Photoshop. Пользоваться им для тайлов и спрайтов в разы удобнее, чем ZX‑Paintbrush.

❯ Спрайты

Здесь есть жесткое ограничение: размеры и последовательность спрайтов изменить нельзя. Цветной фон — прозрачный.

Скриншот из руководства движка
Скриншот из руководства движка

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

Мои спрайты
Мои спрайты

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

Скриншот из шаблонов игры
Скриншот из шаблонов игры

❯ Карта

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

Скриншот из раздела руководства динамических объектов
Скриншот из раздела руководства динамических объектов

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

Последний вариант (цвет ключа другой, хочется использовать всю палитру):

Самое неприятное, что в случае любой ошибки игра виснет.

Так:

Или даже так:

Примерно такое я увидел, когда сгорел мой комп
Примерно такое я увидел, когда сгорел мой комп

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

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

На этом скриншоте показаны свойства объекта «дупло». Это динамический объект с id=200, материал «воздух» (прозрачный) и свойство — предмет.

В других вкладках находятся технические параметры (в том числе неработающий признак слоя):

Пользовательские данные (номер диалога или скрипт действия):

В данном случае при подборе «дупла» игроком показывается диалог 21:

❯ Скрипты и диалоги

Наверное, это самая долгая часть процесса. Описание движка несколько куцевато, несмотря на примеры. Поэтому до многих мелочей (например, я путал поначалу перерисовку спрайтов и перерисовку объектов) приходилось додумываться самому.

Скриншот интерфейса движка (журнал сборки проекта, редактор диалогов и редактор скриптов):

Всего у меня получилось 23 диалога и 9 скриптов. 

Скрипт инициализации игры создается автоматически — в нем я дописал обработчики событий.

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

Дописал скрипт перемещения в начальную точку:

На этом скриншоте показан скрипт проверки окончания игры:

Рассмотрим его подробнее. В нем мы проверяем первое ли это касание, и если да, выводим диалог и отключаем дедушку, чтобы диалог не повторялся.

// ========================================================
// СКРИПТ ПОКАЗА СООБЩЕНИЯ ПРИ ПОПЫТКЕ ДИАЛОГА С ДЕДУШКОЙ
// ========================================================

// Проверяем, был уже диалог или нет
objget(this, O_STATUS) // Забираем статус объекта "Дедушка"
eq(ret, 1, already_activated) // Если диалог был, переходим на метку already_activated 

// Первый диалог
redraw_sprites() // В движке спрайты во время диалогов не перерисовываются, видимо, для экономии ресурсов Спекки.

showmessage(2, 8, 14, CL_YELLOW, CL_WHITE, 1)  // Показываем сообщение "Дедушка спит, не буди его, пока все дела не переделаешь"

objset(this, O_STATUS, 1) // Отключаем дедушку
set(ret, NO_INVENTORY) // Инвентарь не показываем

redraw_screen() // Перерисовываем экран
goto(exit) // Выход
// ==============================================================
// ПРОВЕРКА УСЛОВИЙ ОКОНЧАНИЯ ИГРЫ - ДВЕРЬ ОТКРЫТА, СНЕГ ПОЧИЩЕН
// ==============================================================
already_activated:

set(j, ret)
// Проверяем дверь
objroomfind(5, 0, 0) // id двери = 5
set(a, ret) // Записываем статус в переменную
objget(a, O_STATUS) // Проверяем статус
ne(ret, 1, door_not_open) // Если дверь не открыта, выходим

// Проверяем снег
objroomfind(99, 0, 0) // id снега = 99
set(a, ret) // Записываем статус в переменную
objget(a, O_STATUS) // Проверяем статус
ne(ret, 1, snow_not_cleared) // Если снего не расчищен, выходим

// Если все условия выполнены

// Дедушку перерисовываем без кресла-качалки
// Спрайты можно позиционировать по пикселям, а вот тайлы - кратно 8
objset(this, O_MAP_X, 0) // 0
objset(this, O_MAP_Y, 29) // 232:8

// Перемещаем Дейзи в дом
objroomfind(150, 0, 0)  // ID=150 в комнате (0,0)
set(d, ret)

// Меняем координаты (делим на 8! пиксели)
objset(d, O_X, 18)   // Новая X позиция
objset(d, O_Y, 13)    // Новая Y позиция

redraw_object(d) // Перерисовываем Дейзи
redraw_screen() // Перерисовываем экран

// Получаем текущее количество монет
gameget(PL_COINS)
set(a, ret)  // Сохраняем в переменную A

// Проверяем
eq(a, 0, show_coin_not_found)      // 0 монет
gt(a, 0, coin_found)  // Больше 0 монет

// Монета не найдена
goto(show_coin_not_found) // Показываем диалог, когда игра завершена, но монета не найдена

coin_found:
    redraw_sprites()
    showmessage(1, 8, 22, CL_GREEN, CL_WHITE, 1)  // "Победа и монета найдена!"
    goto(after_coin)

show_coin_not_found:
    redraw_sprites()
    showmessage(1, 8, 23, CL_YELLOW, CL_WHITE, 1)  // "Победа, но монета не найдена"

after_coin:
    redraw_screen()
    redraw_sprites()

    // Задержка 10 секунд
    //wait(500)

    // Возврат в меню
    gameset(PL_GAME_OVER, true)
    redraw_screen()

set(ret, NO_INVENTORY)
goto(exit)

// На всякий случай оставлю под ошибки.

door_not_open:
//showmessage(2, 8, 8, CL_YELLOW, CL_WHITE, 1)
    goto(exit)

snow_not_cleared:
//showmessage(2, 8, 2, CL_YELLOW, CL_WHITE, 1)
    goto(exit)

door_not_found:
showmessage(2, 8, 0, CL_YELLOW, CL_WHITE, 1)
    goto(exit)

snow_not_found:
showmessage(2, 8, 1, CL_YELLOW, CL_WHITE, 1)
    goto(exit)

coin_not_found:
    goto(exit)

daisy_not_found:
    goto(exit)

exit:
Тайлы для дедушки Диззи
Тайлы для дедушки Диззи

❯ Музыка

Про работу с музыкой нужна отдельная статья с обзорами редакторов. Не буду раздувать этот пост и рекомендую почитать Александра Семенова @shiru8bit про ретро‑музыку.

Я сделал простенькую мелодию в размере 5/4 на своей блокфлейте, после чего добавил бас и стандартную «бренчалку» в Vortex Tracker II. Пришлось немного помучаться с орнаментами. В итоге получилось трехголосое фолк‑вступление для игры.

Фото моего блочка Kung
Фото моего блочка Kung

Задержусь только на одном моменте. Я потратил пару дней на изучение того, как работать с музыкой. У процессора AY-3-89XX есть возможность «скользящих» нот. Чем я и воспользовался в самом начале мелодии. 

На скриншоте показа команда, которая реализует скольжение от ноты «ре» шестой октавы до «ля» пятой.

Скриншот программы Vortex Tracker II
Скриншот программы Vortex Tracker II

❯ Результат

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

Игра немного тормозит из‑за большого количества анимации. Но уменьшать число движущихся объектов мне не хочется. Тем более, всего один экран.

Теперь я понимаю, почему над играми работало минимум 3 человека. Один отвечал за графику, другой за музыку, третий за код. А что творили мастера, которые делали музыку под бипер...Это космос.

Игру можно пройти за минуту. Хотя я и показал вам, где монетка, попробуйте догадаться, какая роль у домового?

Рекомендую эмулятор Unreal Speccy. А файл с игрой лежит здесь.

Может быть интересно:
Перейти ↩

Новости, обзоры продуктов и конкурсы от команды Timeweb.Cloud — в нашем Telegram‑канале 

Комментарии (5)


  1. Li_Lu09
    05.08.2026 08:32

    какой классный проект и классная статья! за визуал - отдельный респект)


  1. lleo_aha
    05.08.2026 08:32

    Титаническая работа! Интересно, оно скрипты свои всё же компилит в ассемблер, или чтото типа P-Code и по факту в движок интерпретатор вшит?


    1. wilelf Автор
      05.08.2026 08:32

      Там в итоге образ дискеты получается. Т.е. компилируется в формат TR-DOS.


      1. lleo_aha
        05.08.2026 08:32

        Та я не совсем об этом. Нашёл уже сам, в принципе. Если кому то интересно - то в движке именно интерпретатор получающихся .gs файлов. Интересно почему автор не пошёл чуть дальше и не сделал компилятор скриптов в asm - на PC возможностей больше, а результат по идее был бы компактнее...


  1. nopecomments
    05.08.2026 08:32

    приставки «Атари» и что‑то еще. ZX Spectrum мне нравился больше всего. Много игр, отличная графика, звук. Даже на бипере!

    отличная шутка, синдром утёнка же. все старые системы прекрасны, но есть объективные вещи всё же.