Докуметация Cтарт Статьи Форум Лента Вход
Не официальное русскоязычное сообщество
Главная
    Документация jMonkeyEngine
        jMonkeyEngine Уроки и Документация
            Документация для уверенных пользователей
                Рекомендации для разработчиков на jME3

Рекомендации для разработчиков на jME3

Опубликованно: 10.08.2017, 15:30
Последняя редакция, Andry: 17.08.2017 22:23

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

Эта страница представляет собой набор рекомендаций и советов экспертов. Не стесняйтесь добавлять свои собственные!

Требования и планирование

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

Сбор требований

Для краткого обзора ответьте на следующие вопросы:

  • Мотивация
    • Охарактеризуйте свою игру одним броским предложением. Если вам трудно это сделать вот пример «Крафте днем, сражайтесь ночью!».
    • Кто является целевой аудиторией? Вы делаете это для своих друзей, или пытаетесь привлечь массы?
  • Тип игры
    • Положение точки зрения (камера от первого или третьего лица)? Какие персонажи контролирует игрок? (если это применимо)
    • В реальном времени или пошаговая?
    • Жанр (драма, ужасы, приключения, детектив, комедия, образовательная, документальная)?
    • Постановка и предыстория? (Исторический, фантастический, аниме, футуристический, утопия/антиутопия, пираты, зомби, вампиры…)?
  • Игровой процесс
    • Что представляет из себя начальное состояние игры, и каково конечное состояние? (если это применимо)
    • Какими ресурсами управляет игрок? Какие ресурсы, получает, преобразовывает, тратит?
      Например: «Очки, здоровье, скорость, золото, xp, мана».
    • Как взаимодействует игрок? Определите правила, задачи, игровые механизмы.
    • Какое состояние считается выигрышем, и что приводит к проигрышу, или это открытый мир?
  • Мультимедийные игровые ресурсы
    • Какие медиа вам понадобятся? Как вы получите этот контент?
      Например: Модели, ландшафты; Материалы, текстуры; Шумы, музыка, голоса; Видео, ролики; Разговорные/письменные диалоги; Карты уровней, квесты, рассказы; AI-скрипты.
  • Интерфейс
    • Можете ли вы достичь высокой степени контроля ввода? (Даже незначительные сбои в расположении элементов взаимодействия могут делать игру неиграбельной.)
    • Решите, как вы будете отображать текущий статус и изменения в состояниях игры. Например. Здоровье/повреждение в HUD.
    • Решите, как вознаграждать за хорошие ходы и наказывать за плохие.

Планирование и этапы разработки

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

  1. Пред-Альфовая разработка
    • Оформление: загрузка и сохранение тестовых игровых ресурсов с помощью макетов и запасенных артов.
    • Спланируйте приложение в общем, то есть переключение между интро/опциями/игровым экраном и.т.д.
    • Получите один типичный уровень, прежде чем вы сможете объявить о выпуске Альфа Релиза.
      Например: Если игра «Платформер», прыжки и бег должны работать.
  2. Альфа релиз
  3. Пред-Бета разработка
    • Оформление: Замените все макеты первыми черновыми вариантами реальных медиа и карт уровней.
    • Попросите членов вашей команды проверить и провести «альфа-тестирование» на разных системах, для отслеживания ошибок, отлаживания и оптимизации.
    • Объявите стадию «Заморозка» перед тем, как объявить Бета-релиз, чтобы предотвратить проблемы появления новых ошибок.
  4. Бета-релиз
  5. Пост-Бета разработка
    • Оформление: Сделайте все финальные медиа и карты уровней.
    • Попросите людей со стороны проверить и провести «бета-тест», это упростит получение отчетов об ошибках.
    • Исправляйте ошибки с высоким приоритетом, даже из-за перегибов в коде и игровом процессе, не добавляйте новые функции на данный момент!
  6. Гамма-релиз, Дельта-релиз … = Кандидаты на Релиз
    • Думаешь, все готово? Выполните тестовые испытания. Упаковка и распространение. (Способ приобретения? Скачивания?)
    • Протестируйте его. Последний шанс найти и исправить ужасную ошибку.
  7. Омега = Финальный Релиз

Как вам называть или нумеровать эти этапы, и всей вашей команде. Команды разработчиков используют пронумерованные стадии (m1, m2, m3), греческие буквы (например, альфа, бета, гамма, дельта), «major.minor.patch-build» версия номер (например, «2.7.23-1328) или их комбинации.

