Приклад роботи з ейлерову камерою – РОЗРОБКА ІГОР ДЛЯ ОС ANDROID

Випробуємо клас Eul егСатега, написавши невелику програму Ми хочемо повертати камеру вгору, вниз, вліво і вправо, грунтуючись на дотиках пальця до екрану

Ми також бажаємо переміщати її вперед, якщо натиснута кнопка Наш світ слід наповнити ящиками На рис 1110 зображена картина, яка постане перед очима користувача на початку роботи

Рис 1110 Проста сцена, яка містить 25 ящиків, точкове джерело світла і ейлерову камеру з параметрами, заданими за замовчуванням

Камера буде знаходитися в точці (0 1 3) У світі також розташовуватиметься білий точкове джерело світла в точці (3 3 -3) Ящики розміщуються в сітці з координатами (-4 4) по осі х і (0 -8) по осі z, відстань між ящиками дорівнює 2

Як камера буде реагувати на торкання екрану користувачем Ми хочемо, щоб камера поверталася навколо осі у, якщо користувач проведе пальцем по екрану горизонтально Це еквівалентно повороту голови вліво і вправо Ми також бажаємо, щоб камера поверталася навколо осі х після того, як користувач проведе по екрану вертикально Це еквівалентно руху голови вгору і вниз На додаток ми б хотіли обєднати ці два рухи Найбільш прямолінійний спосіб добитися цього – перевіряти, чи стосується палець екрану, і, якщо це так, порівнювати координати дотику з останнім збереженим значенням Далі можемо реалізувати зміна кута повороту навколо обох осей, використовуючи різницю по осі х для повороту по осі у і навпаки

Ми також хочемо, щоб камера переміщалася вперед при натисканні кнопки, розташованої на екрані Це досить просто Ми просто викликаємо метод Eul erCamera getDi recti on і множимо отриманий результат на швидкість, з якою повинна переміщатися камера, і на зміну часу Як бачите, ми знову реалізовуємо переміщення, засноване на часі Єдине, що нам залишається зробити, – намалювати кнопку (Я вирішив намалювати кнопку розміром 64 х 64 пікселя в нижньому лівому куті екрану) і перевіряти, натискає на неї користувач

Щоб спростити реалізацію, ми дозволимо користувачеві виконувати тільки одну дію за один раз – або повертати камеру, або переміщати її

Ми могли б додати підтримку мультитач, але це ускладнило б нашу реалізацію

Тепер, коли ми описали майбутню програму, поглянемо на клас EulerCameraScreen, реалізацію класу GLScreen, яка знаходиться всередині реалізації класу GLGame, що називається Eul erCameraTest (звичайної тестової структури) Код показаний в лістингу 1110

Лістинг 1110 Фрагменти тесту EulerCameraTestjava, клас EulerCameraScreen

Ми починаємо з опису кількох членів класу Перші два зберігають текстури ящика і вершини текстури куба Ми будемо генерувати ці вершини за допомогою методу createCube, описаного в минулому прикладі

Наступний член класу – це PointLight, з яким ми вже знайомі, як і з екземпляром нашого нового класу Eul erCamera

Наступні кілька членів потрібні для отрисовки кнопки Для неї ми використовуємо окреме зображення розміром 64 х 64 пікселя Нам також знадобляться екземпляри класів SpriteBatcher, Camera2D і TextureRegi on Це означає, що ми обєднаємо 3D-і 20-отрисовку в одному прикладі Останні три члена використовуються для відстеження поточної позиції дотику до екрану (touchPos) в координатах користувальницького інтерфейсу, а також останні відомі точки дотиків Ми використовуємо значення -1 для параметрів lastX і lastY, щоб повідомити, що поки не було жодного дотику

У конструкторі завантажуємо текстуру ящика і створюємо вершини куба точно так само, як і минулого прикладі Ми також створюємо точковий джерело освітлення PointLight і встановлюємо його позицію рівний (3 3 -3) Примірник класу EulerCamera створюється зі стандартними параметрами – поле огляду 67 °, співвідношення сторін відповідає поточному дозволу екрану, відстань ближньої площини відсікання дорівнює 1, а дальньої 100 Нарешті, переміщаємо камеру в позицію (0 1 3), що показано на рис 1110

В іншій частині конструктора просто завантажуємо текстуру кнопки, а також створюємо екземпляри класів SpriteBatcher, Camera2D і TextureRegi on, необхідні для отрисовки кнопки Нарешті, створюємо екземпляр класу Vector2, завдяки чому можемо перетворювати координати дотику до екрану до координатної системі екземпляра класу Camera2D, який використовується для отрисовки елементів користувальницького інтерфейсу, точно так само, як і в грі Великий стрибун

Методи createCube і resume абсолютно не змінилися з попереднього прикладу, тому я не повторюю тут весь їх код

У методі update відбуваються поворот камери і її переміщення, які грунтуються на подіях дотиків до екрану Перше, що ми робимо, – очищаємо буфер цих подій за допомогою виклику методу Input getTouchEvents Далі отримуємо координати поточного дотику першого пальця до екрану Зверніть увагу, якщо палець не торкається до екрану, що викликаються методи просто повернуть останню відому позицію екрану з індексом 0 Ми також перетворюємо координати дотику до координатної системі користувача інтерфейсу Це робиться для того, щоб перевірити, натиснув користувач кнопку в лівому нижньому кутку

