Первое игровое приложение, которое я разработал с использованием Rails и React.

В этом блоге я расскажу о самом первом приложении, которое я разработал полностью самостоятельно. Это приложение было последним проектом во время моего обучения на Bootcamp по разработке программного обеспечения Flatiron School.

GitHub для приложения можно найти здесь: https://github.com/BennyLouie/simple-pokemon-battles

Процесс:

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

Если вы читали мой блог о моем проекте Mod 4, то знаете, что мой ноутбук в то время не работал. К счастью, я смог получить новый Macbook до того, как начал этот проект.

Первый шаг к любому приложению - решить, что построить.

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

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

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

Если я действительно свел все приложения, это действительно все, чем они были.

Очевидно, что есть вариации того, что создается / редактируется / удаляется, но, честно говоря, это казалось немного повторяющимся.

Я хотел вырваться из этого цикла.

Вот почему я решил создать игру.

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

Я также хотел каким-то образом использовать API (в данном случае для заполнения моей базы данных).

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

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

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

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

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

Я использовал генераторы случайных чисел и операторы if, чтобы контролировать ход каждой битвы.

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

Я также вкратце изучил Mocha и Chai, фреймворки / библиотеки для тестирования и утверждения, так как мне сказали, что это поможет при отладке при кодировании моей игровой логики.

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

Я решил, что проще использовать console.log и отладчик для самостоятельного устранения неполадок.

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

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

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

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

Я установил свой минимально жизнеспособный продукт (MVP) как последовательность битв между пользователем и случайным противником.

Я установил пакеты узлов, которые хотел использовать (такие как thunk, redux и browser-router), и начал кодировать свои выборки из базы данных.

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

По мере того, как я разрабатывал логику боя, постоянно возникали ошибки. Иногда это происходило из-за того, что я жестко закодировал выбор, но я ничего не мог с этим поделать, поэтому подумал о способах решения этой проблемы (более жесткое кодирование 😅). Однако в большинстве случаев это происходило из-за ошибок в моей логике.

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

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

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

Только после того, как обе эти функции были правильно настроены, я мог начать выяснять другие функции своего приложения.

Затем я начал работать над рендерингом команды покемонов пользователя. Чтобы лучше понять, с чем я работаю, я добавил немного настраиваемого CSS с помощью flex-box.

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

Только после этого я начал работать с отдельными дисплеями состояния покемонов.

Каждый раз, когда я запускал новую функцию, я добавлял в свое приложение еще один «Маршрут».

Когда эти основные функции заработали правильно, я начал добавлять React-Semantic UI для CSS. Мне пришлось немного подправить свой код, чтобы реализовать его должным образом.

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

Я обнаружил, что JS имеет встроенный аудио объект. После некоторого исследования того, как это работает, я нашел несколько аудиофайлов игры Pokemon и добавил их в свое приложение.

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

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

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

Проэкт:

Бэкэнд был построен на Rails, а фронтенд был построен на React.

Сосредоточившись на своей игровой логике, я решил сделать свой бэкэнд простым, используя только три модели: User, Pokemon, Capture.

Эти модели позволяют пользователю выбрать покемона и добавить его в свою команду.

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

Чтобы решить эту проблему, я реализовал сериализаторы.

Это позволило бы мне выбрать, что будет отображать для пользователя в базе данных. Я добавил покемона, которым владеет пользователь.

Для внешнего интерфейса я использовал Redux для управления состоянием и React Router для упрощения навигации по приложению.

Я разделил свои компоненты на Компоненты и Контейнеры. У меня было всего три компонента (логин, регистрация и покемон). У меня было много контейнеров, которые я повторно использовал во многих местах приложения.

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

Я действительно не имел большого представления о том, как будет выглядеть CSS, заранее, только общий макет моего приложения. Это был действительно процесс проб и ошибок 😅. Я неоднократно настраивал фоновые изображения до крайнего срока, прежде чем смог придумать удовлетворительную «оболочку» для своего приложения.

Позже я развернул свое приложение на Heroku: https://simple-pokemon-battles.herokuapp.com/

Подробнее об этом приложении можно найти в README репозитория проекта GitHub.