Использовать контроль версий файлов

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

  • Относитесь к сообщениям фиксации как к сообщениям себе на будущее. «Сделаны некоторые изменения» это не является сообщением о фиксации.
  • SDK jMonkeyEngine поддерживает Subversion, Mercurial и Git.
    Если вы не знаете, что выбрать, Subversion — хороший выбор для начинающих.
  • Настройте свой собственный локальный сервер или получите свободное место на удаленном хостинге от различных open-source dev-порталов, таких как Sourceforge, Github, bitbucket (поддерживает частные проекты), Java.net

Программный конвейер мультимедийных игровых ресурсов(Multi-Media Asset Pipeline)

Делайте  Не делайте
Сохраняйте ваши оригинальные модели + текстуры в assets/Textures Не ссылайтесь на текстуры или модели вне вашего JME проекта.
Сохраняйте звуки в assets/Sounds Не ссылайтесь на аудио файлы вне вашего JME проекта.
Создавайте простые, низкополигональные модели.  Не создавайте высокополигональные модели, они слишком медленны, чтобы быть полезными в играх.
Используйте только Diffuse Map, Normal Map, Glow Map, Specular Map.  Не используйте свойства неподдерживаемых материалов, которые не указаны в Обзоре Материалов.
Используйте UV текстуру / текстурные атласы / запекание для каждой текстурной карты.  Не создавайте модели, основанные на нескольких отдельных текстурах, это разбивает модель на отдельные сеток.
Преобразование моделей в формат j3o. Переместите файлы j3o в assets/Models Не указывайте файлы Blender/Ogre/OBJ в вашем load() коде, потому что эти не оптимизированные файлы не упакованые в JAR.

Подробнее об Программный конвейер мультимедийных игровых ресурсов можно узнать здесь.

Этап развития

Многие разработчики игр мечтают создать свою собственную «MMORPG» всю с физикой, искусственным интеллектом, эффектами пост-рендеринга, многопользовательской сетью, процедурными картами и настраиваемыми персонажами. Так почему же не так уж и много получается MMORPG на выходе?
Даже для крупных опытных игровых продюсеров создание такой сложной игры требует много времени и сбоев. Насколько вы знакомы с многопоточностью, персистентностью, оптимизацией, синхронизацией клиент-сервер, …? Если вы не можете ответить «очень!», Тогда начните с однопользовательской настольной игры и пройдите свой путь вверх — как это делали профессионалы, когда они начинали.

Расширение SimpleApplication

Каждая jME3 игра сосредоточена вокруг одного основного класса, который (прямо или косвенно) расширяет com.jme3.app.SimpleApplication.

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

В ваших будущих релизах игр вы захотите опираться на свою собственную структуру (на основе jME): ваша настраиваемая структура будет расширять SimpleApplication от jME и включать в себя ваши собственные методы для загрузки, сохранения и упорядочивания ваших сцен, ваших методов управления, ваших вводов для приостановки и переключения экранов, вашего пользовательского интерфейса (экран параметров, HUD и.т.д.), ваша фабрика NPC, ваши физические свойства, ваша синхронизация сети и.т.д.

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

С чего начать?

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

  1. Убедитесь, что фрейм игры на высоком уровне (переключение экрана, сетевая синхронизация, загрузка/сохранение) является прочным и надежным.
  2. Начните с реализации самой сложной игровой функции — той, которая накладывает больше всего ограничений на структуру вашего проекта (например, многопользовательская сеть или физика).
  3. Добавляйте только по одной большой функции за раз. Если есть сложные взаимодействия (например, «сеть + физика»), начните с небольшого тестового примера («один общий куб») и прорабатывайте добиваясь своей цели. Начало с целой сцены вводится слишком много дополнительных источников ошибок.
  4. Реализуйте декорации с низкой степенью сложности (аудио и визуальные эффекты) в последнюю очередь.
  5. Проверяйте на наличие побочных эффектов на уже существующий код после добавления новой функции (тест регрессий).
Задумайтесь, хотите ли вы функцию, потому что это необходимо для геймплея или просто потому, что «у всех это есть». Ваша цель должна состоять в том, чтобы выявить суть вашей игровой идеи. Не разбавляйте геймплей, пытаясь заставить его «делать все», и хорошо. Успешные высокопроизводительные игры — это те, в которых кто-то принимал разумные решения о том, что нужно оставить, а что нужно отбросить.

Умный способ добавления пользовательских методов и полей

