Главная » Программирование игр под Android » ТРЮКИ  ПРИ РАЗРАБОТКЕ 3D ИГР – РАЗРАБОТКА ИГР ДЛЯ ОС ANDROID

0

 

3D -программирование – это очень сложное и широкое поле деятельности. Рассматриваются темы, являющиеся минимальными требованиями к программисту, который желает написать простую 3D-Hrpy.

Мы снова рассмотрим наш знакомый вектор и присоединим к нему еще одну координату.

Освещение – это важная часть любой трехмерной игры. Мы изучим, как реализовать простое освещение с помощью OpenGL ES.

Определение объектов программно выглядит довольно громоздко. Мы рассмотрим простой формат 3D -файлов, с помощью которого можно загружать и отрисовывать 3D -модели, созданные с помощью ПО для 3D -моделирования. Начнем с 3D -векторов.

ПЕРЕД СТАРТОМ

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

У нас будет единая начальная активность, предоставляющая нам доступные тесты в виде списка. Мы назовем ее GLAdvancedStarter и сделаем ее активностью, используемой по умолчанию. Просто скопируем активность под названием GL3DBasi csStarter и заменим имена классов тестов. Нам также понадобится добавить каждую из тестовых активностей в подходящий элемент <acti vity> манифеста.

Как и прежде, каждый тест будет расширять возможности класса GLGame; код будет создан как класс GLScreen, связанный с экземплярами класса GLGame. Для экономии места я буду приводить лишь самые важные фрагменты класса GLScreen. Все тесты и начальная активность будут находиться в пакете com. badl ogi с. androi dgames. gl advanced. Некоторые классы станут частью нашего фреймворка и войдут в соответствующие пакеты фреймворков.

ВЕКТОРЫ В 3D

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

Операции, рассмотренные для двухмерных векторов, могут быть с легкостью перенесены в третье измерение. В 3D вектор определяется следующим выражением:

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

Вычитание работает точно так же:

Умножение вектора на скалярное значение производится так:

Измерение длины трехмерного вектора – также несложная операция; мы просто добавляем координату по оси z к уравнению Пифагора:

Основываясь на этом, мы можем нормализовать векторы к единице измерения длины:

Позиции записываются в виде нормальных координат вектора х, у и z.

Скорости и ускорения также представляются как 3D -векторы. Каждый компонент является определенным количеством атрибута по одной оси, например метры в секунду для скорости или метры на секунду в квадрате, если речь идет об ускорении.

Расстояния можно измерить следующим образом – из координат конца вектора нужно вычесть координаты начала, а затем измерить результирующую длину вектора.

Еще одна операция, которая может оказаться полезной, – вращение 3D -вектора вокруг 3D-oceft. Ранее мы уже использовали этот принцип с помощью метода OpenGL ES gl Rotatef . Однако нельзя применять этот принцип для того, чтобы повернуть вектор, содержащий позиции или направления игровых объектов, поскольку он работает только для вершин, которые мы отправляем в GPU. К счастью, в Android API есть класс Matri х, позволяющий эмулировать воздействие OpenGL ES на GPU. Напишем класс Vector3, реализующий все эти особенности. Его код приведен в листинге 11.1, я буду объяснять его по мере необходимости.

Листинг 11.1. Класс Vector3.java. аналог класса Vector в 3D

Класс начинается с объявления нескольких статических массивов чисел с плавающей точкой. Они понадобятся далее для реализации нового метода rotate класса Vector3. Просто запомните, что член matri х содержит 16 элементов, а члены inVec и outVec – 4 элемента.

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

Как и класс Vector2, наш класс Vector3 имеет несколько конструкторов и методов, устанавливающих значения, а также метод сру, поэтому мы можем с легкостью копировать векторы или задавать их значения, используя компоненты, рассчитанные в программе.

Разнообразные методы add, subO и mul О являются расширением одноименных методов, которые присутствовали в классе Vector2. Добавлена всего одна новая координата – z. Данные методы реализуют те особенности, которые мы рассмотрели несколько страниц назад. Довольно прямолинейно, не правда ли?

Методы также практически полностью копируют одноименные методы класса Vector2. Все, что мы сейчас сделали, – добавили новую координату в расчеты.

А вот и новый метод rotate. Как было отмечено ранее, он использует класс Matri х из Android API. Этот класс состоит в основном из нескольких статических методов наподобие Matrix, set I dentityM  или Matri x.rotateMO. Они работают с массивами чисел с плавающей точкой наподобие тех, что мы определили ранее. Матрица хранится как 16 чисел с плавающей точкой, а вектор должен иметь четыре элемента. Я не буду вдаваться в подробности, описывая внутреннюю работу класса. Все, что нам нужно, – это способ эмулировать возможности матрицы OpenGL ES с помощью Java. Данный класс предлагает именно то, что нам необходимо. Все его методы работают с матрицами и делают это так же, как и методы OpenGL ES gl Rotatef , gl Transl atef  или glIdenti tyf .

Этот метод начинается с установки компонента вектора, используется массив i nVec, определенный нами ранее. Далее вызывается метод Matriх. set Identi tyM для члена matrix нашего класса. Это его очистит. С помощью OpenGL ES мы используем метод glIdenti tyf , чтобы проделать то же самое с матрицами, остающимися в GPU. Далее вызывается метод Matrix.rotateMO. В качестве аргумента он принимает массив чисел с плавающей точкой, смещение для этого массива, угол в градусах, на который необходимо повернуть вектор, а также ось, вокруг которой следует осуществить поворот. Этот метод эквивалентен методу gl Rotatef . Он умножит заданную матрицу на матрицу поворота. Наконец, мы вызываем метод Matrix, mul tiplyMVC, который умножит вектор, хранящийся в массиве inVec, на matrix. Это применит к вектору все преобразования, хранимые в члене matri х. Результат будет помещен в outVec. Остаток метода просто получает новые компоненты вектора из массива outVec и сохраняет их в членах класса Vector3.

ПРИМЕЧАНИЕ

Вы можете использовать класс Matrix не только для того, чтобы поворачивать векторы. Он работает с переданными матрицами точно так же, как и OpenGL ES.

И наконец, мы видим привычные методы dist и distSquared, рассчитывающие расстояние между двумя векторами в 3D.

Обратите внимание, метод anglе  я скопировал без изменений из класса Vecto г 2. В то время, как возможно измерить угол между двумя векторами в 3D, мы все равно не получим значение в промежутке от 0 до 360. Обычно мы измеряем угол между двумя векторами на плоскостях ху, zy и xz, используя только два компонента каждого вектора и применяя метод Vector2. angleC.

Думаю, вы согласитесь, что нам не нужно рассматривать пример использования этого класса. Мы можем просто вызвать его так же, как мы это делали с классом Vector2. Перейдем к следующей теме: освещение в OpenGL ES.

Источник: Mario Zechner / Марио Цехнер, «Программирование игр под Android», пер. Егор Сидорович, Евгений Зазноба, Издательство «Питер»

По теме:

  • Комментарии