Разработка простой игры на платформе 1С своими руками

· 9 мин

Содержание

Игру на 1С пишут во встроенном языке — обычно как внешнюю обработку с расширением .epf и управляемой формой. Поле игры рисуют элементами формы, правила описывают в модуле формы, а рекорды хранят в самой базе. Отдельный «движок» не нужен: хватает Конфигуратора и пустой информационной базы.

Платформа не рассчитана на динамичную графику, поэтому речь о пошаговых и логических играх: крестики-нолики, викторина, 2048, сапёр, «угадай число». Это отличный способ потренировать язык 1С на живой задаче, а не на абстрактных примерах.

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

Подойдёт ли 1С для разработки игр

1С — это платформа для учётных систем, а не игровой движок. У неё нет аппаратного ускорения графики, физики и высокой частоты кадров. Форма перерисовывается по событиям, а не 60 раз в секунду.

Из этого следуют честные ограничения:

  • 🎯 отлично идут пошаговые и логические игры — ход игрока, затем реакция программы;
  • 🧩 нормально работают головоломки с полем из клеток;
  • 🐌 аркады с плавным движением (змейка, тетрис) возможны через таймер, но это уже потолок — рывками и медленно.

Зачем тогда вообще писать игру на 1С? Причина практичная: это тренажёр. В игре есть состояние, условия, циклы, обработка ввода и хранение данных — тот же набор, что в реальной обработке документов. Разобравшись с игрой, вы спокойнее читаете чужой код конфигурации.

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

Что можно сделать: жанры и механики

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

ЖанрПримерЧто потребуется
Текстовая/числоваяУгадай число, викторинаПоле ввода, кнопки, вывод текста
Клеточная логикаКрестики-нолики, сапёрСетка кнопок или табличный документ
Головоломка2048, пятнашкиМассив чисел + перерисовка поля
Аркада на таймереЗмейкаОбработчик ожидания + сетка

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

Не начинайте со змейки или тетриса. Движущиеся объекты требуют игрового цикла и аккуратной перерисовки, на этом новички вязнут. Сначала — что-то пошаговое.

Что понадобится для старта

Набор минимальный, всё бесплатно или уже стоит на рабочем месте:

Перед тем как писать игру
Выполнено: 0 / 4

Отдельную лицензию для разработки обычно даёт учебная версия платформы — её можно скачать и использовать для обучения. Полноформатных конфигураций (Бухгалтерия, ЗУП) для игры не нужно: подойдёт пустая база без конфигурации.

Интерфейс на всех актуальных версиях 8.3 — «Такси». Все пути и названия ниже даны именно для него.

Создаём обработку и игровую форму

Игра живёт во внешней обработке. Создаём её так:

  1. В Конфигураторе: Файл → Новый, в списке выберите Внешняя обработка.
  2. Задайте имя обработки, например УгадайЧисло (латиницей или кириллицей без пробелов).
  3. В дереве обработки встаньте на ветку Формы и добавьте новую форму — Форма обработки.

Теперь наполняем форму. У формы два слоя: реквизиты (данные, которые помнит форма) и элементы (то, что видит игрок).

Добавьте реквизиты формы:

  • ЗагаданноеЧисло — тип Число;
  • Догадка — тип Число (сюда игрок вводит свой вариант);
  • Попыток — тип Число;
  • Результат — тип Строка (сообщение игроку).

Перетащите Догадка и Результат на форму — получите поле ввода и поле вывода. Затем на вкладке команд формы создайте две команды, НачатьИгру и Проверить, и вынесите их на форму кнопками. У каждой команды в свойствах укажите одноимённый обработчик — платформа создаст пустые процедуры в модуле формы.

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

Состояние клеток при этом удобно держать не в самих кнопках, а в отдельной структуре — например, в одномерном массиве из девяти элементов для поля 3×3. Кнопки только показывают содержимое массива, а вся логика (чей ход, есть ли победа) работает с массивом. Так проще проверять правила и перезапускать партию: достаточно очистить массив и обновить надписи на кнопках.