Избегайте Антипаттерны: не создавайте сложный дизайн классов на основе ролей, с использованием Java наследования, это приведет к не исправляемой путанице.
Пример: вы начинаете расширять Node -> MyMobileNode -> MyNPC. Затем вы расширяете MyFighterNPC (защищает, атакует) и MyShopKeeperNPC (торги) от MyNPC. Что делать, если вам нужен NPC, который торгует и защищает себя, но не атакует? Вы расширяете MyShopKeeperNPC и копируете и вставляете защитные методы из MyFighterNPC? Или вы расширяете MyFighterNPC и переопределяете методы атаки для его родителя? Ни одно из них не является чистым решением.
Было бы лучше, если бы поведение было отдельной «системой», а атрибуты были отдельными «компонентами», которые вы добавляете к сущности, которой они нужны?

Вы пишете классы Java с название Control для реализации своих Игровых Сущностей и определяете внешний вид, атрибуты и поведение Сущностей. В jME Spatial (Узлы или Геометрии) используются для визуального представлением игровых сущностей в графе сцены.

  • Игровые сущности имеют атрибуты — Все Сущности это нейтральные вещи, только их атрибуты определяют, чем является сущность на самом деле (персонаж или кирпич). В jME мы зовем эти поля класса Spatial «user data».
    Пример: У игроков есть поля классов для id, здоровья, денег, инвентаря, оборудования, профессии.
  • Игровые сущности имеют поведение — Системы поведения сообщают о состоянии игры и изменяют атрибуты. В jME эти игровые механики реализованы в модульных методах update(), которые все подключаются к основному циклу обновления.
    Пример: У игроков есть такие методы, как walk(), addGold(), getHealth(), pickUpItem(), dropItem(), useItem(), attack().
Следуйте Рекомендациям: в целом используйте структуру над наследованием и сохраняйте «то, что сущность делает (система поведения)» отдельным от «того, что эту сущность характеризует (атрибуты)».

Используйте setUserData() для добавления настраиваемых атрибутов в Spatials.

Используйте Control и Application States для определения пользовательских систем поведения.

Если ваша игра еще сложнее, вам может понадобиться узнать о «реальных Системах Сущностей», которые образуют совершенно другую парадигму программирования из объектно-ориентированного кодирования, но масштабируются до очень больших размеров. Однако обратите внимание, на то что эта тема очень не интуитивна для программиста ООП, и вы должны принять осмысленно решение, действительно ли вам это нужно или нет, и поднабраться некоторого опыта прежде чем, погружаться с головой в разработку MMO проектов. 😊

Умный способ доступа к игровым функциям

SimpleApplication дает вам доступ к игровым функциям, таким как rootNode, assetManager, guiNode, inputManager, audioManager, physicalSpace, viewPort и камера. Но что, если вам нужен этот доступ и из другого класса? Не расширяйте SimpleApplication второй раз и не передавайте множество ссылок на объекты в конструкторах! Необходимость доступа к объектам уровня приложения является признаком того, что этот класс должен быть спроектирован как AppState (читайте детали здесь).

AppState имеет доступ ко всем функциям игры в SimpleApplication через объекты this.app и this.stateManager.
Примеры:

Spatial sky = SkyFactory.createSky(this.app.getAssetManager(), "sky.dds", false);
...
this.app.getRootNode().attachChild( sky );

Умный способ реализации игровой логики

По мере того, как ваша игра на основе SimpleApplication становится более совершенной, вы осуществляете все больше и больше взаимодействий в цикле simpleUpdate(), и ваши методы simpleInitApp() разрастаются все больше и больше. Лучше всего перемещать блоки игровой механики в свои собственные многоразовые классы компонентов. В jME3 эти многоразовые классы называются Control и AppState.

  • Используйте AppStates для осуществления глобальной игровой механики.
    • Каждый AppState вызывает свои собственные методы initialize() и cleanup(), когда он подключается или отсоединяется от игры.
    • Каждый AppState запускает собственный потоко-безопасный цикл update(), который подключается к основному циклу simpleUpdate().
    • Вы задаете, что произойдет, если AppState приостановлен/возобновлен.
    • Вы можете использовать AppState для переключения между наборами AppStates.
    • AppState имеет доступ ко всему в SimpleApplication (rootNode, AssetManager, StateManager, InputListener, ViewPort и.т.д.).
  • Используйте Controls для реализации поведения игровых объектов.
    • Control добавляют тип поведения (методы и поля) отдельному Spatial (игроку, NPC).
    • Каждый Control запускает собственный потоко-безопасный цикл loopUpdate(), который подключается к основному циклу simpleUpdate().
    • На один Spatial могут влиять несколько Control. (!)
    • Каждый Spatial нуждается в собственном экземпляре Control.
    • Control имеет только контроль и доступ к spatial, к которому он привязан (и к его под-spatials).
