Докуметация Cтарт Статьи Форум Лента Вход
Не официальное русскоязычное сообщество
Главная
    jMonkeyEngine 3 Урок (4) — Привет циклическое обновление (Hello Update Loop)
        jMonkeyEngine 3 Урок (4) — Привет циклическое обновление (Hello Update Loop)

BuGaGa

Опубликованно: BuGaGaBuGaGa12.02.2016, 11:47
Последняя редакция, Andry: 04.12.2017 13:31

Предыдущий: Hello Assets, Следующий: Hello Input System.

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

Пример кода

package jme3test.helloworld;
import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
 
/** Образец 4 - как вызвать повторение действия из основного цикла событий.
 * В этом примере вы используете цикл, чтобы персонажа игрока 
 * непрерывное вращался. */
public class HelloLoop extends SimpleApplication {
 
    public static void main(String[] args){
        HelloLoop app = new HelloLoop();
        app.start();
    }
 
 protected Geometry player;
 
    @Override
    public void simpleInitApp() {
        /** этот синий куб — наш персонаж игрока */
        Box b = new Box(1, 1, 1);
        player = new Geometry("blue cube", b);
        Material mat = new Material(assetManager,
        "Common/MatDefs/Misc/Unshaded.j3md");
        mat.setColor("Color", ColorRGBA.Blue);
        player.setMaterial(mat);
        rootNode.attachChild(player);
    }
 
    /* Используйте основной цикл событий, чтобы вызвать повторяющиеся действие.*/
    @Override
    public void simpleUpdate(float tpf) {
        // зададим вращение игрока:
        player.rotate(0, 2*tpf, 0); 
    }
}

Соберите и запустите код: вы увидите непрерывно вращающийся куб.


Понимание кода

По сравнению с нашими предыдущими примерами кода, обратите внимание, что Геометрия игрока теперь — это поле класса. Это связано с тем, что мы хотим, чтобы цикл обновления мог получить доступ к преобразованию этой Геометрии. Как обычно, мы инициализируем объект игрока в методе simpleInitApp().

Теперь рассмотрим метод simpleUpdate() — это цикл обновления.

  • Строка player.rotate(0, 2*tpf, 0); осуществляет поворот объекта player.
  • Мы используем переменную времени tpf («time per frame» — время на кадр), время этого действия зависит от текущего количества кадров на секунду. Это просто означает, что куб вращается с одной и той же скоростью на быстрых и медленных машинах, и игра остается, так сказать, на ходу.
  • После запуска игры, код rotate() выполняется снова и снова.

Использование циклического обновления

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

  • Метод simpleUpdate() запускается после того как метод simpleInitApp() инициализирует граф сцены и переменные состояния.
  • JME3 выполняет все, что в методе simpleUpdate() многократно, и как можно быстрее.
    1. Используйте цикл для опроса состояния игры, а затем инициируйте действия.
    2. Используйте цикл, чтобы вызвать реакцию на событие и обновить состояние игры.
    3. Используйте цикл мудро, потому что слишком много вызовов в цикле также замедляет игру.

Инициализация — Обновление — Визуализация

Обратите внимание на три фазы в каждой игре:

  • Инициализация(Init): Метод simpleInitApp() выполняется только один раз, в самом начале;
  • Обновление(Update): Метод simpleUpdate() запускается постоянно, во время игры.
  • Визуализация(Render): После каждого обновления, jMonkeyEngine автоматически перерисовывает (визуализирует) экран для вас.

Поскольку рендеринг (визуализация) является автоматическим, инициализация и обновление являются двумя наиболее важными понятиями для вас в SimpleApplication — основе игры:

  • Метод simpleInitApp() является «первым дыханием» приложения. Здесь вы загружаете и создаете игровые данные (один раз).
  • Метод simpleUpdate() является «сердцебиением» (единицы времени называются тактами(ticks)). Здесь вы изменяете свойства для обновления состояния игры (многократно).
Все в игре происходит либо во время инициализации, либо во время цикла обновления. Это означает, что эти два метода разрастаются очень долго и в течение долгого времени. Следуйте этим двум стратегиям наращивания кода инициализации и обновления, используя нескольких модульных Java классов:

Имейте это в виду, когда ваше приложение разрастется.


Упражнения

Вот некоторые забавные вещи для тренировки:

  1. Что произойдет, если вы дадите значению метода rotate() отрицательное значение?
  2. Сможете ли вы создать две геометрии рядом друг с другом, и сделать так, чтобы одна вращалась вдвое быстрее, чем другая? (Используйте переменную tpf)
  3. Сможете ли вы сделать куб пульсирующим? (Увеличивается и уменьшается)
  4. Сможете ли вы сделать куб, который изменяет цвет? (Изменить и установить Материал)
  5. Сможете ли вы сделать качение куба? (Вращаться вокруг оси х, а перемещения вдоль оси z)

Обратитесь к уроку Hello Node, если вы не помните методы преобразования для масштабирования, перемещения и вращения.

Ссылка на решения предлагаемые пользователями: Некоторые предлагаемые решения
Но, сначала, попытайтесь решить все сами!

Вывод

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

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


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

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

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

Под игровыми ресурсами(assets)  мы подразумевает мультимедийные файлы, такие как 3D-модели, материалы, текстуры, сцены, пользовательские шейдеры, музыку и звуковые файлы и пользовательские шрифты. JME3 имеет встроенное менеджер ресурсов(asset manager), который поможет вам сохранять игровые ресурсы вашего проекта организованными. Думайте о менеджере ресурсов как о файловой системе вашей игры, независимой от фактической платформы развертывания. По умолчанию, ваши игровые ресурсы сохраняются в папке MyGame/assets/ вашего проекта.

Преимущества менеджера ресурсов (AssetManager):

  • Пути остаются теми же, независимо от того, работает ли игра на Windows, Mac, Linux, и.т.д.!
  • AssetManager автоматически кэширует и оптимизирует обработку объектов OpenGL. Например, одни и те же текстуры не загружаются на видеокарту несколько раз, когда одну текстуру использует несколько моделей.
  • Сценарий сборки по умолчанию автоматически связывает содержимое каталога ресурсов с исполняемый файл.

Опытные пользователи могут писать собственные скрипты сборки и упаковки, и могут регистрировать пользовательский путь к AssetManager, но это зависит уже от вас.

Контекст

jMonkeyProjects/MyGame/assets/    # Здесь вы храните игровые ресурсы в под папках!
jMonkeyProjects/MyGame/build/     # SDK генерирует сборку классов здесь(*)
jMonkeyProjects/MyGame/build.xml  # Настройка скрипта сборки Ant здесь
jMonkeyProjects/MyGame/nbproject/ # SDK сохраняет по умолчанию build.xml и метаданные (*)
jMonkeyProjects/MyGame/dist/      # SDK генерирует исполняемый дистрибутив здесь (*)
jMonkeyProjects/MyGame/src/       # Здесь хранятся ваши исходники Java
jMonkeyProjects/MyGame/test/      # Здесь вы размещаете тестовые классы (необязательно)
(*)Управляется jMonkeyEngine SDK - не редактировать!

Смотрите также: Рекомендации.

Применение

Объект assetManager является экземпляром com.jme3.asset.AssetManager, к которому может получить доступ каждый com.jme3.app.Application. Он поддерживает root, который также включает в себя пути к классу вашего проекта по умолчанию, поэтому вы можете загрузить любой игровой ресурс, находящийся в этом пути к классам, то есть на верхнем уровне вашего каталога проекта.

Вы можете использовать унаследованный объект assetManager непосредственно, или использовать аксессор app.getAssetManager().

Вот пример того как вы можете загрузить игровые ресурсы с использованием AssetManager. Эти строки загружают материал по умолчанию из встроенного каталога Common/:

Material mat = (Material) assetManager.loadAsset(
    new AssetKey("Common/Materials/RedColor.j3m"));

Этот Материал «находится где-то» в jME3 JAR; Менеджер ресурсов по умолчанию настроен правильно обрабатывать Common/… пути, так что вам не нужно указывать полный путь, когда речь идет о встроенных в игру в игровых ресурсов (например, по умолчанию материалов).

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

Каталог ресурсов

По умолчанию, jME3 ищет модели в каталогах с именем assets.

В Java проектах, созданных в jMonkeyEngine SDK, папка assets создается по умолчанию в папке проекта. При использовании любого другого IDE, или из командной строки, вы просто создаете папку assets вручную.

Это наша рекомендация о структуре каталогов для хранения ресурсов:

jMonkeyProjects/MyGame/src/...           # Пакеты, .java исходный код.
jMonkeyProjects/MyGame/assets/...        # Папка игровых ресурсов:
jMonkeyProjects/MyGame/assets/Interface/ # .font, .jpg, .png, .xml
jMonkeyProjects/MyGame/assets/MatDefs/   # .j3md
jMonkeyProjects/MyGame/assets/Materials/ # .j3m
jMonkeyProjects/MyGame/assets/Models/    # .j3o
jMonkeyProjects/MyGame/assets/Scenes/    # .j3o
jMonkeyProjects/MyGame/assets/Shaders/   # .j3f, .vert, .frag
jMonkeyProjects/MyGame/assets/Sounds/    # .ogg, .wav
jMonkeyProjects/MyGame/assets/Textures/  # .jpg, .png; also .mesh.xml+.material, .mtl+.obj, .blend (!)

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

Вы можете переименовать/удалить/добавить (под)папки внутри папки assets любым образом. Обратите внимание, однако, что нет автоматического рефакторинга для путей к игровым ресурсам в SDK, так что если вы модифицируете их в конце процесса разработки, вы должны реорганизовать все пути вручную.

Примеры: Вы можете переименовать assets/Sounds в assets/Audio, можно удалить assets/MatDefs если вы его не используете, вы можете создать assets/AIscripts, и.т.д. Вы можете переименовать/переместить папку assets/Textures или её подпапки, но тогда вы должны реэкспортировать все модели, и вновь переконвертировать их все в .j3o, так что планируйте все заранее!

Сохраняйте текстуры в assets/Textures/, прежде чем станете работать с ними в редакторе сетки! Экспортируйте и сохраняйте файлы 3D моделей (.mesh.xml+.material, .mtl+.obj, .blend) в assets/Textures/(!) перед преобразованием модели в двоичный формат (.j3o)! Это гарантирует, что пути  текстуры будут правильно указывать на ваши папки в assets/Textures.
После преобразования, вы перемещаете .j3o файл в папку assets/Models/ или assets/Scenes/. Таким образом, вы можете повторно использовать текстуры, ваши двоичные файлы последовательно связывают правильные текстуры, а папки assets/Models и assets/Scenes не становятся загроможденными.

Пример кода: загрузка ресурсов

Создадим экземпляр материала с описанием материала Unshaded.j3md:

Material mat_brick = new Material(
    assetManager, "Common/MatDefs/Misc/Unshaded.j3md");

Применим текстуры материала:

mat_brick.setTexture("ColorMap",
    assetManager.loadTexture("Textures/Terrain/BrickWall/BrickWall.jpg"));

Загрузим шрифты:

guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");

Загрузим модели:

Spatial ninja = assetManager.loadModel("Models/Ninja/Ninja.mesh.xml");

Загрузка сцены из файла Ogre3D dotScene, который хранится внутри zip архива:

assetManager.registerLocator("town.zip", ZipLocator.class);
Spatial scene = assetManager.loadModel("main.scene");
rootNode.attachChild(scene);

В качестве альтернативы ZipLocator, существует также HttpZipLocator, который может транслировать модели из zop архива онлайн:

assetManager.registerLocator("https://storage.googleapis.com/"
    + "google-code-archive-downloads/v2/code.google.com/"
    + "jmonkeyengine/wildhouse.zip", HttpZipLocator.class);