Программируем игровую логику

Вся игра — это код в модуле формы. Разберём на примере «угадай число». Логика простая: программа загадывает число от 1 до 100, игрок называет варианты, программа подсказывает «больше» или «меньше» и считает попытки.

Клиент и сервер: почему код в двух контекстах

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

  • &НаКлиенте — выполняется на компьютере игрока. Здесь живут обработчики кнопок, реакция на ввод, перерисовка формы.
  • &НаСервере и &НаСервереБезКонтекста — выполняется на стороне базы. Отсюда доступны объекты, которых нет на клиенте, и запись данных.

Для игры деление важно по двум причинам. Объект ГенераторСлучайныхЧисел создаётся на сервере, поэтому загадывание числа вынесено в серверную функцию. Запись рекорда в базу — тоже серверная операция. А вся «движуха» с кнопками и полями — клиентская.

Клиент не видит серверные переменные напрямую: данные между контекстами передают через реквизиты формы и параметры процедур. Приписка БезКонтекста означает, что серверной процедуре не нужны данные формы — такой вызов быстрее.

Случайное число получаем на сервере — объект ГенераторСлучайныхЧисел создаётся там:

&НаСервереБезКонтекста
Функция ЗагадатьЧисло()
    Генератор = Новый ГенераторСлучайныхЧисел;
    Возврат Генератор.СлучайноеЧисло(1, 100);
КонецФункции

Метод СлучайноеЧисло(1, 100) возвращает целое число в диапазоне включительно. Обработчик кнопки «Начать игру» вызывает эту функцию и обнуляет счётчики:

&НаКлиенте
Процедура НачатьИгру(Команда)
    ЗагаданноеЧисло = ЗагадатьЧисло();
    Попыток = 0;
    Догадка = 0;
    Результат = "Я загадал число от 1 до 100. Попробуйте угадать.";
КонецПроцедуры

Теперь главный обработчик — проверка догадки:

&НаКлиенте
Процедура Проверить(Команда)
    Если ЗагаданноеЧисло = 0 Тогда
        Результат = "Сначала нажмите «Начать игру».";
        Возврат;
    КонецЕсли;

    Попыток = Попыток + 1;

    Если Догадка < ЗагаданноеЧисло Тогда
        Результат = СтрШаблон("Загаданное больше. Попытка №%1", Попыток);
    ИначеЕсли Догадка > ЗагаданноеЧисло Тогда
        Результат = СтрШаблон("Загаданное меньше. Попытка №%1", Попыток);
    Иначе
        Результат = СтрШаблон("Верно! Вы угадали за %1 попыток.", Попыток);
        СохранитьРекорд(Попыток);
    КонецЕсли;
КонецПроцедуры

Обратите внимание на СтрШаблон — через него число подставляется в строку. Склеивать число со строкой через + в 1С нельзя — будет ошибка несовпадения типов. Используйте СтрШаблон(...) или Формат(Число, "ЧГ=0").

Процедуру СохранитьРекорд разберём в следующем разделе. Этот код уже рабочий: вставьте процедуры в модуль формы, запустите обработку и играйте.

Если игре нужен таймер

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

&НаКлиенте
Процедура НачатьИгру(Команда)
    ПодключитьОбработчикОжидания("Такт", 1);
КонецПроцедуры

Интервал задаётся в секундах. В процедуре Такт() на каждом шаге сдвигаете объект, проверяете столкновения и перерисовываете поле. Когда игра окончена, цикл останавливают: ОтключитьОбработчикОжидания("Такт").

Сохранения, рекорды и настройки

Реквизиты формы живут только пока открыта форма — после закрытия обработки они обнуляются. Чтобы рекорд пережил перезапуск, его нужно записать в базу.

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

&НаСервереБезКонтекста
Процедура СохранитьРекорд(Попыток)
    Рекорд = ХранилищеОбщихНастроек.Загрузить("ИграУгадайЧисло", "Рекорд");
    Если Рекорд = Неопределено ИЛИ Попыток < Рекорд Тогда
        ХранилищеОбщихНастроек.Сохранить("ИграУгадайЧисло", "Рекорд", Попыток);
    КонецЕсли;
