Спрайт-АНИМАЦИЯ – РОЗРОБКА ІГОР ДЛЯ ОС ANDROID

Якщо ви коли-небудь грали в 20-відеогру, то помітили, що ми до цих пір не займалися одним дуже важливим компонентом – спрайт-анімацією Анімація складається з так званих ключових кадрів, які створюють ілюзію руху На рис 825 ви можете побачити прекрасний анімований спрайт, створений Арі Фельдман (узятий з його безгонорарній бібліотеки SpriteLib)

Рис 825 Той, хто йде печерна людина, створений Арі Фельдман (в оригіналі – без сітки)

Зображення має розміри 256 х 64 пікселя, кожен кадр – 64 х 64 пікселя Для створення анімації ми просто малюємо спрайт, використовуючи перший ключовий кадр, деякий період часу – скажімо, 0,25 секунди, потім перемикається на наступний ключовий кадр і т д Коли ми досягаємо останнього кадру, є два варіанти: ми можемо залишитися на останньому кадрі або знову почати спочатку (і реалізувати так звану циклічну анімацію)

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

Клас Animation

Виходячи з цього, ми можемо визначити вимоги до класу Ani mat i on, який буде зберігати дані про одну анімації, такий як анімація ходьби на рис 825

Animation буде містити кілька TextureRegion, які будуть зберігати інформацію про позицію кожного кадру в атласі текстур Порядок TestureRegion повинен бути таким же, як при відтворенні кадрів

Animation також буде зберігати тривалість кадру, тобто час, який повинен пройти до перемикання на наступний кадр

Animation повинен містити метод, куди ми будемо передавати час, який ми проводимо в представленому Animation стані (наприклад, крок вліво), і який буде повертати потрібний TextureRegi on Метод повинен враховувати, чи хочемо ми зробити анімацію циклічною чи залишитися на останньому кадрі при досягненні кінця

Остання вимога особливо важливо, тому що воно дозволяє нам зберігати тільки один екземпляр Animation для використання різними обєктами нашого світу Обєкт просто стежить за своїм поточним станом (Наприклад, стріляє чи обєкт, ходить або стрибає, а також як довго він знаходиться в цьому стані) Коли ми Рендер цей обєкт, ми використовуємо його стан для вибору анімації, яку ми хочемо відтворити, і тривалість стану, щоб вибрати потрібний TextureRegion з Animation У лістингу 819 показаний код нашого нового класу Ani mation

Лістинг 819 Animationlava, простий клас Animation

Спочатку визначаємо дві константи, які будемо використовувати у методі getKeyFrame Перша вказує, що анімація має бути циклічної, друга – що анімація повинна зупинитися на останньому кадрі

Далі задаємо два члена: масив, що містить TextureRegi on, і змінну f1oat, яка зберігає тривалість кадру

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

Найцікавіше тут полягає в методі getKeyFrameC Ми передаємо йому час, який обєкт провів у стані, представленому анімацією, а також режим Ani mati on AN IMATI0N L00P I NG або Animtion N0N L00P I NG Спочатку підраховуємо на основі stateTime, скільки кадрів уже було відображено до даного моменту Якщо анімація нециклічне, просто закріплюємо frameNumber за останнім елементом масиву TextureRegi on В іншому випадку беремо модуль, який автоматично створює ефект циклічності, який нам потрібен (наприклад, 4% 3 = 1) Залишилося тільки повернути відповідний TextureRegi on

&nbsp

Приклад

Створимо приклад під назвою Ani mati onTest з відповідним екраном AnimationScreen Як і зазвичай, обговоримо тільки екран

Ми хочемо отрендеріть декількох печерних людей, що йдуть вліво Світ буде таких же розмірів, як і конус відображення, тобто 4,8 х 3,2 м (цей розмір довільний, насправді ми можемо використовувати будь розмір) Печерна людина є Dynami cGameObject розміром 1 х 1 м Виведемо з DynamicGameObject новий клас Caveman, в якому буде зберігатися додатковий член класу, що стежить за тим, як довго печерна людина вже знаходиться в русі Кожен печерна людина буде рухатися зі швидкістю 0,5 м / с вправо або вліво Ми також додамо в клас Caveman метод update для оновлення позиції печерного людини відповідно з дельтою часу і його швидкістю Якщо печерна людина досягає правого або лівого краю нашого світу, встановлюємо його з іншого боку світу Ми використовуємо зображення з рис 825 і створимо TextureRegion та примірник Animati on відповідно Для рендеринга застосовуємо екземпляр класу Camera2D і SpriteBatcher У лістингу 820 показаний код класу Caveman

Лістинг 820 Фрагмент з AnimationTest, внутрішній клас Caveman

Дві константи W0RLD WIDTH і W0RLD HEIGHT є частинами зовнішнього класу AnimationTest і використовуються внутрішнім класом Наш світ має розміри 4,8 х 3,2 м