Игра содержит алгоритмы, которые непосредственно не влияют на spatials (например, код траектории AI, который вычисляет и выбирает пути, но фактически не перемещает spatial). Вам нет необходимости вводить такой не-spatial код в controls, вы можете запускать эти вещи в новом потоке. Только код преобразований, который фактически изменяет spatial, должен вызываться из control или должен быть enqueue().

Control и AppStates часто работают вместе: AppState может дотянуться до application и получить все Spatials из rootNode, которые несут определенный Control, и выполнять глобальные действия над ними. Например: В BulletPhysics все Spatials с физикой, которые имеют RigidBodyControls, управляются общим BulletAppState.

AppStates и Controls являются расширениями для SimpleApplication. Это ваши модульные строительные блоки для создания более сложной игры. В идеальном случае вы перемещаете весь init/update код в Controls и AppStates, а ваши simpleInitApp() и simpleUpdate() могут оказаться практически пустыми. Этот мощный и модульный подход значительно улучшает ваш код.

Здесь вы можете прочитать все о Пользовательских Controls и Application States.

Оптимизация производительности приложений

  • Оптимизация — как избежать циклов расточительства
  • Многопоточность — используйте параллелизм для длительных фоновых задач, но не манипулируйте графом сцены вне основного потока (цикл обновления)!
  • Вы можете добавить Средства профилирования java в jMonkeyEngine SDK с помощью Сервис → Подключаемые модули → Доступные подключаемые модули. Профайлер представляет статистику жизненного цикла методов и объектов. Проблемы с производительностью могут быть вызваны некоторыми методами, которые долго исполняются или вызываются слишком часто (попробуйте кэшировать значения, чтобы избежать этого). Если счетчик количества объектов и сбора мусора увеличивается, вы смотрите на утечку памяти.

Не вмешивайтесь в Geometric State

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

  • Не вызывайте updateGeometricState() ни на чем, кроме корневого узла!
  • Не переопределяйте и не вмешивайтесь в updateGeometricState() вообще.
  • Не используйте getLocalTranslation().set() для перемещения spatial объекта в jME3, всегда используйте setLocalTranslation().

Ведение внутренней документации

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

  • Что это? Как он выполняет свою задачу (ввод, используемый алгоритм, вывод, побочные эффекты)?
  • Напишите неявные ограничения (например, минимальные/максимальные значения) и значения по умолчанию, пока вы их все еще помните.
  • В какой ситуации я хочу использовать это, является ли это, частью более крупного процесса? Необходим ли этот шаг или какие есть альтернативы?

Относитесь к javadoc как к сообщениям себе на будущее. GenNextVal() генерирует следующее значение и @param float
коэффициент. Коэффициент, влияющий на результат, не учитывается как документация.

Фаза отладки и тестирования

Отладчик Java включен в jMonkeyEngine SDK. Это позволяет вам установить точку останова в коде рядом с строкой кода, где происходит исключение. Затем вы переходите строку за строкой выполняя их и смотрите объекты и состояние живых переменных, чтобы определить, где начинается ошибка.

Используйте Logger для печати сообщений о состоянии на этапе разработки и отладки вместо System.out.println(). Регистратор можно отключить с помощью одной строки кода, тогда как комментирование всех ваших println() занимает некоторое время.

Модульное тестирование (Java Assertions) имеет иной статус в разработке 3D-графики, чем в других типах программного обеспечения. Вы не можете писать утверждения, которые автоматически проверяют правильность отображения изображения, или взаимодействия интуитивно понятны. Тем не менее вы должны создать простые тестовые примеры для отдельных игровых функций, таких как загрузчики, генераторы контента, эффекты. Запускайте тестовые примеры время от времени, чтобы узнать, работают ли они по-разному, или же они страдают от регрессий или побочных эффектов. Храните тестовые классы в тестовом каталоге вашего проекта, не добавляйте их в дистрибутив.

