Я смог и вы сможете: делаем RPG на JavaScript

в 15:53, , рубрики: edisonsoftware, javascript, Блог компании Edison, игра, Программирование, проектирование, разработка, разработка игр, учимся кодить

image

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

Я боялся использовать объекты, например. Они были такой большой страшной вещью, которую я откладывал на потом. Но сейчас я использую их все время.

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

Имейте в виду, что я новичок (всего 2 месяца в программировании), поэтому некоторые мои решения можно улучшить. Я же постараюсь дать вам основы, с которых можно начать.


Вот моя игра на CodePen (замечу, что она еще не оптимизирована для мобильных устройств).

Во-первых, выберите цель вашей игры. Это пазл? РПГ? Hack&slash? Ладно, теперь подумайте о технических трудностях её создания. Игра-головоломка потребует много сложного кода JavaScript, Hack & slash требует острожное балансирование и так далее.

Также решите, хотите ли вы, чтобы это была браузерная игра, мобильная игра, или и то и другое.

Например, моя игра не может хорошо поместиться на экране мобильного телефона, поскольку у игрока есть 24 заклинания. Неудобно щелкать эти маленькие кнопки на маленьком экране, поэтому мне нужно будет переделать эту игру для мобильного телефона.

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

  • системы инвентаря;
  • генератор шмоток;
  • параметры игрока;
  • систему сохранялок.

В-третьих, начните делать свою игру, решая эти проблемы одну за другой.

Нужна помощь в самом создании игры?

Гораздо легче разбить игру на мелкие задачи. Ты не делаешь игру, ты делаешь систему инвентаризации. Затем вы делаете боевую систему. И так далее.

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

  • Game-Icons.net  — эти иконки забавные и их легко рисовать
  • Open Game Art  — получите отличные публичные домены
  • Bulk Resize Photos  — отличный инструмент для создания собственных маленьких иконок
  • CSS Sprite Generator  — помогает сделать CSS спрайт-листы для иконок

Проблемы, с которыми я столкнулся и как я их решал

Спрайт-листы

Вы планируете иметь больше чем 20 изображений в вашей игре? Если это так, вы не хотите, чтобы каждое из этих 20 изображений было связано с другим. Вы, возможно, не думаете, что 20 изображений это много, но что если вы решите добавить еще 50? Вот тогда вам пригодятся спрайт-листы: добавьте туда несколько фотографий, скопируйте CSS файл в ваш проект и просто добавьте класс в элемент, который соответствует желаемому изображению.

Сохранение состояния игры

Вы хотите, чтобы ваша игра сохранялась? Вы можете выбрать между браузерным хранилищем и хранением вещей на сервере. Серверы требуют особых знаний. Если у вас их нет, я рекомендую использовать LocalStorage. Он сохраняет игру до тех пор, пока пользователь не удалит ее с помощью какого-нибудь инструмента по очистке. Вот как я это сделал:

image

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

Модулируйте свой код

Выясните, какую часть игры трудно кодировать, и какую часть кода стоит модулировать. Я по ошибке начал кодировать заклинания, которые пошли быстро. Мне нужны были 24 функции наряду с 24 функциями ifCritical.

image
Клянусь я не писал этого… Эээ меня заставили

image
У него даже есть функция, которая добавляет пользовательские функции

Теперь вы можете спросить, как работает второе заклинание? У меня есть функция playerAttack(), которая использует объект заклинания, чтобы проделывать разные вещи:

  • Сначала она запускает обновление функции заклинания, которая вызывает объект заклинания. Затем заклинание берет ваши статистические данные и превращает их в “урон”, “ману” и т.д.
  • Она проверяет урон. Если он больше 0, она наносит урон боссу и отображает урон, который совершило заклинание и его количество. Она делает это для всего остального тоже. Вы можете подумать, что проверка на то больше ли урон 0 бесполезна, но вы подумаете об этом еще раз, когда игра скажет вам, что вы нанесли 0 урона и поэтому восстановили 0 маны.
  • Запускает пользовательскую функцию, если такая есть у заклинания. Её можно использовать, чтобы дать заклинанию особые эффекты, которые невозможны при функции обычной атаки.