Далі слід внутрішній клас Caveman, який доповнює DynamicGameObject, оскільки ми будемо переміщати печерної людини з якоюсь швидкістю Ми визначаємо додатковий член класу для відстеження того, як довго печерна людина рухається на даний момент У конструкторі поміщаємо печерної людини в довільну позицію і дозволяємо йти направо або наліво Ми також Привласнюємо члену класу wal ki ngTime номер від 1 до 10 таким чином наші печерні люди не будуть рухатися синхронно

Метод update переміщує печерної людини відповідно до його швидкістю і дельтою часу Якщо людина покидає світ, ми відновлюємо його з правого або лівого боку Ми також додаємо дельту часу до wa1kingTime, щоб стежити, як довго він уже рухається Лістинг 821 показує клас AnimationScreen

Лістинг 821 Фрагмент з AnimationJava: клас AnimationScreen

У класі екрану всі члени будуть нам вже звичні Так, у нас є екземпляр класу GLGraphics, масив Caveman, класи SpriteBatcher, Camera2D, клас Texture, що містить ключові кадри ходьби, та примірник класу Animation

У конструкторі створюємо екземпляр класу Caveman, а також класів SpriteBatcher і Camera2D

У методі resume завантажуємо текстурний атлас, що містить ключові кадри анімації, з ресурсного файлу під назвою wal kanim png, який виглядає так само, як рис 825 Після цього створюємо екземпляр класу Animation, встановивши тривалість кадру в 0,2 секунди і передаємо в нього TextureRegion для кожного ключового кадру в атласі текстур

Метод update просто перебирає всі екземпляри класу Caveman і викликає їх метод Caveman update з поточною дельтою часу Це змушує печерних людей пересуватися і оновлює їх час ходьби

І нарешті, у нас є метод present Ми починаємо з чищення екрану і встановлення області перегляду і проекційної матриці за допомогою нашої камери Потім включаємо змішування та обробку, текстур і встановлюємо функцію змішування Починаємо відображення, повідомляючи сортувальника спрайтів, що ми хочемо завести новий пакет, використовуючи анімаційний атлас текстур Потім проходимо по всіх печерним человечкам і відображаємо їх Для кожного печерної людини знаходимо спочатку потрібний ключовий кадр в екземплярі класу Ani mati on відповідно з часом ходьби людини Вказуємо, що анімація має бути циклічної Потім малюємо печерної людини з правильним текстурованим фрагментом на його місці

Але що робити з параметром ширини Ви памятаєте, що наша анімаційна текстура містить ключові кадри для ходьби вліво Ми можемо відобразити текстуру По горизонталі (на випадок, якщо печерна людина захоче піти направо), просто вказавши негативну ширину Якщо ви не вірите мені, можете повернутися до коду SpriteBatcher і перевірити, чи спрацює цей спосіб Ми, по суті, відображаємо прямокутник спрайта, вказуючи негативну ширину Ми можемо зробити те ж саме по вертикалі, задавши негативну висоту

Наші гуляють печерні люди зображені на рис 826

От і все, що потрібно знати, щоб створити хорошу 2D-гру за допомогою OpenGL Знову зверніть увагу на те, що ми поділяємо логічну складову гри і графічне представлення Печерній людині зовсім необовязково знати, що його відображають Тому він не містить ніяких членів, що відносяться до рендерингу, як, наприклад, екземпляр класу Animation або Texture Все, що нам потрібно робити, – стежити за станом печерної людини і тим, як довго він вже знаходиться в цьому стані Додавши до цього його позицію і розмір, ми можемо легко здійснити відображення за допомогою наших маленьких допоміжних класів

Рис 826 Гуляють печерні люди

Підводячи підсумок

Тепер ви досить підковані, щоб створити практично будь-яку 2D-гру, яку хочете Ми обговорили вектори і роботу з ними, в результаті отримавши гарний клас Vector2, який можемо використовувати багато разів Ми також згадали основи фізики для створення таких обєктів, як балістичні гарматні ядра Визначення зіткнень – також найважливіша частина більшості ігор, і ви повинні знати, як правильно і ефективно визначати зіткнення між обєктами за допомогою SpatialHashGrid Ми розглянули, як відокремлювати логічну складову гри і обєкти від процесу відображення, створивши класи GameObject і Dynami cGameObject, які відстежують стан і форму обєктів Ми дізналися, як просто за допомогою OpenGL ES і одного тільки методу glOrthof можна реалізувати ідею 20-камери Ми обговорили атласи текстур, зясували, чому і навіщо ми їх застосовуємо Розвинувши ідею, ми поговорили про фрагменти текстури, спрайт і те, як можна ефективно відображати їх за допомогою Spri teBatcher І нарешті, вивчили спрайт-анімацію, яка виявилася дуже проста

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

*

*