Після того як ми отримаємо всі ці значення, виконується перевірка на те, торкається чи палець до екрану в даний момент Якщо так, спочатку перевіряємо, чи не натиснута кнопка, яка заповнює весь простір від точки (0 0) до точки (64 64) двомірної системи координат користувача інтерфейсу Якщо це так, то ми отримуємо поточний напрямок камери і, помноживши на зміну часу, додаємо його до позиції камери

Оскільки ми працюємо з одиничним вектором, камера буде переміщатися на одну одиницю відстані в секунду

Якщо ж користувач не торкнувся кнопки, програма інтерпретує це дотик так, ніби він провів по екрану пальцем Щоб працювати в цьому напрямку далі, нам потрібно знати останню координату дотику до екрану Під час першого дотику користувача до екрану члени 1 astX і 1 astY будуть рівні -1 Це говорить про те, що цього разу ми не можемо обчислити різницю між останньою і поточної координатами дотику до екрану, оскільки у нас є всього лише один відлік даних Тому ми просто зберігаємо поточні координати і повертаємося з методу updateO Якщо координати дотику вже зберігалися, просто знаходимо різниця між значеннями координат по осях х і у для попереднього і поточного дотиків Потім безпосередньо перетворюємо їх до Інкремент кутів повороту

Щоб трохи сповільнити поворот камери, отриману різницю доведеться ділити на 10 Єдине, що залишається зробити, – викликати метод EulerCamera rotate, який відповідно змінить кути повороту камери

Нарешті, якщо палець більше не стосується екрану, встановлюємо значення параметрів lastX і lastY рівними -1, повідомляючи, що нам знову доводиться чекати першого дотику до екрану перед тим, як здійснювати обробку події дотику

Метод present дивно простий завдяки тому, що він містить виклики всіх допоміжних класів Ми починаємо з звичних дій – очищення екрану і установки вікна перегляду Далі вказуємо класу Eul erCamera встановити проекційну і видову матриці

З цього моменту ми можемо малювати на екрані все тривимірні елементи До того як ми зможемо зробити це, слід дозволити тестування глибини, текстурирование і освітлення Далі повязуємо текстуру ящика і вершини куба, а також дозволяємо використання точкового джерела освітлення Зверніть увагу, ми повязуємо текстуру і вершини куба тільки одного разу, оскільки хочемо повторно їх використовувати для всіх отрісовиваємих ящиків Той же самий прийом ми застосовували в прикладі BobTest для прискорення отрисовки за допомогою скорочення кількості змін стану

Наступний фрагмент коду просто малює 25 кубів, розташованих у формі сітки, за допомогою простого вкладеного циклу for Оскільки нам доводиться множити модельно-видову матрицю на матрицю перетворення для того, щоб помістити вершини куба на певні позиції, ми також повинні використовувати методи glPushMatrix і glPopMatrix, щоб не знищувати матрицю камери, яка також є модельно-видовий

Як тільки ми отрісуем все куби, необхідно відвязати вершини куба, а також відключити освітлення і тестування глибини Це критично, оскільки тепер ми збираємося отрісовать двомірний елемент користувацького інтерфейсу, що містить кнопку Оскільки кнопка є круглою, ми також включаємо змішування, щоб зробити кордони текстури прозорими

Отрісовка кнопки працює точно так само, як і отрисовка елементів інтерфейсу користувача в грі Великий стрибун Ми наказуємо екземпляру класу Camera2D встановити вікно перегляду і матриці (на самому справі нам не знадобиться повторно встановлювати вікно перегляду, ви можете вільно отпімізіровать цей метод) і вказуємо екземпляру класу SpriteBatcher, що ми збираємося отрісовать спрайт Ми отрісовиваємих всю текстуру кнопки в точці (32 32) в нашій системі координат розміром (480 х 320), встановленої з допомогою gui Camera

Нарешті, ми просто відключаємо кілька попередніх станів, які підключили раніше, а також змішування і текстурирование

Інша частина класу – це просто порожні методи pause О і dispose О На рис 1111 показаний результат роботи цієї невеликої програми

Рис 1111 Простий приклад, який ілюструє роботу камери для першої особи, мультитач для простоти не дозволені

Досить мило, чи не так Програма має невеликий обєм завдяки нашим допоміжним класам Тепер непогано було б додати підтримку мультитач Ось невелика карта: замість використання опитування, як у попередньому прикладі, застосовуйте реальні події дотику При дотику пальця до екрану виконуйте перевірку натискання кнопки Якщо це трапилося, відзначайте ID покажчика, повязаний з нею так, що він не буде здатний обробляти проведення пальцем по екрану, поки перший палець не відірветься від екрану Події дотику до екрану від всіх інших ID можуть бути інтерпретовані як проведення пальцем по екрану

Джерело: Mario Zechner / Маріо Цехнер, «Програмування ігор під Android», пров Єгор Сидорович, Євген зазноби, Видавництво «Пітер»

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*