Spatial scene = assetManager.loadModel("main.scene");
rootNode.attachChild(scene);

jME3 также предлагает ClasspathLocator, ZipLocator, FileLocator, HttpZipLocator, и UrlLocator (см. com.jme3.asset.plugins).

 В пользовательском сценарий сборки автоматически не включаются все файлы ZIP в исполняемый файл. Смотрите «Не удается найти ресурс» решение ниже.

Типичные задачи Asset Manager

Задача? Решение!
Загрузить модель с материалами Используйте метод менеджера ресурсов loadModel() и прикрепите spatial к rootNode

Spatial elephant = assetManager.loadModel("Models/Elephant/Elephant.mesh.xml");
rootNode.attachChild(elephant);
Spatial elephant = assetManager.loadModel("Models/Elephant/Elephant.j3o");
rootNode.attachChild(elephant);
Загрузить модель без материалов Если у вас модель без материалов, вы должны назначить ей материал по умолчанию, чтобы сделать ее видимой.

Spatial teapot = assetManager.loadModel("Models/Teapot/Teapot.j3o");
// материал по умолчанию
Material mat = new Material(assetManager, "Common/MatDefs/Misc/ShowNormals.j3md");
teapot.setMaterial(mat);
rootNode.attachChild(teapot);
Загрузить сцену Вы загружаете сцену точно также, как загружаете модели:

Spatial scene = assetManager.loadModel("Scenes/town/main.scene");
rootNode.attachChild(scene);
Spatial scene = assetManager.loadModel("Scenes/town/main.j3o");
rootNode.attachChild(scene);

NullPointerException: Не удается найти ресурс?

Проблема:

Моя игра работает отлично, когда я запускаю ее прямо из jMonkeyEngine SDK. Но когда я запускаю автономные исполняемые файлы (.jar, .jnlp .exe, .apps), Desktop AssetManager выдает в консоль сообщение об ошибке, и он завершает работу?

com.jme3.asset.DesktopAssetManager loadAsset
WARNING: Cannot locate resource: Scenes/town/main.scene
com.jme3.app.Application handleError
SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
java.lang.NullPointerException

Причина:

Если вы используете сценарий сборки по умолчанию, исходные модели и сцены (.mesh.xml, .obj, .blend, .zip), автоматически исключаются из дистрибутива. Автономный исполняемый файл включает только преобразованные .j3o файлы (модели и сцены) только. Сценарий сборки по умолчанию позволяет объединить существующие .j3o файлы в дистрибутиве, но вам нужно не забыть, самостоятельно конвертировать модели (из mesh.xml–>.j3o, или .obj–>.j3o и т.д.).

Решение

Перед сборкой исполняемого файла, необходимо использовать контекстное меню в jMonkeyEngine SDK для преобразования 3D-моделей в .j3o двоичный формат.

  1. Сохраните ваши исходные модели (файлы .mesh.xml, .scene, .blend или .obj плюс текстуры) в assets/Textures/. (!)
  2. Откройте jME3 проект в jMonkeyEngine SDK.
  3. Перейдите в папку assets в окне Проекты.
  4. Щелкните [ПК мыши] исходную модель(в изначальном формате) в assets/Textures/, и выберите «Преобразовать в j3o двоичный» (“Convert to j3o Binary”).
  5. Преобразованный файл появится в той же папке, что и исходный файл. Он имеет то же имя, и суффикс .j3o.
  6. Переместите файл .j3o в assets/Models/ или assets/Scenes/ директорию.
  7. Для загрузки файла .j3o используйте метод load() из assetManager.

Это гарантирует, что пути текстур для вашей моделей из 3D редактора сетки, будут продолжать работать и в JME3.

Если вам необходимо загрузить пользовательские игровые ресурсы не являющиеся .j3o из ZIP файла, вы должны вручную изменить сценарий сборки заданный по умолчанию для копирования ZIP-файлов в ваш дистрибутив. ZIP-ы пропускаются по умолчанию.

Работа с игровыми ресурсами в других IDE: Codeless проекты

Проблема:

Я использую другой IDE, вместо jMonkeyEngine SDK для кодинга (Eclipse, IntelliJ, текстовый редактор). Где находится моя папка asset и .j3o конвертор?

Решение:

Вы можете программировать в любой IDE, но вы должны создать так называемый codeless проект в jMonkeyEngine SDK для поддержки игровых ресурсов(assets). Codeless jMonkeyEngine проект не вмешивается со своими источниками или пользовательскими скриптами сборки. Вы просто используете его для преобразования моделей в .j3o двоичные файлы.

  1. Создайте свой проект (в Eclipse или любой другой), в чем вам нравится.
  2. Создайте каталог в папке вашего проекта и назовите его, например, assets
    Сохраните там ваши игровые ресурсы, как описано выше.
  3. Загрузите и установите jMonkeyEngine SDK.
  4. В SDK, перейдите в меню Файл → Импорт проекта → External Project Assets.
  5. Выберите (в Eclipse или любой другой) проект и папку ваших ресурсов в мастере импорта.
  6. Теперь вы можете открывать этот проект (из Eclipse или любой другой) в jMonkeyEngine SDK. 
    Конвертируйте ресурсы, как описано выше.
Если вы по какой то причине не используете SDK, вы все равно можете конвертировать модели в формат j3o: Загрузите любую модель в формате Ogre3D или формате Wavefront с AssetManager.loadModel() как spatial. Затем сохраните spatial виде j3o файла используя BinaryExporter.
Используйте контроль версий файла, и давайте членам команды возможность проверят ваш проект. Ваши разработчики могут открывать проект в Eclipse (и.т.д.), как они и привыкли. В дополнение к их графическим инструментам, попросите своих графических дизайнеров установить jMonkeyEngine SDK, и, проверить проект Codeless, который вы для них подготовите. Это легко осуществимо для не программирующих членов команды, чтобы просмотреть или сделать пред просмотр игровых ресурсов, для организации сцены, и преобразования файлов. В то же время, не-кодеры случайно не накосячат с кодом, а разработчики случайно не накосячат с игровыми ресурсами.

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

Предыдущий: Hello Node, Следующий: Hello Update Loop

В этом уроке мы научимся загружать 3D-модели и текст в графе сцены, используя jME Менеджер ресурсов(Asset Manager). Вы также узнаете, как определить правильные пути, и какие форматы файлов использовать.

beginner-assets-models

Не удается найти файлы для запуска этого образца? Чтобы получить ресурсы (3D модели) используемые в этом примере, добавьте встроенный jME3-testdata.jar в ваш проект. В проекте созданном в jMonkeyEngine SDK (рекомендуем), просто щелкните [ПК Мыши] на вашем проекте, выберите Свойства, перейдите в раздел Библиотеки, нажмите кнопку [Добавить библиотеку] и добавьте предварительно сконфигурированную “jme3-test-data” библиотеку.

Пример кода

package jme3test.helloworld;

import com.jme3.app.SimpleApplication;
import com.jme3.font.BitmapText;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Box;

/** Образец 3 - как загрузить модель OBJ и OgreXML модель,
 * материал/текстуры, или текст.*/
public class HelloAssets extends SimpleApplication {

    public static void main(String[] args) {
        HelloAssets app = new HelloAssets();
        app.start();
    }

    @Override
    public void simpleInitApp() {

        Spatial teapot = assetManager.loadModel("Models/Teapot/Teapot.obj");
        Material mat_default = new Material( 
        assetManager, "Common/MatDefs/Misc/ShowNormals.j3md");
        teapot.setMaterial(mat_default);
        rootNode.attachChild(teapot);

        // Создать стену с простой текстурой из test_data
        Box box = new Box(2.5f,2.5f,1.0f);
        Spatial wall = new Geometry("Box", box );
        Material mat_brick = new Material( 
        assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        mat_brick.setTexture("ColorMap", 
        assetManager.loadTexture("Textures/Terrain/BrickWall/BrickWall.jpg"));
        wall.setMaterial(mat_brick);
        wall.setLocalTranslation(2.0f,-2.5f,0.0f);
        rootNode.attachChild(wall);

        // Отображение строки текста шрифтом по умолчанию
        guiNode.detachAllChildren();
        guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
        BitmapText helloText = new BitmapText(guiFont, false);
        helloText.setSize(guiFont.getCharSet().getRenderedSize());
        helloText.setText("Hello World");
        helloText.setLocalTranslation(300, helloText.getLineHeight(), 0);
        guiNode.attachChild(helloText);

        // Загрузите модель из test_data (OgreXML + материал + текстура)
        Spatial ninja = assetManager.loadModel("Models/Ninja/Ninja.mesh.xml");
        ninja.scale(0.05f, 0.05f, 0.05f);
        ninja.rotate(0.0f, -3.0f, 0.0f);
        ninja.setLocalTranslation(0.0f, -5.0f, -2.0f);
        rootNode.attachChild(ninja);
        // Вы должны добавить освещение, чтобы сделать модель видимой
        DirectionalLight sun = new DirectionalLight();
        sun.setDirection(new Vector3f(-0.1f, -0.7f, -1.0f));
        rootNode.addLight(sun);

    }
}

Соберите и запустите образец. Вы должны увидеть зеленого ниндзю с разноцветным чайником, стоящим на стене. Текст на экране должен быть следующий: «Hello World».


Asset Manager (Менеджер ресурсов (3D моделей))

Под игровыми ресурсами(Assets) мы подразумеваем все мультимедийные файлы такие как: модели, материалы, текстуры, целые сцены, пользовательские шейдеры, музыку и звуковые файлы, пользовательские шрифты. JME3 поставляется с удобным объектом AssetManager, который поможет вам получить доступ к своим игровым ресурсам. AssetManager можете загружать файлы из:

