GLGAME: РЕАЛІЗАЦІЯ ІГРОВОГО ІНТЕРФЕЙСУ

&nbsp

Ми реалізували клас Androi dGame, який повязує все підмодулі для звуку, файлів введення-виведення, графіки та обробки користувача введення Ми знову використовуємо велику частину цього коду в нашої майбутньої двомірної грі на OpenGL ES, тому створимо новий клас GLGame, який реалізує ігровий інтерфейс, який ми описали раніше

Взагалі, ми поки знаємо про OpenGL ES недостатньо, щоб реалізувати інтерфейс Graphics Однак тут вас чекає сюрприз: ми не будемо його реалізовувати OpenGL не дуже добре працює з програмними моделями інтерфейсу Graphics Замість цього ми створимо новий клас GLGraphics, що відслідковує екземпляр класу GL10, отримуваний від GLSurfaceView (лістинг 72)

Лістинг 72 GLGraphicsJava: відстеження GLSurfaceView і примірника GL10 package combadlogiсandroi dgamesframeworkimp1

У цьому класі всього кілька методів-установників і методів-одержувачів Зверніть увагу, що ми будемо використовувати даний клас для візуалізації потоку, запущеного GLSurfaceView Таким чином, у нас може виникнути проблема з викликом методу Vi ew, який працює в основному в потоці користувача інтерфейсу В даному випадку це неважливо, Ми зможемо запитувати тільки ширину і висоту GLSurfaceView, чого нам цілком вистачить

Клас GLGame трохи складніше Він використовує більшу частину коду з класу Androi dGame Єдиний момент, який викликає складності, – синхронізація між візуалізацією і потоками користувача інтерфейсу Розглянемо, як це відбувається (лістинг 73)

Лістинг 73 GLGamejava реалізація OpenGL ES Game package combadlogicandroidgamesframeworkimpl

Цей клас доповнює клас Activity і реалізує Game і інтерфейс GLSurf aceVi ew Renderer Він містить перелік GLGameState, що відслідковує, в якому стані на даний момент знаходиться екземпляр класу GLGame Ми повернемося до цього трохи пізніше

Члени даного класу складаються з екземплярів класу GLSurf aceVi ew і GLGraphi cs Клас також містить екземпляри Audio, Input, FilelO і Screen, які знадобляться нам для написання гри, так само як і в класі Androi dGame Елемент state відстежує стан за допомогою одного з переліків GLGameState Елемент stateChanged являє собою обєкт, який ми будемо використовувати для синхронізації потоку користувача інтерфейсу і потоку візуалізації Далі використовуємо елемент, що відслідковує дельту часу, і WakeLock, який не дає екрану гаснути

У OnCreate виконується звичайна підпрограма установки Ми розгортаємо Activity на весь екран і створюємо екземпляр GLSurfaceView, встановлюючи його як вид з вмістом Ми також створюємо екземпляри всіх інших класів, які реалізують інтерфейси фреймворка, зокрема класи AndroidFilelO або Androidlnput Зверніть увагу на те, що ми заново використовуємо класи, які застосовували в класі Androi dGame за винятком Androi dGraphics Ще один важливий момент полягає в тому, що ми більше не дозволяємо класу Androidlnput масштабувати координати дотику до цільового дозволу як це було в Androi dGame Обидва значення масштабу рівні 1, так що ми будемо використовувати реальні координати дотику Навіщо це потрібно, ми розберемося трохи пізніше Останнє, що нам належить зробити, – створити екземпляр класу WakeLock

У методі onResume ми вказуємо класу GLSurfaceView запустити потік візуалізації, викликавши його метод onResume Ми також створюємо WakeLock

Далі викликаємо метод onSurfaceCreate Він, природно, також викликається в потоці візуалізації Тут ми бачимо, як використовуються переліки станів Якщо додаток запущено вперше, то стан буде мати вид GLGameState Initialized У цьому випадку ми викликаємо метод getStartScreen для того, щоб повернутися до стартового екрану гри Якщо гра знаходиться в неініціалізованих стані, але вже була запущена, ми знаємо, що ми просто її відновили У будь-якому випадку ми встановлюємо GLGameState Runni ng і викликаємо поточний метод Screen – resume Ми також відслідковуємо поточний час, щоб пізніше можна було вирахувати дельту часу

