javascript

Как я сделал игру для Яндекс Игр

  • пятница, 18 июля 2025 г. в 00:00:05
https://habr.com/ru/articles/928654/

Всем привет! Меня зовут Игорь, и в свободное время я занимаюсь созданием игр.

Вчера я выпустил свою первую публичную игру «Дом до небес». Это простая в которой нужно ставить блоки этажей, чем ровнее тем лучше, этому мешает раскачивающийся крюк, и шатающееся здание. Игра похожая на ту, в которую я играл в детстве, когда телефоны ещё были кнопочными.

Ссылка на игру

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

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

Я начал с того, что подумал, а какую игру я хочу выпустить.

  1. Я понял что эта игра должна быть небольшая

  2. Я понял что эта игра должна увлекать людей

  3. Из видео я подчерпнул что успеха скорее всего не будет :(, , но можно взять за основу существующую игру, добавив свои элементы (например таблица лидеров и изменение баланса в игре) и графику.

Определившись с этими пунктами, я начал искать небольшие игры, которые мне нравились, и наткнулся на Tower Building Game — ту самую игру, в которую я играл на телефоне ещё в школе.

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

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

Что касается меня, я с энтузиазмом взялся за код. Вся разработка заняла около двух недель. По пути возникало множество вопросов и решений. Часть работы пришлась на мой отпуск, а часть — на период после него. Пришлось совмещать: днём — работа, вечером — разработка игры (здравствуй, недосып из-за ночного кодинга!). В последствии я ещё взял на себя составление звуков и музыки. Было сложно, но, как говорится, нет ничего невозможного, у меня уже есть громадный опыт кодинга (моя основная работа) и отдельно занимался в свободное время звуками и музыкой для моих предыдущих игр.

Тут я думаю стоит описать несколько вещей которые мне очень помогли для публикации игры.

  1. Локализация

    Составил фразы с помощью переводчика, вот в таком виде

    var lang = {
    'ru': {
    'start': 'НАЧАТЬ',
    'leaders': 'Лидеры',
    'leadersall': 'Лидеры за всё время',
    ...
    },
    'en': {
    'start': 'START',
    'leaders': 'Leaders',
    'leadersall': 'All-time Leaders',
    ...
    },
    'tr': {
    'start': 'BAŞLAT',
    'leaders': 'Liderler',
    'leadersall': 'Tüm Zamanların Liderleri',
    ...
    }
    };

    Во всех местах где текст вставлял фразу из lang напримерlang[language].leadersall для фразы Лидеры за всё время. Ну и функцию которая автоматически делает это для html

    function updateTexts(langCode) {

    const currentLang = lang[langCode];

    $('[data-lang]').each(function () {

    const key = $(this).data('lang');

    if (currentLang[key]) {

    $(this).html(currentLang[key]);

    }

    });

    if (window.playerName) { document.getElementById('authStatus').innerHTML = lang[langCode].authSuccess + '<strong>' + window.playerName + '</strong>'; document.getElementById('authButton').textContent = lang[langCode].authButton; document.getElementById('authButton').onclick = handleLogout;

    }

    }

    Вызывал её в начале и когда меняют язык в таких блоках <div data-lang="language">

  2. Добавил лидерборд, сначала хранения было в бд на моём сервере, потом перенёс в яндекс

    ysdk.leaderboards.getEntries('HeightLimitALL', { quantityTop: 20})
    .then(res => {$('#over-modal-leader').show();$('#loading-indicator').hide();setLeaders(res)});

    function setLeaders(curleaders){
    let html = '

    ' + lang[language].leadersall + '

    1. '; if(curleaders && curleaders.entries) { curleaders.entries.forEach(function (item) { html += '

    2. ' + item.player.publicName + '' + item.score + '

    3. '; }); } html += '

    '; $('#setleaderboard').html(html); }

  3. Самое сложное было для меня в адаптиве (яндекс по сути требует чтобы игра почти не менялась с изменением размера экрана, у меня же было разное отображение для разных экранов) и в запуске Game Reay API (api яндекса которое управляет игровым процессом и рекламой)

    Подгрузка api яндекс (не знаю как это у них работает но он у них загружается и после того как загрузился похоже есть ещё какая-то подгрузка), сначала я поставил его после моей подгрузки ресурсов, но в итоге пришлось перенести перед ней когда весь dom (весь html обработался в браузере если по простому) уже загрузился. Было настолько же сложно насколько я это описал )

    В конце концов я его поставил так

    window.addEventListener('load', function (ev) {
    domReady = true;
    if (typeof YaGames !== 'undefined') {
    YaGames.init().then(ysdk => {
    window.ysdk = ysdk;

    window.addEventListener('load', function (ev) {
      domReady = true;
      if (typeof YaGames !== 'undefined') {
      YaGames.init().then(ysdk => {
      window.ysdk = ysdk;
      // Включаем полноэкранный режим
      ysdk.features.LoadingAPI?.ready();
      //тут установка языка, уже в этот момент можем его взять из api яндекс
      const playerLanguage = ysdk.environment.i18n.lang;
      if (playerLanguage && lang[playerLanguage]) {
          language = playerLanguage;
          updateTexts(language);
      }
    задержка 300 в settimeout
    Далее начальные функции игры, подгрузка ресурсов у меня занимает короткое время

В целом модерация оказалось самым сложным этапом для меня.

Я изрядно потратил нервов, переживая, пройдёт ли игра проверку. У платформы много требований, и я не все правильно понял.

Например системный плеер браузера не должен показываться когда играет музыка (я прочитав пояснение к требованию вместо самого требования подумал что наоборот должен...). В итоге поставил музыку и звуки так this.audioContext = new (window.AudioContext || window.webkitAudioContext)(); так как стандартный для html audio как раз используется системным плеером.

В целом пунктов было больше но остальное решалось легко. Модерацию отклоняла игру 2 раза.

В итоге игра прошла модерацию, и теперь в неё можно играть!

Спасибо, если дочитали до конца. Буду рад советам, рекомендациям и отзывам. Если есть вопросы — задавайте в комментариях, постараюсь ответить.