  • Текущий путь к классам (верхний уровень папки проекта),
  • Папка игровых ресурсов assets вашего проекта и
  • Необязательные, прописанные вами пути.

Ниже приведена рекомендуемая структура папок для хранения игровых ресурсов в папке проекта:

MyGame/assets/  
MyGame/assets/Interface/ 
MyGame/assets/MatDefs/  
MyGame/assets/Materials/  
MyGame/assets/Models/       <-- ваши .j3o модели здесь 
MyGame/assets/Scenes/
MyGame/assets/Shaders/ 
MyGame/assets/Sounds/       <-- ваши аудио файлы здесь 
MyGame/assets/Textures/     <-- ваши текстуры здесь 
MyGame/build.xml            <-- настройки Ant 
MyGame/src/...              <-- ваш Java код здесь 
MyGame/...

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


Загрузка текстур

Разместите ваши текстуры в подпапке assets/Textures/. Загрузите текстуру в Материал до того, как вы зададите Материал. Следующий пример кода относится к методу simpleInitApp() и загружает простую модель стены:

// Создать стену с простой текстурой из test_data
Box box = new Box(2.5f,2.5f,1.0f);
Spatial wall = new Geometry("Box", box );
Material mat_brick = new Material( 
assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat_brick.setTexture("ColorMap", 
assetManager.loadTexture("Textures/Terrain/BrickWall/BrickWall.jpg"));
wall.setMaterial(mat_brick);
wall.setLocalTranslation(2.0f,-2.5f,0.0f);
rootNode.attachChild(wall);

В этом случае вы создаете свой собственный Материал и применяете его к Геометрии. Вы основываете Материалы на описании материала по умолчанию (например “Unshaded.j3md”), как показано в этом примере.


Загрузка текста и шрифтов

Этот пример показывает текст «Hello World» в нижней части экрана, используя шрифт по умолчанию. Вы прикрепляете текст к узлу guiNode – это специальный узел для отображения плоских (ортогональных) элементов. С помощью него вы показываете счет в игре, здоровье игрока и.т.п. Следующий пример кода так же реализуется в методе simpleInitApp().

// Отображение строки текста шрифтом по умолчанию
guiNode.detachAllChildren();
guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
BitmapText helloText = new BitmapText(guiFont, false);
helloText.setSize(guiFont.getCharSet().getRenderedSize());
helloText.setText("Hello World");
helloText.setLocalTranslation(300, helloText.getLineHeight(), 0);
guiNode.attachChild(helloText);
Избавится от существующего текста можно отсоединив всех потомков узла guiNode.

Загрузка моделей

Экспортируйте вашу 3D модель в OgreXML формате (.mesh.xml, .scene, .material, .skeleton.xml) и поместите ее в подпапку ресурсов assets/Models/. Следующий пример кода так же реализуется в методе simpleInitApp().

// Загрузите модель из test_data (OgreXML + материал + текстура)
Spatial ninja = assetManager.loadModel("Models/Ninja/Ninja.mesh.xml");
ninja.scale(0.05f, 0.05f, 0.05f);
ninja.rotate(0.0f, -3.0f, 0.0f);
ninja.setLocalTranslation(0.0f, -5.0f, -2.0f);
rootNode.attachChild(ninja);
// Вы должны добавить свет, чтобы сделать модель видимой
DirectionalLight sun = new DirectionalLight();
sun.setDirection(new Vector3f(-0.1f, -0.7f, -1.0f));
rootNode.addLight(sun);
Вам не нужно создавать Материал, если вы экспортировали модель с Материалом. Не забудьте добавить источник света, как показано, иначе Материал (и вся модель) не будут видны.

Загрузка игровых ресурсов с использованием пользовательских путей

Что делать, если ваша игра зависит от использования ваших файлов, которые не включены в дистрибутив? Если файл не находится в папке по умолчанию (папка assets), вы можете зарегистрировать пользовательский Locator и загружать из любого пути.

Здесь приведен пример использования ZipLocator, который регистрирует файл town.zip на верхнем уровне папок вашего проекта:

assetManager.registerLocator("town.zip", ZipLocator.class);
Spatial scene = assetManager.loadModel("main.scene");
rootNode.attachChild(scene);

А вот пример HttpZipLocator, который может скачивать сжатые модели и загружать их:

assetManager.registerLocator(
"https://storage.googleapis.com/"
            + "google-code-archive-downloads/v2/code.google.com/"
            + "jmonkeyengine/wildhouse.zip", 
HttpZipLocator.class);
Spatial scene = assetManager.loadModel("main.scene");
rootNode.attachChild(scene);

JME3 предлагает ClasspathLocator, ZipLocator, FileLocator, HttpZipLocator, и UrlLocator (смотрите com.jme3.asset.plugins).


Создание моделей и сцен

Для создания 3D моделей и сцен вам нужен 3D редактор сетки. Если у вас нет инструментов, установите Blender и плагин OgreXML Exporter. Затем вы создаёте полностью текстурированные модели (например с помощью Blender) и экспортируете их в свой проект. Затем используйте SDK, для загрузки моделей, конвертирования и создания 3D сцен из них.

Смотрите создание моделей и сцен как пример того, как экспортировать ваши модели в виде Ogre XML сеток с материалами.


Формат файла модели

JME3 может конвертировать и загрузить:

  • Ogre XML модели + материалы
  • Ogre DotScenes
  • Wavefront OBJ + MTL модели
  • .Blend файлы

Метод loadModel() загружает эти исходные форматы файлов когда вы запускаете свой код непосредственно из SDK. Однако, если вы соберете исполняемый файл используя сборку скриптов по умолчанию, тогда оригинальные файлы моделей (XML, OBJ, и др.) не будут включены. Это означает, что когда вы запустите исполняемый файл вне SDK и загрузите любую оригинальную модель напрямую, вы получите следующее сообщение об ошибке:

com.jme3.asset.DesktopAssetManager loadAsset
WARNING: Cannot locate resource: Models/Ninja/Ninja.mesh.xml
com.jme3.app.Application handleError
SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
java.lang.NullPointerException

Вы видите, что загрузка файлов XML/OBJ/Blend приемлема только на этапе разработки в SDK. Например, каждый раз когда ваш 3D дизайнер обновляет файлы в папке игровых ресурсов assets, вы сможете быстро просмотреть последнюю версию в вашей среде разработки.

Но для QA(на качество) тестов и для финальной сборки, вы должны использовать исключительно файлы .j3o. J3o – это оптимизированный бинарный формат для jME3 приложений. Когда вы делаете сборку для QA(на качество) тестов, или будете готовы к выпуску, используйте SDK для конвертации всех .obj/.scene/.xml/.blend файлов в .j3o файлы, и обновите весь код для загрузки .j3o файлов. Сценарий сборки по умолчанию автоматически упаковывает .j3o файлы в исполняемые.

Откройте ваш JME3 проект в jMonkeyEngine SDK.

  1. Щелкните [ПК Мыши] файл .blend, .obj или .mesh.xml в окне Проекты, и выберите Convert to J3o Binary.
  2. Файл .j3o появится рядом с файлом .mesh.xml и будет иметь такое же название.
  3. Обновить все loadModel() строки для загрузки нового файла. Например:
Spatial ninja = assetManager.loadModel("Models/Ninja/Ninja.j3o");
Если ваш исполняемый файл выдает предупреждение «Cannot locate resource(Не удается найти ресурс)», проверьте все пути загрузок и убедитесь, что вы от конвертировали все модели в .j3o файлы!

Загрузка моделей и сцен

Задача? Решение!
Загрузить модель с материалами Используйте метод loadModel() в asset manager, и прикрепите spatial к rootNode.

Spatial elephant = assetManager.loadModel("Models/Elephant/Elephant.mesh.xml");
rootNode.attachChild(elephant);
Spatial elephant = assetManager.loadModel("Models/Elephant/Elephant.j3o");
rootNode.attachChild(elephant);
Загрузить модель без материалов Если у вас есть модель без материалов, вы должны дать ей материал, чтобы сделать ее видимой.

Spatial teapot = assetManager.loadModel("Models/Teapot/Teapot.j3o");
Material mat = new Material(assetManager, "Common/MatDefs/Misc/ShowNormals.j3md"); // материал по умолчанию
teapot.setMaterial(mat);
rootNode.attachChild(teapot);
Загрузить сцену Вы загружаете сцену точно также, как загружаете модели:

Spatial scene = assetManager.loadModel("Scenes/town/main.scene");
rootNode.attachChild(scene);
Spatial scene = assetManager.loadModel("Scenes/town/main.j3o");
rootNode.attachChild(scene);

Упражнение – как загрузить ресурсы

  1. Загрузите town.zip пример сцены.
  2. (Необязательно): Разархивируйте city.zip, чтобы увидеть структуру содержащегося Ogre dotScene: Вы получите папку с названием town. Он содержит XML файлы и текстуры, а так же файл с названием main.scene. (Это просто информация для вас, вам не нужно ничего делать с этим.)
  3. Поместите файл town.zip в верхнем уровне папок вашего проекта JME3, например, так:
    jMonkeyProjects/MyGameProject/assets/
    jMonkeyProjects/MyGameProject/build.xml
    jMonkeyProjects/MyGameProject/src/
    jMonkeyProjects/MyGameProject/town.zip
    ...
    

    Используйте следующий метод, чтобы загрузить модели из zip файла:

  4. Убедитесь, что town.zip находится в папке проекта.
  5. Зарегистрируйте локатор ZipLocator в директории проекта: добавьте следующий код в simpleInitApp() {
    assetManager.registerLocator("town.zip", ZipLocator.class);
    Spatial gameLevel = assetManager.loadModel("main.scene");
    gameLevel.setLocalTranslation(0, -5.2f, 0);
    gameLevel.setLocalScale(2);
    rootNode.attachChild(gameLevel);
    

    Теперь метод loadModel() ищет эту zip директорию непосредственно в файлах загрузки.
    (это означает, не нужно писать loadModel(town.zip/main.scene) или чего-то подобного!)

  6. Очистите, соберите и запустите проект.
    Вы должны увидеть Ниндзю + стену + чайник стоящих в городе.
Если вы зарегистрировали новый локатор, убедитесь, что у вас не получается никаких конфликтов имен файлов: Не называйте все сцены main.scene (главная.сцена), лучше дайте каждой сцене своё единственное уникальное имя.

Ранее в этом уроке вы загружали сцены и модели из каталога ресурсов assets. Это самый распространенный способ загрузки сцен и моделей. Вот стандартная процедура:

  1. Удалить код, который был добавлен в предыдущем упражнении.
  2. Переместите распакованную папку town/ в папку assets/Scenes/ вашего проекта.
  3. Добавьте следующий код в simpleInitApp()
    Spatial gameLevel = assetManager.loadModel("Scenes/town/main.scene");
    gameLevel.setLocalTranslation(0, -5.2f, 0);
    gameLevel.setLocalScale(2);
    rootNode.attachChild(gameLevel);
    

    Обратите внимание, что путь относится к каталогу assets /….

  4. Очистите, соберите и запустите проект.
    Вы снова должны увидеть Ниндзю + стену + чайник стоящих в городе.

Вот третий метод, который вы должны знать, по загрузке сцены/модели из файла .j3o:

  1. Удалить код из предыдущего упражнения.
  2. Если вы это еще не сделали, то откройте SDK и откройте проект, содержащий класс HelloAsset.
  3. В окне проектов перейдите в папку assets/Scenes/town.
  4. Щелкните [ПК Мыши] main.scene и сконвертируйте сцену в двоичном формате: jMonkeyPlatform сгенерирует файл main.j3o.
  5. Добавьте следующий код в simpleInitApp() {
    Spatial gameLevel = assetManager.loadModel("Scenes/town/main.j3o");
    gameLevel.setLocalTranslation(0, -5.2f, 0);
    gameLevel.setLocalScale(2);
    rootNode.attachChild(gameLevel);
    

    Снова отметим, что путь относится к каталогу assets/….

  6. Очистите, соберите и запустите проект.
    Вы снова должны увидеть Ниндзю + стену + чайник стоящих в городе.

Выводы

Теперь вы знаете, как заполнить граф сцены статическими фигурами и моделями, и как создавать сцены. Вы научились загружать игровые ресурсы(assets) с помощью assetManager и вы видели, что путь к файлам начинается относительно вашей папки проекта. Еще одной важной вещью является то, что вы научились конвертировать модели в формат .j3o для исполняемых JAR и.т.д.

Теперь давайте добавим некоторое действие на сцене и продолжим изучение с циклическими обновлениями!  


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


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

Плохая новость: 3D вращение осуществляется с помощью матричного исчисления.
Хорошая новость: Если вы не понимаете это исчисление, есть два простых правила, как вам все делать правильно.

3D вращение – это сумасшедшая математическая операция, где вам нужно умножить все вершины вашего объекта на четыре числа с плавающей точкой; Умножение называется конкатенацией, массив из четырех чисел {x, y, z, w} называется кватернионом. Не волнуйтесь, 3D движок сделает всю тяжелую работу за вас. Все, что вам нужно знать:

Кватернион является объектом, который способен к «глубокой заморозке» и хранению вращения, которое можно применить к 3D объекту.

Использование кватернионов для вращения

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

  • Угол поворота определяется как кратное числу Пи.
  • Ось вращения определяется вектором: Подумайте о них с точки зрения «тангаж», «рыскание», и «крен».

Пример:

/* В этом кватернионе хранит поворот на 180 градусов в виде крена */ 
Quaternion roll180 = new Quaternion();
roll180.fromAngleAxis( FastMath.PI , new Vector3f(0,0,1) ); 
/* Применяется вращения: объект накреняется на 180 градусов.*/ 
thingamajig.setLocalRotation( roll180 );

Итак как выбрать правильные цифры для параметров кватернионна? Я дам вам мою шпаргалку:

Вращение вокруг осей Использование осевого вектора Примеры вращения такого рода
Ось X (1, 0, 0) Самолет поднимается и опускается(тангаж). Положительное кивание головой.
Ось Y (0, 1, 0) Самелет «рыскает». Авто поворачивает. Отрицательное качание головой.
Ось Z (0, 0, 1) Крен самолета или «банка». Склонить голову.
Это три наиболее распространенных примера – технически вы можете вращать вокруг любой оси, выраженной вектором.
Угол? Используем радианы! Примеры
45 градусов FastMath.PI / 4 Восьмая часть круга
90 градусов FastMath.PI / 2 Четверть круга, или 3 часа
180 градусов FastMath.PI Половина круга или 6 часов
270 градусов FastMath.PI *3/2 Три четверти круга или 9 часов
360 градусов FastMath.PI*2 Полный круг или 12 часов ;)
g градусов FastMath.PI *g/180 Любой угол g
Вы должны указать углы в радианах (кратные или доли PI). Если вы будете использовать градусы, вы просто получите бесполезные результаты.

Как использовать эти таблицы, чтобы задать определенное вращение:

 1. Выберите подходящий вектор оси из таблицы.
 2. Выберите соответствующее значение угла в радианах из таблицы.
 3. Создайте Кватернион для хранения этого вращение. … fromAngleAxis( radians , vector )
 4. Применить Кватернион к узлу, чтобы повернуть его. … setLocalRotation(…)

Объекты Кватернионы можно использовать так часто, как вы захотите, только давайте им осмысленные имена, такие как например roll90, pitch45, yaw180

Больше о Кватернионах…

Пример кода


/* Мы начнем с горизонтального объекта */ 
Cylinder cylinder = new Cylinder("post", 10, 10, 1, 10);
cylinder.setModelBound(new BoundingBox());
/* Создадим Кватернион с 90-градусным-тангажом. */
Quaternion pitch90 = new Quaternion();
pitch90.fromAngleAxis(FastMath.PI/2, new Vector3f(1,0,0));
/* Применим поворот к объекту */
cylinder.setLocalRotation(pitch90);
/* Обновим модель. Теперь она вертикальна. */
cylinder.updateModelBound();
cylinder.updateGeometry();

Интерполяция вращения

Вы можете указать два оборота, и затем jme вычислит (интерполирует) шаги между двумя вращениями:

«Добавление» вращения

Вы можете объединить (добавить) повороты: это означает, что вы сначала осуществите вращение вокруг одной оси, а затем вокруг другой за один шаг.

Quaternion myRotation = pitch90.mult(roll45); /* тангаж и крен */

Поиск и устранение неисправностей при вращении

Объект оказался в неожиданном месте или под неожиданным углом? Если вы получили странные результаты, проверьте следующее:

  1. 3D преобразования являются некоммутативно! Это означает, что имеют огромное значение такие вещи как если вы сначала вы передвинули узел, а потом повернул вокруг оси, или сначала повернули узел, а потом передвинули. Убедитесь, что ваш код делает именно то, что вы от него хотите.
  2. Вы хотите повернуть объект вокруг его центра по оси или вокруг другой стежневой точки вне объекта? Если вы хотите повернуть объект вокруг стержневой точки, то вам необходимо сначала создать(невидимый) стежневой узел и прикрепить к нему объект. Затем применить вращение к родительскому стержневому узлу, а не к самому объекту потомку!
  3. Вы ввели угол в градусах (0-360°) или в радианах (0-2*PI)? 3D движок ожидает радианы, поэтому убедитесь, что вы преобразовали ваши значения! Формула: g° = FastMath.PI * g / 180

Совет: Матричные преобразования

Здесь речь идет только о вращении, но есть 3 типа 3D преобразования: вращение, масштабирование, и перемещение.

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

  • com.jme3.math.Transform, interpolateTransforms() – интерполирует шаг между двумя преобразованиями.


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

Предыдущий: Hello SimpleApplication, Следующий: Hello Assets.

В этом уроке мы рассмотрим создание 3D сцены.

При создании 3D-игры:

  1. Вы создаете некоторые графические объекты такие, как игроки, здания и так далее.
  2. Вы добавляете объекты в сцену.
  3. Вы перемещаете, изменяете размер, поворачиваете, настраиваете цвет и выполнять их анимацию.

Вы узнаете, что граф сцены представляет собой 3D мир и почему корневой (родительский) узел (rootNode) важен. Вы узнаете, как создавать простые объекты, как им давать пользовательские данные (такие как состояние здоровья), и как «трансформировать» их; двигать, масштабировать и вращать. Вы поймете разницу между двумя типами “Spatials” в графе сцены: Узлами и Геометриями.

Пример кода:

package jme3test.helloworld;

import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.shape.Box;

/** Пример 2 – как использовать узлы в качестве рычага, для управления объектами на сцене.
 * Вы можете вращать, перемещать и масштабировать объекты, манипулируя их родительскими узлами.
 * Особенность корневого узла: только то, что прикреплено к нему, появляется на сцене. */
public class HelloNode extends SimpleApplication {

    public static void main(String[] args){
        HelloNode app = new HelloNode();
        app.start();
    }

    @Override
    public void simpleInitApp() {

        /** Создание синего коуба с координатами (1,-1,1) */
        Box box1 = new Box(1,1,1);
        Geometry blue = new Geometry("Box", box1);
        blue.setLocalTranslation(new Vector3f(1,-1,1));
        Material mat1 = new Material(assetManager, 
                "Common/MatDefs/Misc/Unshaded.j3md");
        mat1.setColor("Color", ColorRGBA.Blue);
        blue.setMaterial(mat1);

        /** Создание красного куба прямо над синим (1,3,1) */
        Box box2 = new Box(1,1,1); 
        Geometry red = new Geometry("Box", box2);
        red.setLocalTranslation(new Vector3f(1,3,1));
        Material mat2 = new Material(assetManager, 
                "Common/MatDefs/Misc/Unshaded.j3md");
        mat2.setColor("Color", ColorRGBA.Red);
        red.setMaterial(mat2);

        /** Создание стержневого узла в (0,0,0) и прикрепление его к корневому узлу. */
        Node pivot = new Node("pivot");
        rootNode.attachChild(pivot); // поместить этот узел на сцену
        /** Прикрепим два куба к этому узлу. (Который идентичен корневому.) */
        pivot.attachChild(blue);
        pivot.attachChild(red);
        /** Повернём наш новый узел: заметьте, оба куба поворачиваются! */
        pivot.rotate(.4f,.4f,0f);
    }
}

Собрав и запустив образец кода. Вы должны увидеть два цветных куба наклоненных под одним и тем же углом.


Понимание терминологии

В этом уроке вы узнаете некоторые новые термины: 

Что вы хотите сделать Как вы скажете на языке JME3
Скомпоновать 3D сцену Заполнить граф сцены
Создать объекты сцены Создать Spatials (например, создать Геометрию)
Сделать объект видимым на сцене Присоединить Spatial к родительскому узлу (rootNode)
Сделать объект исчезающим со сцены Отсоединить Spatial от rootNode
Расположение/движение, повернуть или изменить размер объекта Переместить или вращать, или масштабировать объект = трансформация (преобразование) объекта

Каждое JME3 приложение имеет корневой узел (rootNode). Ваша игра автоматически наследует объект – корневой узел (rootNode) от базового приложения (SimpleApplication). Все прикрепленное к корневому узлу является частью графа сцены. Элементы графа сцены – Spatial (пространственные или те, кто занимает какое-то пространство).

  • Spatial содержит местоположение, вращение и масштаб(размер) объекта.
  • Spatial может быть загружен, изменен и сохранен.
  • Есть два вида Spatial: Узлы и Геометрии.
  Геометрия Узел
Видимость: Геометрия является видимым объектом сцены Узел является невидимым «рычагом» для объектов сцены.
Цель: Геометрии сохраняют внешний вид объекта. Узел группирует Геометрии и другие Узлы вместе.
Примеры: Коробка, сфера, игрок, здание, кусочек местности, транспортного средства, ракет, агенты ИИ, и.т.д … Корневой узел(rootNode), напольный узел, группирующий несколько территорий, пользовательский узел, связывающий пассажира и автомобиль, игрока и оружие, аудио узел(audio node).

Понимание кода

Что происходит в этом фрагменте кода? Вы используете метод simpleInitApp(), который был введен в первом уроке, чтобы инициализировать сцену.

  1. Вы создаете первую Геометрию куб.
    • Создаёте фигуру куба(Box) с размером (1, 1, 1), что создаст куб в 2*2*2 условных единиц измерения.
    • Располагаете куб в (1, -1, 1), используя метод setLocalTranslation().
    • Оборачиваете фигуру куба в Геометриею.
    • Создаёте синий материал.
    • Применяете материал к Геометрии куба.
    •     Box box1 = new Box(1,1,1);
          Geometry blue = new Geometry("Box", box1);
          blue.setLocalTranslation(new Vector3f(1,-1,1));
          Material mat1 = new Material(assetManager,"Common/MatDefs/Misc/Unshaded.j3md");
          mat1.setColor("Color", ColorRGBA.Blue);
          blue.setMaterial(mat1);
      
  2. Вы создаете вторую Геометрию куба.
    • Создаёте вторую фигуру куба(Box) с тем же размером.
    • Располагаете второй куб в (1, 3, 1). Это прямо над первым кубом, с промежутком в 2 единицы мира между ними.
    • Оборачиваете фигуру куба в Геометриею.
    • Создаёте красный материал.
    • Применяете материал к Геометрии куба.
    •     Box box2 = new Box(1,1,1);
          Geometry red = new Geometry("Box", box2);
          red.setLocalTranslation(new Vector3f(1,3,1));
          Material mat2 = new Material(assetManager,
            "Common/MatDefs/Misc/Unshaded.j3md");
          mat2.setColor("Color", ColorRGBA.Red);
          red.setMaterial(mat2);
      
  3. Создаёте стержневой узел.
    • Называете стержневой узел pivot.
    • По умолчанию узел расположен на (0,0,0).
    • Прикрепляете узел к корневому узлу.
    • Узел не имеет видимых проявлений на сцене.
    •     Node pivot = new Node("pivot");
          rootNode.attachChild(pivot);
      

      Если вы запустите приложение только с кодом до этого места, сцена окажется пустой. Это потому, что узел является невидимым, и вы еще не присоединили никаких видимых Геометрий к rootNode.

  4. Присоедините два куба к стержневому узлу.
            pivot.attachChild(blue);
            pivot.attachChild(red);
    

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

  5. Поверните стержневой узел.
            pivot.rotate( 0.4f , 0.4f , 0.0f );
    

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


Что такое стержневой узел (Pivot Node)?

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

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

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

  • Противоположный вариант: если вы не создадите стержневой узел и попробуете преобразовать Геометрии, то каждое изменение нужно делать относительно каждой Геометрии (ее центра).

    Например: если непосредственно вращать каждый кубик (используя команды red.rotate(0.1f , 0.2f , 0.3f); и blue.rotate(0.5f , 0.0f , 0.25f);) то каждый куб будет вращаться индивидуально вокруг своего центра. Это похоже на планеты, вращающиеся вокруг своего центра.


Как мне заполнить граф сцены?

Задача…? Решение!
Создание Spatial Создать фигуру сетки (Mesh), обернуть ей в Геометрию, и назначить ей материал. Например:

Box mesh = new Box(Vector3f.ZERO, 1, 1, 1); // по умолчанию куб
Geometry thing = new Geometry("thing", mesh);
Material mat = new Material(assetManager, 
   "Common/MatDefs/Misc/ShowNormals.j3md");
thing.setMaterial(mat);

 

Чтобы объекты появились на сцене Прикрепите Spatial к корневому узлу rootNode, или к любому узлу, который прикреплен к корневому узлу:

rootNode.attachChild(thing);

 

Удаление объектов со сцены Отсоедините Spatial от корневого узла или другого узла, который прикреплен к корневому узлу:

rootNode.detachChild(thing);
rootNode.detachAllChildren();
 

Найти объект на сцене по его названию или ID, или по его положению в иерархии родитель-потомок.

Посмотрите на  потомков или родителей:

Spatial thing = rootNode.getChild("thing");
Spatial twentyThird = rootNode.getChild(22);
Spatial parent = myNode.getParent();
Указать, что должно быть загружено при старте Все что вы инициализируете и прикрепляете к корневому узлу rootNode в методе базового приложения simpleInitApp() является частью сцены при старте игры.

Как мне перемещать Spatial-ы?

Есть три типа 3D преобразования: Перемещение(Translation), Масштабирование(Scaling) и Вращение(Rotation).

Движения перемещения Spatials Ось-х Ось-у Ось-z
Укажите новое местоположение в трех измерениях: как далеко оно от начала координат, оно находится правее-выше-впереди?

Чтобы переместить Spatial в определенные координаты, например, (0,40.2f,-2), используйте:

thing.setLocalTranslation( new Vector3f( 0.0f, 40.2f, -2.0f ) );

Для перемещения Spatial на определенное расстояние, например, выше (y=40.2f) и далее назад (z=-2.0f):

thing.move( 0.0f, 40.2f, -2.0f );	
+ вправо

— влево

+ вверх

— вниз

+ вперед

— назад

Изменение масштаба(размера) Spatial Ось-х Ось-у Ось-z
Укажите коэффициент масштабирования в каждом измерении: длина, высота, ширина. Значение между 0.0f и 1.0f сжимают Spatial, больше, чем 1.0f растягивает его, а 1.0f сохраняет прежний масштаб.
Использование для каждого измерения тех же самых значений, масштабирование получается пропорциональным, а различные значения будут растягивать объект.
Попробуйте масштабировать Spatial с коэффициентом  10.0f – в длину, 0,1f — в высоту и 1.0f в ширину.

thing.scale( 10.0f, 0.1f, 1.0f );	
Ширина Высота Длина
Вращение Spatials Ось-х Ось-у Ось-z
3D вращение немного сложней (узнать подробности здесь). Короче говоря: вы можете вращать вокруг трех осей: Тангаж(Pitch), Рысканье(Yaw), Крен(Roll). Вы можете указывать углы в градусах путем умножения значения градусов с FastMath.DEG_TO_RAD.

Крен объекта на 180° градусов вокруг оси z:

thing.rotate( 0f , 0f , 180*FastMath.DEG_TO_RAD );
Если ваша игровая идея требует серьезного объема вращений, то стоит посмотреть – что такое кватернионы, структура данных которая позволяет объединять и хранить вращения эффективно.
thing.setLocalRotation(
   new Quaternion().fromAngleAxis(180*FastMath.DEG_TO_RAD, new Vector3f(1,0,0)));
Тангаж = Положительное кивание головой. Рысканье = Отрицательное вращение головой.

 

Крен = Движения головой к плечам.

Как мне устранить неполадки со Spatial?

Если вы получаете странные результаты, проверьте, возможно, вы сделали следующие распространенные ошибки:

Проблема? Решение!
Созданная Геометрия не появляется на сцене Вы прикрепили ее (узлу, который прикреплен к) к корневому узлу( rootNode)?
Имеется ли у нее материал?
Каково ее перемещение (расположение)?
Возможно, это положение за камерой или закрыто другой Геометрией?
Возможно она слишком мала или огромна чтобы её можно было увидеть?
Это слишком далеко от камеры? (Попробуй cam.setFrustumFar(111111f); видимость увеличится)
Spatial вращается в неожиданном направлении Использовали ли вы значения в радианах или градусах? (Если в градусах, то нужно перемножить с FastMath.DEG_TO_RAD, чтобы преобразовать в радианы)
Вы создали Spatial в начале координат (Vector.ZERO) до начала его движения?
Вы вращаете вокруг предполагаемого стержневого узла или вокруг чего-то еще?
Вы вращали вокруг правой оси?
Геометрия имеет неожиданный цвет или материал. Вы используете повторно материал на другой Геометрии и случайно поменяли свойства? (если так, то сделайте клонирование mat2 = mat.clone(); )

Как добавить пользовательские данные к Spatial?

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

В зависимости от вашей игры, игровые объекты не только лишь меняют свое местоположение, вращается или изменяет масштаб (те преобразования, о которых вы только что узнали). У игровых объектов также есть пользовательские свойства, такие как здоровье, инвентарь, оборудование или прочность корпуса у космического корабля. В Java вы представляете данные сущности в качестве переменных классов, например, Float, Strings или массивы.

Вы можете добавлять пользовательские данные непосредственно к любому узлу или геометрии. Вам не нужно расширять класс Node, чтобы включить переменные! Например, чтобы добавить такие пользовательские данные как идентификационный номер(ID) узла:

pivot.setUserData( "pivot id", 42 );

Чтобы получить идентификационный номер этого узла в другом месте, вы должны использовать:

int id = pivot.getUserData( "pivot id" );

Используя различные строковые ключи (здесь ключ – это pivot id), вы можете получить и установить несколько значений любых данных которые должен переносить Spatial. Когда вы начнете писать свою игру, вы можете добавить значения топлива к узлу автомобиля, значения скорости к узлу самолета или количество золотых монет к узлу игрока и многое другое. Однако, следует отметить, что только пользовательские объекты с интерфейсом Savable могут быть переданы.


Вывод

Вы узнали, что ваша 3D сцена — это граф сцены состоящий из Spatial: видимых Геометрий и невидимых Узлов. Вы можете преобразовывать Spatial, или прикреплять их к узлам и преобразовывать узлы. Вы знаете самый простой способ, как добавить пользовательские свойства объекта (таких как здоровье игрока или скорость авто) в Spatial.

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


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

Предыдущий: Уроки для начинающих, Следующий: Hello Node.

Предпосылка: это руководство предполагает, что вы уже загрузили и установили jMonkeyEngine SDK.

В данной серии уроков мы предполагаем, что вы используете  jMonkeyEngine SDK. Как Java программист, вы быстро увидите, что, в принципе, вы можете писать код jMonkeyEngine в любой среде (IDE NetBeans, Eclipse, IntelliJ) разработки или даже из командной строки.

Хорошо, давайте приступим к созданию нашего первого приложения в jMonkeyEngine3.

Создание проекта:

В jMonkeyEngine SDK:

  1. Выберите Файл ▸ Создать проект… в главном меню.
  2. В появившемся окне Создать проект выбираете пакет JME3 затем Basic Game и кликните [Далее].
    1. Укажите имя проекта, например, HelloWorldTutorial.
    2. Укажите путь, где будет храниться ваш новый проект, например, папка jMonkeyProjects в вашем домашнем каталоге.
  3. Нажмите [Готово].

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

Мы рекомендуем пройти все шаги самостоятельно, как описано в уроках. Кроме того, вы можете создать проект, основанный на шаблоне JmeTests в jMonkeyEngine SDK. Так создастся проект, который уже содержит jme3test.helloworld образцы ( и многое другое). Например, вы можете использовать проект JmeTests чтобы проверить, получилось ли все правильно.

Расширим SimpleApplication

В этом уроке вам нужно создать пакет jme3test.helloworld в вашем проекте, и создать в нем файл HelloJME3.java.

В jMonkeyEngine SDK:

  1. Щелкните [ПК Мыши] на папке с исходными файлами вашего проекта (папка HelloWorldTutorial в окошке слева сверху(если вы выбрали это название)).
  2. Выберите в выпавшем меню Новый… ▸ Класс Java… для создания нового файла.
  3. Введите имя класса: HelloJME3.
  4. Введите имя пакета: jme3test.helloworld.
  5. Нажмите [Готово].

SDK создаст для вас файл HelloJME3.java.


Пример кода

Замените содержимое файла HelloJME3.java на следующий код:


package jme3test.helloworld;
 
import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
import com.jme3.math.ColorRGBA;

/** Пример 1 - как начать с самого простого приложения JME3.
* На экране отображается 3D куб с просмотром со всех сторон
* и перемещением с помощью мыши и кнопок WASD. */

public class HelloJME3 extends SimpleApplication {
 
    public static void main(String[] args){
        HelloJME3 app = new HelloJME3();
        app.start(); // начало игры
    }
 
    @Override
    public void simpleInitApp() {
        Box b = new Box(1, 1, 1); // создание фигуры куба
        Geometry geom = new Geometry("Box", b);  // создание геометрии куба из фигуры
        Material mat = new Material(assetManager,
          "Common/MatDefs/Misc/Unshaded.j3md");  // создание простого материала
        mat.setColor("Color", ColorRGBA.Blue);   // установка цвета материала: синий
        geom.setMaterial(mat);                   // установка материала куба
        rootNode.attachChild(geom);              // отобразить куб на сцене
    }
}

Щелкните правой кнопкой  мыши на поле, куда вы вставили код и выбираете Выполнить файл. При появлении диалогового окна настроек jME3, подтвердите настройки по умолчанию.

  1. Вы должны увидеть окно, отображающее простой 3D куб.
  2. Нажимайте клавиши WASD и двигайте мышью, чтобы перемещаться.
  3. Посмотрите на FPS (количество кадров в секунду) и расчеты по объекту в левом нижнем углу. Вам понадобиться эта информация во время разработки, вы ее удалите в конце. (Чтобы прочитать числа корректно, считайте, 14 линий текстовых расчетов? за 14 объектов с 914 вершинами).
  4. Нажмите клавишу Esc, чтобы закрыть приложение.

Поздравляем! Теперь давайте выясним, как это работает!


Понимание кода

Код описанный выше инициализирует сцену и запускает приложение.

Старт SimpleApplication (простого приложения)

Посмотрите на первую строчку: ваш класс HelloJME3.java является расширением com.jme3.app.SimpleApplication.


public class HelloJME3 extends SimpleApplication {
  // ваш код...
}

Каждая игра JME3 является экземпляром класса com.jme3.app.SimpleApplication. Класс SimpleApplication является простейшим примером приложения: он управляет графом 3D-сцены, проверяет ввод данных пользователем, обновление состояния игры, автоматически рисует сцену на экране. Это основные функции игрового движка. Вы просто расширяете это простое приложение и настраиваете его при создании своей игры.

Вы запускаете каждую игру JME3 из метода Main(), также как и любое стандартное приложение Java:

  1. Создайте экземпляр класса на основе SimpleApplication
  2. Вызовите метод start() приложения для запуска игрового движка.
public static void main(String[] args){
    HelloJME3 app = new HelloJME3(); // экземпляр игры
    app.start();                     // старт игры!
}

app.start (); — строчка, которая открывает окно приложения. Давайте узнаем, как вы помещаете что-то в это окно (сцену) дальше.


Понимание терминологии

Что вы хотите сделать Как вы это скажете в терминологии JME3
Вы хотите создать куб. Я создаю Геометрию(Geometry) 1*1*1 с фигурой Куба(Box).
Вы хотите использовать синий цвет. Я создаю Материал(Material) со свойством синего цвета.
Вы хотите раскрасить куб в синий цвет. Я задаю Материал с синим цветом для Геометрии с формой Куба
Вы хотите добавить куб в сцену. Я прикрепляю Геометрию Куба к rootNode (корневому узлу).
Вы хотите, чтобы куб появился в центре сцены. Я создаю Куб(Box) в начале координат = Vector3f.ZERO

Если вы не знакомы с терминологией, подробнее о графе сцены здесь.


Инициализация сцены

Посмотрите на остальную часть образца кода. Метод simpleInitApp() вызывается автоматически один раз, в начале, при запуске приложения. Каждая игра JME3 должна содержать этот метод. В методе simpleInitApp(), вы загружаете игровые объекты до начала игры.


public void simpleInitApp() {
    // инициализация вашего кода...
}

Код инициализации синего куба выглядит следующим образом:


public void simpleInitApp() {
    Box b = new Box(1, 1, 1); // создание фигуры куба
    Geometry geom = new Geometry("Box", b);  // создание геометрии куба из фигуры
    Material mat = new Material(assetManager,
    "Common/MatDefs/Misc/Unshaded.j3md");  // создание простого материала
     mat.setColor("Color", ColorRGBA.Blue);   // установка цвета материала: синий
     geom.setMaterial(mat);                   // установка материала куба
     rootNode.attachChild(geom);              // отобразить куб на сцене
}

В стандартной JME3 игре имеется следующий процесс инициализации:

  1. Вы инициализируете игровые объекты:
    • Вы создаете или загружаете объекты и размещаете их.
    • Вы делаете их видимыми на сцене, присоединяя их к rootNode (корневому узлу).
    • Например: загрузка игрока, местности, неба, противников, препятствий, …, и установка их на стартовые позиции.
  2. Вы инициализируете переменные:
    • Вы создаете переменные для отслеживания состояния игры.
    • Вы задаёте переменным, их начальные значения.
    • Например: установим счет – 0, установим здоровье –100%, …
  3. Вы инициализируете клавиши клавиатуры и действия мышью.
    • Следующие привязки ввода данных предварительно настроены:
      • Клавиши WASD – перемещение по сцене.
      • Движение мышью и кнопки со стрелками – поворот камеры.
      • Кнопка Esc – выход из игры.
    • Задайте ваши собственные дополнительные кнопки и клики мышью.
    • Например: левый клик мыши для выстрела, кнопка пробел для прыжка, …

Будущее SimpleApplication

Планируется изменить SimpleApplication. Некоторое время назад было решено, что мы должны переопределить класс Application. SimpleApplication в особенности представляет собой проблему защищенных «магических» полей, которые, с одной стороны, позволяют с легкостью взломать одно простое одно-классное приложение, а с другой стороны, новые пользователи его не любят, потому что они понятия не имеют, где cam и AssetManager. К сожалению, много кода относится к Application, и его сложно изменить… особенно в app states.

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

Если вы посмотрите на конструктор SimpleApplication идущий по умолчанию, вы поймете, как это работает.

public SimpleApplication() {   
    this(new StatsAppState(), new FlyCamAppState(), new AudioListenerState(), new DebugKeysAppState());}

Базовое приложение вводится при построении с AppStates по умолчанию. Давайте посмотрим на второй конструктор.

public SimpleApplication( AppState... initialStates ) {   
    super(initialStates);
}

Он позволяет указать, какой AppState вы хотите для своего приложения. Таким образом, SimpleApplication удобен для тестовых проектов (я очень часто использую его как он есть), но я рекомендую для полноценной игры, чтобы его использовали следующим образом:

public class MyGame extends SimpleApplication {

    public MyGame(){
         super(new MyCustomSate(), new AnotherState(), ....);
    }

    public static void main(String[] args) {
        MyGame app = new MyGame();
        app.start();
    }

}

Затем вся логика реализована в AppStates, и ваша SimpleApplication никогда сильно не изменяется, за исключением случаев, когда вы хотите добавить начальную загрузку AppState (или, может быть, вы хотите иметь AppState, который управляет AppStates …), SimpleApplication — это всего лишь список состояний, которые вы используете.

В будущих версиях весь код в SimpleApplication будет переработан в AppStates (InputHandlingState, RenderAppState, какой то другой), и вы будете решать, что вам нужно использовать. Однако как наследия мы сохранили код как есть на данный момент.


Вывод

Вы узнали, что SimpleApplication является хорошей отправной точкой, потому что оно дает вам:

  • Метод simpleInitApp(), где вы можете создавать объекты.
  • rootNode, к которому вы можете прикреплять объекты, чтобы они появлялись на сцене.
  • Полезные настройки ввода данных по умолчанию, с помощью которых уже можно перемещаться по сцене.

При разработке игровых приложений вы хотите:

  1. Инициализировать сцену игры.
  2. Запустить(триггер) игровые действия.
  3. Реагировать на вводимые данные пользователя(реагировать на нажатие клавиш управления персонажем, например).

В следующих уроках мы узнаем, как выполнить эти задачи с jMonkeyEngine 3.

Продолжить изучать урок Hello Node, где вы узнаете более подробную информацию о том, как инициализировать игровой мир, также известный как граф сцены.


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


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


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

Перед тем как начинать создавать игры, убедитесь, что вы понимаете основные термины в построении 3D игр.

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

Затем продолжите изучение jME3 понятий здесь.

Система координат

JMonkeyEngine использует метод правой руки в системе координат, как и OpenGL.

Система координат состоит из:

  • Начало, одна центральная точка в пространстве.
    • Начальная точка всегда имеет координату ноль, в Java: new Vector3f(0,0,0)
  • Три оси координат, которые взаимно перпендикулярны, и пересекаются в начале.
    • Ось Х – располагается слева на права.
    • Ось У – снизу вверх.
    • Ось Z – начинается перед вами и идет к вам.

coordinate-system

Каждая точка в пространстве однозначно определяется своими координатами X, Y, Z. Три числовые координаты показывают, сколько образных «шагов» нужно пройти по трем осям до точки. Тип данных для всех векторов в jME3: com.jme3.math.Vector3f. Все вектора относятся к описанной системе координат.

Например: До точки new Vector3f(3,-5,1) нужно сделать три шага направо, 5 шагов вниз и 1 шаг к вам.

  • Единица измерения («один шаг») в jME3 – «мировая единица» (world unit) или коротко: wu. Как правило, 1 wu принимается как 1 метр. Но вы можете принять любое расстояние, которое вам нравиться, главное, помнить об этом на протяжении всей вашей игры.

Для ориентации:

  • Расположение камеры по умолчанию — Vector3f(0.0f, 0.0f, 10.0f).
  • Камера по умолчанию смотрит в отрицательном направлении по оси Z: вектор — Vector3f(0.0f, 0.0f, -1.0f)

Это означает, что точка наблюдения игрока расположена на положительной стороне оси Z.

Как перемещаться по 3D сцене

Когда вы играете в 3D игры, вы, как правило, хотите перемещаться по 3D сценам. Обратите внимание, что по умолчанию, курсора мыши не видно. Мышь установлена контролировать вращение камеры.

По умолчанию в jME3 используются следующие общий навигационный ввод:

Вводимые данные Движение камеры Точка зрения (POV) игрока
При нажатии W и S клавиш Перемещение камеры вперед и назад Вы передвигаетесь вперед и назад
При нажатии A и D клавиш Перемещение камеры влево и право Вы делаете шаг влево или право
При нажатии Q и Z клавиш Перемещение камеры вверх или вниз Вы летаете вверх или вниз
При движении мыши влево-вправо Вращение камеры влево-вправо Вы смотрите влево или вправо
При движении мыши вперед-назад Вращение камеры вверх-вниз Вы смотрите в небо или под ноги

Настройки по умолчанию вызывают «WASD клавиши» (“WASD keys) и «Просмотр мышью» (“Mouse Look”). Вы можете настроить свою обработку ввода для вашей игры. К сожалению, эти настройки лучше всего работают с клавиатурой QWERTY/QWERTZ.

Граф сцены и корневой узел (RootNode)

Граф сцены представляет 3D мир. Объекты в графе сцены jME3 называются Spatial (буквально: пространственный, занимающий пространство. Произносится как «Спейшел» ).  Все они прикреплены к корневому узлу (RootNode) и являются частью сцены. Ваша игра будет наследовать объект rootNode от класса SimpleApplication (простое приложение).

scene-graph

  • Присоединение Spatial к rootNode ( или к дочернему узлу) добавляет объект в сцену.
  • Отсоединение Spatial от rootNode ( или от дочернего узла) удаляет объект со сцены.

Все объекты на сцене имеют отношения родитель-потомок. Когда вы преобразуете (перемещаете, вращаете, масштабируете) один из родительских объектов, то преобразуются и все потомки.

  • Граф сцены лишь управляет отношением родитель-потомок между Spatial. Фактическое местоположение, вращение или масштабирование объекта храниться внутри каждого Spatial.

Spatials: Сравнение Узла и Геометрии

Spatial может быть трансформирован (другими слова, он может поменять место положения, повернуться или поменять масштаб). Spatial может быть загружен и сохранен как .3jo файл. Есть два вида Spatials: Узлы и Геометрии:

Spatial
Предназначение: Spatial является абстрактной структурой данных, которая хранит преобразования (перемещение, вращение, масштабирование).
Геометрия Узел
Видимость: Видимый 3D объект Является невидимым «рычагом» для группы объектов
Предназначение: Геометрия представляет из себя «внешний вид объекта»: форма, цвет, текстура, затемнение/прозрачность. Узел это группа геометрий и/или других прикрепленных узлов: Если вы изменяете узел, то это затрагивает все прикрепленные узлы (родитель – потомки) и Геометрии
Содержит: Преобразования, сетку, материал. Преобразования, без сетки, без материала.
Примеры: Куб, сфера, игрок, постройка, кусок поверхности, транспортное средство, ракеты, ИИ агент и так далее rootNode,  guiNode,  audioNode, настраиваемая группа узлов для транспорта и его пассажиров и.т.д..

 Как использовать эти знания?

Прежде чем вы начнете создавать свою игру, вы должны распланировать ваш граф сцены: какие узлы и геометрии вам нужны? Изучите учебное пособие для начинающих, чтобы научиться загружать и создавать Spatials, как поставить их на сцену, прикрепить, отцепить Spatial и как добавлять взаимодействия и эффекты в игру.

Промежуточная и продвинутая документация даст вам более подробную информацию о том, как собрать все части вместе, чтобы создать отличную 3D игру на Java!

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

  • Spatial – подробнее об узлах и геометрии.
  • Траверс SceneGraph – найти любой узел или геометрию в графе сцены.
  • Камера – узнайте больше о камере в сцене.

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

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

3D графика и аудио.

OpenGL является Открытой Графической Библиотекой, спецификация, определяющая платформонезависимый (независимый от языка программирования) программный интерфейс для написания приложений, использующих 2D/3D компьютерную графику. Для языка Java есть две реализации визуализации на основе OpenGL:

  1. Lightweight Java Game Library (LWJGL). – Облегченная библиотека для Java игр.
  2. Java OpenGL (JOGL).

OpenAL – это Открытая Аудио Библиотека, платформонезависимый API для работы с 3D аудио.

Контекст(Context),  Дисплей(Display), Средства визуализации(Renderer).

Jme Контекст(jME Context) подготавливает настройки, средства визуализации, таймер, слушателей ввода и событий, систему отображения, доступную в JME игре.

  • Система Отображения jME(jME Display System) — это то, что рисует пользовательское окно JME (вместо Java Swing).
  • Система ввода(Input System) является компонентом, который позволяет реагировать на ввод пользователя: щелчок мыши и движение, нажатие клавиш на клавиатуре и джойстике.
  • Средства визуализации(Renderer) – это то, что выполняет всю работу по расчету того, как нарисовать 3D сцену на 2D экране.
    • Шейдер(Shader) представляет собой программируемую часть конвейера рендеринга(визуализации). Игровой движок jME3 использует его, чтобы предложить самые передовые настраиваемые материалы.

Геометрия

Полигон(Polygon), Сетка(Mesh), Вершина(Vertex)

dolphin-mesh

Большинство видимых объектов в 3D сцене состоят из полигонов, сетки – персонажи, ландшафты, здания и так далее . Сетка представляет собой сетчатую структуру сложной формы. Преимущество Сетки – в том, что становиться достаточно просто математически визуализировать объекты в реальном времени с достаточной степенью точности что бы они были узнаваемы.

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

Вы можете создавать 3D сетки с помощью инструментов, называемых редакторами сеток, например, Blender. JmonkeyEngine может загружать готовые сетки (= модели) и размещать их в сценах, но он не может редактировать саму сетку.

Материалы: Цвет, Освещение/Затемнение

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

Цвет

Окружающий цвет(Ambient color)

  • Однородный базовый цвет сетки – тот, который делает объект видимым не зависимо ни от какого источника света.
  • Обычно похож на рассеянный (диффузный) цвет.
  • Это минимальный цвет, который нужен вам  для объекта, чтобы он был видимым.

Диффузный цвет(Diffuse color)

  • Базовый цвет сетки плюс разбавленный светом и тенями, которые вызваны источником света.
  • Обычно похож на Окружающий цвет(Ambient color).

Источники света(Light Sources)

Эмиссионный (излучающий) цвет(Emissive color)

  • Цвет света, излучаемого источником или светящимся материалом
  • Только светящиеся материалы, такие как светящиеся фары, имеют эмиссионный цвет, нормальные объекты не обладают этим свойством.
  • Часто белый (солнечный свет).

Отражения(Reflections)

Блеск(Shininess)

  • Степень блеска поверхности (1-128).
  • Блестящие объекты имеют небольшие, четко очерченные блики. (Например, стекло, вода, серебро)
  • Обычные объекты имеют широкие, размытые блики. (Например, металл, пластик, камень, полированные материалы)
  • Неравномерные объекты не блестят и не имеют бликов. (Например, ткань, бумага, дерево, снег)

Установите зеркальный цвет(Specular color) на ColorRGBA.Black(Черный), чтобы выключить блеск.

Зеркальный цвет(Specular Color)

  • Если материал блестящий, то зеркальный цвет(Specular Color) – это цвет отраженных бликов.
  • Обычно такой же как и у источников света, эмиссионный цвет(emissive color) (например, белый).
  • Вы можете использовать цвета для достижения специальных зеркальных эффектов таких как металлические или переливающиеся отражения.
  • Не блестящие объекты имеют черный зеркальный цвет. 

tanlglow2

Материалы: Текстуры

Текстуры являются частью Материалов. В простейшем случае, объект может иметь только одну текстуру – карту цветов(Color Map), загруженную из одного файла изображений. Если вы вспомните старые компьютерные игры, то там все выглядело довольно просто.

Чем больше информации которую вы (разработчик игры) предоставляете дополнительно к карте цветов (Color Map), тем выше степень детализации и реализма. Если вы хотите фотореалистичной визуализации, или мультяшной визуализации (Cel Shading), все будет зависеть от качества ваших материалов и текстур. Современная 3D графика использует несколько слоев информации для описания одного материала, каждый отображаемый слоя является текстурой.

У вас нет текстур? Скачайте бесплатно текстуры с opengameart.org. Только не забывайте прописывать авторские права вместе с используемыми текстурами!

Наложение текстур

Карта цветов / Диффузная карта (Color Map / Diffuse Map)

  • Простой файл изображения или процедурная текстура, которая описывает видимую поверхность объекта.
  • Изображение может иметь альфа-каналы для прозрачности.
  • Карта цветов(Color Map) это минимальная текстура. Вы можете отображать больше текстур для внесения дополнительных улучшений.
  • Карта цветов без теней. Диффузные карты(Diffuse Map) называются так потому что используются в Фонг-освещенном материале, потому что эта текстура определяет основные цвета света, которые рассеиваются этим объектом.

tank_diffuse

Карта Рельефа (Bump Map)

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

  • Вы можете использовать Карту Нормалей(Normal Map), чтобы моделировать мелкие детали, такие как трещины в стенах, ржавчина, текстуру кожи или ткани (Узнать больше о Bump Map).
  • Вы можете использовать Карты Высоты(Height Map) для моделирования больших территорий с долинами и горами.

Карта высот (Height Map)

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

mountains512

Карта нормалей(Normal Map)

  • Хорошо сделанная карта нормалей позволяет добиться большей детализации без необходимости добавления дорогостоящих полигонов к сетке. Она содержит информацию о затенении, которая делает объект более гладким и более мелкозернистым.
  • Когда вы открываете карту нормалей в графическом редакторе, она выглядит как ложно-цветная версия Карты Цветов. Карты нормалей, однако, никогда не используются для окрашивания, вместо этого, каждый цвет несет данные о смещении выступов и трещин на поверхности. Данные о смещении представлены Нормалями Поверхности(Surface Normals) склонов, отсюда и название.
  • Вы не сможете рисовать или редактировать карты нормалей вручную, профессиональные дизайнеры используют программное обеспечение для расчета 3d моделей высокого качества. Вы можете либо купить профессиональный набор текстур или найти бесплатные коллекции, которые включают в себя карты нормалей.

tank_normals

Зеркальные карты (Specular Map)

  • Зеркальная карта дополнительно улучшает реализм поверхности объекта: она содержит дополнительную информацию о блеске, обеспечивая больший реализм освещения.
  • Начните с копии диффузной карты в средне серой цветовой гамме, которая соответствует средней яркости/тусклости этого материала. Затем добавьте более светлые оттенки серого для более гладких, блестящих, более отражающих областей; И более темные оттенки серого для более тусклых, более грубых, изношенных областей. Полученный файл изображения похож на черно-белую версию диффузной карты.
  • Вы можете использовать цвета в зеркальной карте, чтобы создать определенные отражающие эффекты (поддельное иридизерование, металлический эффект).

tank_specular

Бесшовные плиточные текстуры

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

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

BrickWall

Смотрите также это пособие о том, как сделать бесшовные текстуры в Photoshop.

UV-развертка (преобразование) / Текстурный Атлас(UV Maps / Texture Atlas)

Создать текстуру для куба легко – но, что насчет персонажа: его лица, конечностей? Для более сложных объектов, вам потребуется рисовать текстуру также, как и для плоских: Где один файл изображения содержит контур передней, задней и боковой части объекта рядом друг с другом. Конкретные области плоской текстуры  (UV-координаты) отображаются на определенным областям вашей 3D модели (XYZ-координатам) отсюда и название UV-карты(развертка). Используя UV-развертку (также известную как Текстурный Атлас), учитывайте, что одна модель может иметь различные текстуры на каждой из сторон. Вы можете создавать одну соответствующую UV-развертку для каждой текстуры.

Получение правильных швов и отображение имеет решающее значение: вам придется использовать графический инструмент, такой как Блендер, для создания UV-развертки (Текстурного Атласа) и сохранить правильно координаты. Это стоит того, чтобы изучит это, модели с UV-отображением выглядят намного профессиональнее.

Car

Отображение окружающей среды

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

Вы создаете кубическое пространство(Cube Map) для отображения среды: возможно и сферическое(Sphere Map), но в таком случае часто происходят искажения. Обычно выставляется изображение, охватывающее 360 градусов фоновой сцены – очень похоже на скайбокс. Рендер (визуализатор) отображает эту среду на текстуре отражающей поверхности, что приводит к приемлемому эффекту «стекло/зеркало/вода». Также как и в скайбоксе, отражение является статическим, и динамические вещи (например, гуляющий игрок) не являются частью отражения.(!)

glass-teapot1

Смотрите также: Вода.

MIP текстурирование

MIP текстурирование означает, что вы предоставляете одну текстуру в двух или трех исполнениях в одном файле (MIP = “multum in parvo” = “много в малом”). В зависимости от того, как близко или далеко камера, движок автоматически выдает более или менее подробную текстуру объекта. Таким образом объекты выглядят прорисованными как вблизи, так и издалека. Такой подход хорош всем, однако требует больше времени на создание и больше места для хранения текстур. Если вы не предусмотрите эти детали, то jMonkeyEngine создаст базовые MIP текстуры автоматически, в качестве оптимизации.

Процедурные текстуры

Процедурные текстуры генерируются от повторяющегося маленького изображения, плюс некоторые псевдослучайные вариации градиента (так называемые шумы Перлина). Процедурные текстуры выглядят более естественней, чем статические прямоугольные текстуры, и их менее искажает на сферах. На больших моделях их повторяемость гораздо менее заметна, чем бесшовная плиточная текстура. Процедурные текстуры идеально подходят для неравномерных больших по площади текстур таких как: трава, почва, породы, ржавчина и стены. Используйте плагин jMonkeyEngine SDK Нео Texture для их создания.

neotexture-2

Смотрите также: Создание материалов в Блендере, Блендер: каждый материал, известный человеку.

Анимация

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

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

Подготовка (Rigging) и Покрытие (Skinning)

Анимированный персонаж имеет «арматуру»: внутренний скелет (кости) и внешнее покрытие (кожа или еще называется скин). Кожа(скин) является видимой частью персонажа и включает в себя еще и одежду. Кости не видны и используются для интерполяции (расчета) морфинга (изменений) кожи(скина).

JME3, игровой движок, загружает и воспроизводит только уже записанные анимации. Вы должны использовать инструмент (такой как Blender), чтобы настроить (одежду, кожу и анимирование) персонажа.

  1. Подготовка (Rigging): Построение скелета персонажа.
    • Создавайте как можно меньше костей, чтобы уменьшить сложность.
    • Кости связаны иерархически: перемещение одной может повлечь перемещение другой (например, предплечье тянет кисть).
    • Кости располагаются по определенной схеме наименования, так что 3D движки знают что к чему.
  2. Покрытие(Skinning): ассоциирование отдельных костей с соответствующими участками кожи(скина).
    • Каждая кость соединена с частью кожи. Анимация происходит так: кость (невидима) тянет кожу (видима) за собой. Для примера, бедренная кость соединяется с кожей ноги.
    • Определенная зона кожи может быть затронута более, чем одной костью (например, колено, локоть).
    • Соединение между костями и кожей осуществляется постепенно: вы назначаете вес, сколько кожных полигонов будет задействовано при движении какой-нибудь кости. Например: Когда бедренная кость движется, нога полностью затронута, тазобедренных суставов меньше, а головы вообще отсутствует.
    • jMonkeyEngine поддерживает покрытие кожей(скининг) аппаратно (на GPU, а не на CPU).
  3. Анимация по ключевым кадрам (keyframe): Ключевой кадр – это один из снимков последовательности движения.
    • Серия ключевых кадров составляет одну анимацию.
    • Каждая модель может иметь несколько анимаций. Каждая анимация имеет идентификационное имя (например, «прогулка», «нападение», «прыжок»).
    • Вы задаёте в своей игре код, который будет подгружать ключевые кадры анимации.
В чем разница между анимацией (Подготовка(Rigging), Покрытие(Skinning), Ключевые кадры) и преобразованием (поворот, масштабирование, перемещение)?

  • Преобразование проще, чем анимация: Иногда, трансформируя геометрию можно добиться похожести на анимацию: например, вращающаяся мельницы, пульсация энергетического шара, движение стержней в машине. Преобразование легко осуществляются с помощью методов JME3.
  • Анимация более сложна и кодируется в специальном формате (keyframes). Она искажает поверхность объекта и осуществляет ряд сложных движений, которые могут быть записаны (во внешних инструментах) и воспроизведены (в JME3).

Кинематики

  • Суть прямой кинематики состоит в том, что воздействие передаётся по иерархической цепочке сверху вниз, то есть дочерние сегменты движутся относительно родительских. Сначала положение и/или ориентацию меняет родительский сегмент. Например, при движении тазобедренного сустава двигаются все потомки, т.е. коленный сустав и все остальные.
  • Инверсная кинематика использует принцип, диаметрально противоположный принципу прямой — перемещение компонентов-потомков приводит к изменению положения компонентов-предков, то есть алгоритм рассчитывает положение и ориентацию компонентов-предков, исходя из положения и ориентации компонентов-потомков.

Контроллер и Канал

В JME3 приложении вы регистрируете анимированные модели в Анимационном контроллере. Объект контроллера предоставляет доступ к доступным последовательностям анимации. Контроллер имеет несколько каналов, каждый канал может запускать одну анимационную последовательность за раз. Для запуска нескольких последовательностей вы создаете несколько каналов и запускаете их параллельно.

Искусственный интеллект (ИИ)

NPC (управляются компьютером)  игроки – это персонажи (NPC –НИП: неигровой персонаж) нужные для забавы в игре, если конечно они не тупо бьются о стену или просто бегут на линию огня. Вам нужно создать NPC, которые бы «знали» о своей окружающей среде и обстановке и мог бы принимать решения, основанные на текущем состоянии игры – в противном случае игрок будет их просто игнорировать. В большинстве случаев стараются сделать так, чтобы враг своими действиями бросал бы вызов игроку, навязывая ему более интересный путь развития событий в игре.

«Умные» игровые элементы называются агентами искусственного интеллекта (ИИ агенты). ИИ агенты могут быть использованы для реализации вражеских NPC, а также обученных животных. Вы также можете использовать их, чтобы  создавать автоматические системы сигнализаций, блокирующие двери и «вызывающие охранников» после того как игрок поднимет тревогу.

Область применения ИИ, среди прочего:

  • Знания — знание это данные, к которым ИИ имеют доступ и на основе которых основывают свои решения. Реалистичные агенты «знают» только то что они «видели и слышали». Это подразумевает что информация может быть скрыта от ИИ. Вы можете иметь всезнающего ИИ или позволить лишь некоторым ИИ агентам обмениваться информацией, или позволить некоторым знать о текущем состоянии игры. Например: после того, как игрок разъединяет провод, только несколько охранников с двусторонней связью начинают двигаться в сторону позиции игрока, в то время как другие охранники даже не подозревают еще ничего.
  • Цель планирования – планировать то, какие ИИ агенты будут предпринимать меры. Каждый агент имеет свои приоритеты в достижении какой-либо цели, для достижения будущего состояния. При программировании вам нужно разделять цели агентов на несколько подцелей. Агент сверяет свои знания с текущим состоянием игры, выбирает из имеющихся тактик и стратегий, сортирую по приоритетности. Агент неоднократно тестирует пути достижения цели с текущим состоянием. Если получается неуспешно, то он отказывается от текущей тактики и выбирает другую. Пример: агент ищет наилучший путь на базу игрока в изменяющейся среде, избегая ловушек. Агент догоняет игрока с целью его ликвидировать. Агент скрывается от игрока, когда он VIP цель для устранения.
  • Решение проблемы – Решение проблем связано с тем, как агент реагирует на, препятствия, стоящие между ним и его целью. Агент использует предустановленные факты и правила, вычисляя в каком он состоянии – боль, агония, скука, попал в ловушку. В каждом состоянии только определенное подмножество реакций. Фактическая реакция также зависит от агента, так как реакция не должна блокировать цель!
    Например: если игрок приближается, что делать агенту: атаковать, прятаться, поднять тревогу? А будучи в режиме ожидания: устанавливать ловушки, лечить себя или перезаряжаться? А если возникла опасность собственной жизни: бежать или стать камикадзе?

Более продвинутые ИИ могут самообучаться, например, используя нейронные сети

Есть множество ресурсов, объясняющие интересные алгоритмы ИИ:

А*(A-Star) поиск пути для начинающих

А*(A-Star) теория поиска пути

«Z-Путь» алгоритм (в обратном направлении поиска пути)

GOAP —целевое планирование действий

Neuroph — Java нейронные сети

Математика

Координаты

coordinate-system

Координаты представляют местоположение в системе координат. Координаты относительно начала координат (0,0,0). В 3D-пространстве вам нужно указать три координатных значения, чтобы найти точку: X (справа), Y (вверх), Z (по направлению к вам). Аналогично, -X (слева), -Y (вниз), -Z (от вас). В отличие от вектора (который выглядит аналогичным) координата — это местоположение, а не направление.

Начало координат(Origin)

Началом координат является центральной точкой в мире 3D, где встречаются три оси. Он всегда в координатах (0,0,0).

Пример:

Vector3f origin = new Vector3f( Vector3f.ZERO );

Векторы

Вектор имеет длину и направление, как стрела в 3D пространстве. Вектор начинается с некоторой координаты (x1,y1,z1) или из начала координат и заканчивается на целевой координате (x2,y2,z2). Обратное направление выражается отрицательными выражениями.

Например:

Vector3f v = new Vector3f( 17f , -4f , 0f ); //начинается в (0/0/0)
Vector3f v = new Vector3f( 8f , 0f , 33f ).add(new Vector3f( 0f , -2f , -2f )); // начинается в (8,-2,31)

Единичные вектора

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

  • Vector3f.UNIT_X = (1, 0, 0) = вправо
  • Vector3f.UNITY = (0, 1, 0) = вверх
  • Vector3f.UNIT_Z = (0, 0, 1) = вперед
  • Vector3f.UNIT_ XYZ = 1 uw по диагонали: вправо-вверх-вперед

Инвертируйте компоненты вектора, чтобы изменять его направление, например. Сделав отрицательным в право (1,0,0) получим в лево (-1,0,0).

Нормализованные векторы

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

Вектор Нормали

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

300px-surface_normal

Векторное произведение

Векторное произведение — это вычисление, которое вы используете, чтобы найти перпендикулярный вектор (ортогональный, «прямой угол в 90°). В трехмерном пространстве говорить о ортогональности имеет смысл только в отношении плоскости. Для однозначного определения плоскости необходимы два вектора. Векторное произведение двух векторов, v1 × v2, представляет собой новый вектор, перпендикулярный этой плоскости. Вектор, перпендикулярный плоскости, называется нормалью поверхности.

Например: х – единичный вектор и у – единичный вектор вместе определяют х/у плоскость. Вектор, перпендикулярный к ним, проходит по оси Z. JME может просчитать, что это равенство верно:
( Vector3f.UNIT_X.cross( Vector3f.UNIT_Y ) ).equals( Vector3f.UNIT_Z ) == true

Преобразование(Transformation)

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

Например: Падение и вращение кирпичей в 3D тетрисе.

Slerp (сферическая линейная интерполяция)

Это интерполированное преобразование, которое используется в качестве простой «анимации» в 3D движках. Вы определяете начальную и конечную точку, и постоянную скорость перехода из одного состояния в другое. Вы можете проигрывать движение, приостановить его на различном значении (от 0,0 до 1,0) и проигрывать его назад и вперед. JavaDoc: slerp()

Например: Горение метеорита.
Узнайте больше о 3D математике здесь.

Жаргон разработчиков игр

Культурный словарь игровой студии.

Терминология 3D Вики книга

http://en.wikipedia.org/wiki/User:Jreynaga/Books/3D_Graphics_Terms

Вот тут вы еще можете почитать об основах 3D графики


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

Это Замечание. Вы увидите, много таких Замечаний разбросанных по всей Вики. Посмотрите Описание Замечаний что бы узнать назначения всех типов Замечаний.

SDK Документация.

JMonkeyEngine SDK является нашей рекомендуемой средой разработки игр.

Вот несколько видео о том, как jMonkeyEngine SDK может облегчить жизнь вашей команде разработчиков:


Уроки для начинающих.

Начальные уроки демонстрируют наиболее распространенные случаи и объясняют базовые понятия. Мы рекомендуем вам запускать коды примеров и экспериментировать с ними. Все примеры кода включены в jMonkeyEngine SDK: просто создайте новый проект из шаблона JmeTests.

Чтобы начать писать собственный проект, создавайте новый файл в шаблоне BasicGame.

Нажмите F1 в jMonkeyEngine SDK, чтобы просматривать, искать и копировать код  из предоставляемой  ВИКИ. Справочные документы в SDK всегда соответствуют той версии которую вы используете в настоящее время. ВИКИ обновляется до последней версии jME3.
  • Убедитесь, что вы знакомы с основными понятиями построения 3D игр, такими как граф сцены.
  • beginner-physics

    1.    Hello SimpleApplication – инициализация простого приложения.
    2.    Hello Node – преобразование геометрии и узлов в графе сцены.
    3.    Hello Assets – загрузка 3D моделей, сцен и других модулей.
    4.    Hello Loop – запуск действий в цикле обновления.
    5.    Hello Input – реакция на ввод с клавиатуры и мыши.
    6.    Hello Material – установка материалов, текстур, прозрачности.
    7.    Hello Animation – управление анимироваными моделями.
    8.    Hello Picking – стрельба, нажатие кнопок, выбор и подбор предметов.
    9.    Hello Collision – создание стен и твердых полов.
    10.  Hello Terrain – создание холмистых ландшафтов с текстурами.
    11.  Hello Audio – сопровождение действий и места 3D звуками.
    12.  Hello Effects – создание эффектов частиц, таких как огонь, взрывы, заклинания.
    13.  Hello Physics – отскок ядра и падающие кирпичи.
    14.  Hello Vector3f – визуализация вектора и векторные операции.
    15.  Hello Chase camera – Следящая камера (камера от третьего лица), пример.

    Смотрите также: проблемы запуска образцов?


    Документация для пользователей среднего уровня

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

    Концепция jMonkeyEngine3

    Математическая концепция

    Концепция 3D-графики

    Игра Обучение

    Видео применения учебного пособия

    Обратите внимание, что эти видеоролики используют альфа-функции, доступные только в следующем выпуске.

    Изучите примеры кода в src/main/java/jme3test (также доступен в sdk в меню Файл ▸ Создать проект ▸ JME3 Tests) и в примерах игр, предоставляемых сообществом!!


    Документация для продвинутых пользователей

    Теперь, когда вы понимаете принципы, пришло время чтобы максимально использовать возможности jMonkeyEngine. Глубоко погрузится в API, и узнать про все варианты, включая менее распространенные современные методы. Не перенапрягайтесь, разработка хорошей игры требует времени и преданность делу. Шаг за шагом, чемпион! :)

    Управление игровой логикой

    1. Цикл Обновления
    2. Application States
    3. Пользовательский Control
    4. Многопоточность

    Управление объектами в графе 3D сцены

    Анимация и сцены

    Материалы(Materials), Свет(Light), Тень(Shadow)

    Интеграция Физики

    Аудио и Видео

    Постпроцессорные фильтры и эффекты

    Пейзажи

    Искусственный интеллект(ИИ)(Artificial Intelligence (AI))

    Многопользовательская Сеть

    Система Сущностей

    Камера

    Взаимодействие с пользователем

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

    Настраиваемая визуализация(Rendering)

    Пользовательские инструменты

    Ведение журнала и отладка

    Разработка Android-приложений

    Развертывание

    Сценарии(Scripting)

    Виртуальная реальность и симуляция

    Вклад пользователей jMonkey

    Примеры проектов

    • JmeTests — официальный образец проекта JmeTests.
    • BookSamples — Еще некоторые примеры кода jME3(Из книги)

    Эти примеры кода не поддерживаются основной командой, и мы не можем гарантировать их правильность:

    Обратная связь

    JME3 находится в разработке; Если учебное пособие(оригинальное Англоязычное) не работает должным образом, попробуйте использовать последнюю ежедневную сборку. Если это не «исправит это, то:


    Переведено для jmonkeyengine.ru, оригинал

    Автор перевода: BuGaGa

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