Нам також необхідна синхронізація, оскільки тими елементами, якими ми управляємо всередині блоку синхронізації, також можна управляти в методі onPause потоку для користувача інтерфейсу Необхідно уникнути цього, тому використовуємо обєкт як замок Ми могли б також застосувати екземпляр класу GLGame

Метод onSurfaceChanged – це, по суті, заглушка, тому не будемо його розбирати

У методі onDrawFrame робиться велика частина роботи Він викликається потоком візуалізації максимально часто У ньому перевіряємо стан нашої гри на даний момент і реагуємо відповідно з цим Оскільки стан може бути змінено в методі onPause в потоці користувача інтерфейсу, необхідно синхронізувати доступ до нього

Якщо гра запущена, підраховуємо дельту часу і вказуємо поточним Screen оновитися

Якщо гра поставлена ​​на паузу, вказуємо поточним Screen також встати на паузу Потім ми змінюємо стан на GLGameState Idle, позначаючи, що ми отримали запит на призупинення від потоку користувальницького інтерфейсу Оскільки ми очікуємо, що це відбудеться в методі onPause користувача інтерфейсу, ми повідомляємо потоку для користувача інтерфейсу, що він тепер може поставити додаток на паузу Дане повідомлення необхідно, оскільки нам потрібно переконатися, що потік візуалізації поставлений на паузу / закритий у разі, якщо наша Activity закрита або поставлена ​​на паузу в потоці користувача інтерфейсу

Якщо Acti vi ty завершується (і не поставлена ​​на паузу), переходимо до GLGameState Finished У цьому випадку вказуємо поточним Screen зупинитися і видалити себе, а потім відіслати ще одне повідомлення потоку користувача інтерфейсу, ожидающему, поки потік візуалізації завершить роботу

Метод onPause – звичайний метод повідомлення для роботи з Acti vi ty, що викликається потоком користувача інтерфейсу, коли Activity ставиться на паузу Залежно від того, закрито додаток або поставлено на паузу, встановлюємо відповідний стан і чекаємо, поки потік візуалізації обробить це новий стан Для цього використовується стандартний механізм Java очікування / повідомлення

Нарешті, вивільняємо WakeLock і вказуємо GLSurf aceVi ew і Acti vi ty встати на паузу, зупинити потік візуалізації і видалити поверхню OpenGL ES, через що ініціюється втрата контексту OpenGL ES, про яку ми говорили раніше

Метод getGLGraphi cs – це новий метод, доступний тільки через клас GLGame Він повертає екземпляр класу GLGraphics, який ми зберігаємо, щоб пізніше у нас був доступ до інтерфейсу GL10 при подальшій реалізації Screen

Залишок даного класу функціонально не змінився Якщо ми випадково спробуємо отримати доступ до стандартного екземпляру класу Graphics, отримаємо виняток, оскільки GLGame не підтримує таку операцію Замість цього будемо працювати з методом GLGraphics, який отримуємо через метод GLGame getGLGraphicsO

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

Підібємо підсумки за допомогою прикладу У лістингу 74 показано, як виглядає наш перший приклад при використанні GLGame і Screen

Лістинг 74 GLGameTestJava більше очищення екрана, тепер на 100 X більше GLGame

Це та ж сама програма, що і в нашому попередньому прикладі, за винятком того, що тепер ми успадковуємо від GLGame, а не від Activity і надаємо реалізацію Screen замість реалізації GLSurfaceViewRenderer

У наступних прикладах ми просто розглянемо відповідні частині реалізації Screen кожного прикладу Загальна структура наших прикладів залишиться тією ж Звичайно, нам необхідно додати приклад реалізації GLGame до нашої стартовою Acti vi ty і файлу маніфесту

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

Джерело: 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>

*

*