Обеспечение качества (QA) означает повторную проверку определенного набора функций, которые должны работать, но могут быть неожиданно нарушены каким то побочным эффектом. В каждой игре есть какие-то сумасшедшие ошибки — но базовые задачи должны работать, в любом случае. Такими задачами являются установка и деинсталляция; сохранение и загрузка; изменение параметров; запуск, приостановка, выход из игры; основные действия, такие как ходьба, борьба и.т.д. После каждой этапа вы снова просматриваете свой список QA и систематически смотрите на наличие регрессий или новые ошибки. Проверьте приложение на каждой поддерживаемой операционной системе и аппаратном обеспечении (!), Поскольку не все графические карты поддерживают одни и те же функции. Если вы не найдете очевидных ошибок, ваши пользователи их найдут, и ваша небрежностью будет отталкивать их.

Альфа и Бета-тестирование означает, что вы просите кого-то попытаться установить и запустить вашу игру. Это должна быть ситуация с реальными пользователями, где им самим нужно разобраться с установкой и игровым процессом — вы можете предоставить только обычную документацию read-me и справку. Предоставьте тестировщикам простой способ сообщить о проблемах, с которыми они столкнулись, что им больше всего нравится или что им не понравилась. Оцените, являются ли сообщаемые проблемы одноразовыми глюками, или же они есть только у некоторых и они должны быть исправлены, что бы игра могла работать у всех.

Фаза Релиза(Выпуска)

Список дел перед релизом

  • Подготовьте веб-страницу, классный лозунг, рекламные объявления и.т.д.
  • Убедитесь, что все игровые ресурсы обновлены и преобразованы в .j3o.
  • Убедитесь, что ваш код отредактирован так что бы загружать только оптимизированные .j3o-файлы, а не исходные форматы.
  • Подготовьте лицензии на игровые ресурсы, которые вы используете для включения. (Вы получили разрешение на их использование, правильно…?)
  • Отключите вывод тестовой информации из журнала.
  • Подготовьте рекламные арты: самые потрясающие скриншоты (в миниатюрах, квадратных, вертикальных, горизонтальных и полноэкранных форматах) и видеоклипы. Укажите название, контактную информацию, слоган и.т.д., Чтобы клиенты могли вас найти.
  • Подготовьте файл readme.txt, руководство по установке или справку — если это применимо.

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

Распространение исполняемых файлов

jMonkeyEngine SDK поможет вам в развертывании. В диалоговом окне Свойства проекта укажите параметры вашего брендинга и развертывания, а затем выберите Очистить и собрать проект из контекстного меню. Если вы используете другую среду IDE, обратитесь к документации IDE.

Решите, хотите ли вы выпустить свою игру как WebStart, настольный JAR, мобильный APK или браузерный Applet. У каждого варианта есть свои плюсы и минусы.

Распределение  Плюсы Минусы
Настольный Launcher
(.EXE, .app, .jar+.sh) 
Это стандартный способ распространения настольных приложений. jMonkeyEngine SDK можно настроить для автоматического создания заархивированных launchers для каждой операционной системы. Вы должны предлагать три отдельные загрузки, зависящие от платформы.
Настольное Приложение
(.JAR) 
Независимое от платформы настольное приложение. Пользователь должен иметь Java, настроенную для запуска JAR при их открытии; Или пользователь должен знать, как запускать JAR из командной строки; Или вы должны предоставить настроенную обертку для JAR.
Web Start
(.JNLP) 
Пользователь обращается к URL-адресу, по которому хранится игра как один исполняемый файл. Легкий процесс, не требуется установка. Вы можете разрешить игру в офлайн-режиме. Пользователям необходимо установить сетевое подключение для установки игры. Скачивание больших игр занимает больше времени, чем их запуск с компакт-диска.
Браузерный Applet
(.HTML+.JAR) 
Легкий доступ и играбельно в большинстве веб-браузеров. Удобное решение для быстрых небольших игр. Игра работает только в браузере. Игра или настройки не могут быть сохранены на диск. Некоторые ограничения в управлении камерой по умолчанию (jME не может захватить мышь).
Android
(.APK) 
Игра работает на устройствах Android. Устройства Android не поддерживают эффекты пост-обработки.

Какой бы метод вы ни выбрали, Java-Приложение работают в основных операционных системах: Windows, Mac OS, Linux, Android.

Файлы для распространение появляется во вновь созданной папке dist внутри папки проекта. Это файлы, которые вы загружаете или записываете на компакт-диск для распространения среди ваших клиентов.

Смотрите также:


Переведено для jmonkeyengine.ru, оригинал
Автор перевода: Andry

Добавить комментарий

jMonkeyEngine.ru © 2017. Все права сохранены.