КонецПроцедуры

Метод Загрузить возвращает Неопределено, если значения ещё нет, — поэтому первый рекорд запишется всегда, а дальше только при улучшении результата. Так же хранят настройки: сложность, размер поля, имя игрока.

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

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

Отладка: как находить ошибки

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

Чтобы пошагово пройти свой код:

  1. Убедитесь, что в свойствах базы и в запускаемом сеансе разрешена отладка — иначе Конфигуратор не подключится к процессу.
  2. Поставьте точку останова в модуле формы: встаньте на строку и нажмите F9. Строка подсветится.
  3. Запустите игру в режиме отладки через меню Отладка → Начать отладку.
  4. Когда выполнение дойдёт до точки, оно замрёт. Дальше:
    • F11 — шаг с заходом внутрь вызываемой процедуры;
    • F10 — шаг без захода (процедура выполнится целиком);
    • F5 — продолжить до следующей точки.

Текущие значения переменных смотрите в окне Табло (туда перетаскивают имена переменных) или наведя курсор на переменную в коде. Так видно, что реально лежит в Догадка и ЗагаданноеЧисло на каждом шаге.

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

  • Кнопка «ничего не делает». Обработчик стоит не на той команде или назван иначе, чем указано в свойствах команды. Проверьте в свойствах команды привязку к процедуре.
  • Ошибка про недоступный объект. Серверный объект (тот же ГенераторСлучайныхЧисел) пытаются создать в клиентской процедуре. Вынесите этот код в процедуру с директивой &НаСервере.
  • Поле на форме не меняется. Значение присвоили не реквизиту формы, а локальной переменной с похожим именем. На экран выводятся только реквизиты формы, связанные с элементом.

Эти три случая покрывают большую часть «молчаливых» сбоев, когда ошибки нет, но игра ведёт себя не так, как задумано.

Как распространять готовую игру

Внешняя обработка — это один файл .epf. Передать игру можно тремя способами.

  • 📎 Просто файлом. Отдаёте .epf, получатель открывает его через Файл → Открыть в режиме 1С:Предприятие. Способ требует прав на открытие внешних обработок и подходит для коллег-разработчиков.
  • 📚 Через справочник дополнительных обработок. Если в конфигурации есть подсистема дополнительных отчётов и обработок, игру подключают туда — тогда её запускают обычные пользователи из меню, без открытия файлов вручную.
  • 🧩 Встроить в конфигурацию. Обработку переносят в дерево конфигурации как встроенную. Так делают, если игра — часть внутреннего корпоративного решения (например, обучающий тренажёр).

Для большинства домашних экспериментов хватает первого способа: сохранили .epf, отправили, открыли. Исходный код обработки открыт — любой сможет посмотреть, как всё устроено, и доработать под себя.

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

Частые вопросы

Нужна ли лицензия, чтобы написать игру в 1С?
Для разработки и обучения подойдёт учебная версия платформы. Для запуска в обычной базе нужна действующая лицензия платформы — без неё 1С:Предприятие базу не откроет.
В какой конфигурации делать игру?
Ни в какой конкретной. Внешняя обработка работает поверх пустой информационной базы без конфигурации. Бухгалтерия, ЗУП и прочие прикладные решения для игры не требуются.
Можно ли сделать игру с картинками и анимацией?
Статичные картинки — да, через элементы формы и реквизиты типа «Картинка». Плавной анимации платформа не даёт: обновление идёт по событиям и таймеру, поэтому движение получается рывками.
Почему игра забывает рекорд после закрытия?
Реквизиты формы хранятся только пока форма открыта. Чтобы рекорд сохранялся, записывайте его в хранилище общих настроек или в файл — тогда он переживёт перезапуск.
С какой игры начать новичку?
С числовой («угадай число») или клеточной (крестики-нолики). В них вся сложность — в логике, а интерфейс простой. Движущиеся аркады оставьте на потом.