Цикл игры

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

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

Но еще есть смерть босса. Её проверку я запускаю каждую секунду с момента начала битвы. Почему? Чтобы игроку не пришлось ждать 20 секунд пока босс умрет. Для некоторых вещей цикл даже не нужен. Функции просто можно вызывать тогда, когда они нужны. Возьмите, например, функцию заклинания. Она нужна только тогда, когда игрок использует заклинание.

Вот, что я узнал:

  • Объекты это хорошо. Когда вам нужно сохранить данные, вам просто нужно сохранить объект, а не 50 отдельных переменных.
  • Всегда задавайте тайм-ауты и интервалы в качестве переменных, чтобы их потом можно было очистить — не делайте этого только в том случае, если это постоянные эффекты и вы уверены, что их потом не придется очищать.
  • Один большой файл JavaScript не самая мудрая идея. CodePen позволяет использовать только один JavaScript файл, но в идеале, вы должны разделить все на модули.
  • Если Вы не беспокоитесь о производительности, вы можете просто скопировать и вставить объект, когда он нуждается в обновлении — нет необходимости обновлять половину значений по отдельности. Если объект огромный, вы даже можете определить его сначала в качестве переменной, как: var object; а затем построить его, используя некоторые другие функции, когда вы хотите его обновить. Я сделал это с моими заклинаниями. Каждый раз, когда игрок использует заклинание, функция updateSpell() сначала определяет объект этого заклинания снова, просчитывает весь урон и статистические данные, а затем вызывает заклинание.

Забавные факты, с которыми мне пришлось смириться:

  • Способность к мане на уровне босса, потому что если бы она была на уровне игрока, я бы наказывал игроков каждый раз, когда у них повышался уровень. Также это сделало бы боссов более высокого уровня гораздо сложнее, чем мне бы этого хотелось.
  • Элементы создаются со всей статистикой, но не отображаются, если они равны 0. Таким образом, мне не нужно проверять определены ли они и я могу не показывать статистику, если они равны 0. Двойная победа!
  • У меня много упрощенных бафов и дебафов. Есть переменные buffStat, nerfStat, totalStat и stat. Поэтому бафы и дебафы никогда не в стеке.
  • С боссами навыки не нерфится до нуля. Все гораздо сложнее. Параметры нерфятся от 9999999, затем проверяет меньше ли она нуля. Если да, то он приравнивает их к нулю. Так что если вам удастся достичь уровня, где параметры будут выражены в миллиардах, мне, возможно, придется добавить больше нулей.

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

Баги и эксплойты

Это поразило меня и испугало немного. Я не мог поверить, что в моем безупречном творении есть баги.

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

Вот несколько багов и эксплойтов, которые всплыли в памяти:

  1. Ты можешь изменить уровень босса во время сражения с ним, и цикл тогда работает лучше.
  2. Индикаторы опыта и маны порой переполняются.
  3. Ты можешь атаковать босса до того как началась битва. Вот так оплеуха!
  4. Мана может стать отрицательной и это не позволит вам выполнять даже базовые атаки, которые являются основным способом восстановить ману.
  5. Лечение временно увеличивает максимальное количество здоровья.
  6. Одно заклинание на самом деле было нерабочим из-за проблем с CSS.
  7. Если ты атакуешь не в бою, то твои заклинания будут находиться на бесконечной перезарядке.

Все это звучит ужасно, не правда ли? В MMORPG, эти вещи с первого же дня все испортят! Ну, хорошей новостью является то, что большинство из них были легко поправимы — как правило, достаточно было написать менее одной строчки кода. Другие ошибки, однако, требовали, чтобы я полностью переделал всю систему. С системой заклинаний я пришел от написания целых трех функций для каждого заклинания до того, что мне нужно было описать всего лишь небольшой объект, который занимает всего несколько секунд редактирования.

Делайте свою игру на JavaScript и получайте удовольствие.

Автор: Edison

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js