Пишемо движок гри під android - tutorial частина 1 (примітиви), програмування для android, java -

Хто б посперечався з тим, що самі корисні і потрібні програми для будь-якої мобільно платформи - це звичайно гри! І андроїд тут зовсім не виняток. Мобільний пристрій в наш час це центр розваг в кишені. Можна сказати, що сучасна гонка за продуктивністю - прямий результат цієї тенденції. Ну так і ми з вами давайте будемо в тренді! Розробка будь-якої гри процес досить трудомісткий і кропіткий. А написання ігрового движка - мабуть не менше складна справа.

Ось і я вирішив спробувати написати свій простенький ігровий движок для Android і поділитися з Вами цим досвідом.

Перш за все необхідно визначитися які можливості будуть у нашого движка? Адже сенс його створення полягає в тому, щоб полегшити нам в майбутньому розробку гри. Писати тривимірний движок ми з Вами не будемо. Занадто це складно для нас новачків. Тому спробуємо створити простенький 2D движок для спрайтові АНІМАЛ. Може по ходу справи будемо його розширювати. У його функціонал буде входити наступне:

  • Робота з самою системою, як то: створення поверхні для малювання, стеження за отрисовкой.
  • Робота з графічними примітивами - (точка, лінія, прямокутник, коло, еліпс).
  • Можливість переміщати примітиви.
  • Робота зі спрайтами (завантаження, рух, обертання, зміна розміру).

Все це досить просто організувати вбудованими функціями системи, однак якщо ви збираєтеся писати не одну, а кілька ігор, то робити це кожен раз досить складно. Звідси простий висновок, що всі ці функції варто перекинути на свою невелику бібліотеку класів. Саме так її створенням ми з Вами і займемося. Попутно спробуємо розібратися що звідки росте в цьому Андройде 🙂 Отже створюємо новий проект Android:

Пишемо движок гри під android - tutorial частина 1 (примітиви), програмування для android, java -
В параметрах цього проекту вказуємо назву проекту і пакет за замовчуванням:
Пишемо движок гри під android - tutorial частина 1 (примітиви), програмування для android, java -

Ну ось, проект створили, тепер переходимо до найпростішого і самому базовому класу нашого движка. Так його і назвемо mBasic. Всі інші класи для роботи з примітивами ми в майбутньому успадкуємо від цього класу. Ось його код:

І так, ми визначили абстрактний клас (це значить що в наших програмах ми не зможемо створювати екземпляри такого класу безпосередньо), в якому визначили як констант кілька різних типів примітивів. TYPE_POINT - точка, TYPE_LINE - відрізок, TYPE_POLYLINE - полілінія, TYPE_RECT - прямокутник, TYPE_CIRCLE - коло, TYPE_SIMPLESPRITE - простий спрайт. Насправді не думаю що нам знадобляться в роботі над грою всі ці типи примітивів, але про всяк випадок нехай будуть. Також в цьому класі ми визначили абстрактний метод update () яким будемо користуватися для поновлення параметрів наших примітивів і ще один метод boolean isSelected (float f, float g) - їм ми будемо користуватися для визначення чи належить точка з координатами f і g нашому примітиву. Ну і поставимо метод draw (Canvas c, Paint p). Він знадобиться нам для відтворення наших примітивів. Параметрами методу є об'єкти типу Canvas (канва на якій ми хочемо малювати) і Paint (кисть якої ми хочемо проводити отрисовку). Обидва методи абстрактні, значить реалізовувати ми їх будемо вже в відповідних класах.

Тепер давайте приступимо до реалізації нашої бібліотеки. Почнемо з класу mPoint - цей клас буде відповідати за роботу з точкою. Параметри x і y - це зрозуміло, положення точки на екрані (або за його межами). dx і dy - це швидкість точки в напрямку кожної з осей. axX і axY - це прискорення точки якщо воно більше ніж одиниця, то точка буде прискорюватися, якщо менше ніж одиниця то сповільнюватися. (Навіщо це треба розберемося потім). сам клас mPoint успадкуємо від класу mBasic. І поставимо кілька різних конструкторів, щоб було не нудно :-). В результаті отримуємо наступний клас:

А що ж робить метод update () який ми успадкували від батьківського класу? Він перераховує нові координати точки, з огляду на її швидкість і прискорення. Зауважте, в кожному конструкторі ми строго вказуємо тип створюваного об'єкта:

Так ми позбавимо себе в майбутньому від деякої кількості проблем. Ще ми реалізоавлі метод darw (Canvas c, Paint p) в його реалізіціі використаний стандартний метод класу Canvas: Canvas.drawPoint (float x, floaty). Крім іншого ми задали ще кілька методів аксессор. В основному думаю весь код досить прозорий і труднощів не викличе.

Тепер реалізуємо клас який буде відповідати за роботу з відрізками. Ось його код:

Ну тут взагалі нічого складного немає! Лінія в нашому розумінні задається кінцями відрізка. Власне тут є дві точки p1 і p2 - які і є кінцями нашого відрізка. Кілька різних конструкторів в яких задаються ці точки і метод для оновлення положення точок (оскільки клас mLine успадкований від mBasic то тут теж обов'язково треба реалізувати цей метод). Точно так само як і при відображенні точки ми скористалися стандартним методом канви darwLine ().

Вам сподобалось? Було корисно? Поділіться!

На майбутнє, напевно простіше оперувати з вектором прискорення, а не зберігати прискорення по 2-м осях.
Можна ввести його (прискорення) в клас Basic - і тоді можна буде вибудовувати дуже складні рухи об'єктів, наприклад вся ламана лінія рухається по власній траєкторії з одним прискоренням, і плюс ще кожна точка рухається зі своїм власним. Щось подібне можна побачити в World of Goo.
Якщо відразу реалізувати вектора, на верхньому рівні набагато простіше буде працювати.
Суто моє IMHO, звичайно.

Так, ідея хороша! Я теж спочатку так думав зробити, потім щось полінувався 🙂 Якщо Ви реалізуєте, буде здорово, а якщо ще й вихідні мені відправите взагалі здорово буде!

Відносно розрахунків швидкості і прискорення в методі update клас mPoint - мені здається, що швидкість потрібно не множити на прискорення, а додавати його. Уявіть подає предмет в реальному світі, прискорення становить 10 м / c ^ 2 (9.8). В даний момент тіло падає зі швидкістю 10 м / с, через секунду 20 м / с, потім 30 і т.д. Якщо ми будемо множити швидкість на прискорення то отримаємо через секунду 100, потім 1000 і т.д. Чи не занадто круто? До того ж якщо, виходячи з Ваших формул, взяти початкову швидкість об'єкта = 0, то скільки б ми не множили її на прискорення, швидкість залишиться рівною нулю. Загалом, шкільний курс фізики)

Та вже 🙂 Ну в принципі логічно 🙂 Я чет не особливо там морочився як писалося так і писав 🙂 Навчався 🙂

Так. Згоден. Логіка що першого що другого диференціала ідентична.

Насмілюся поправити: не прискорення до швидкості потрібно додавати, а прискорення помножене на момент часу, тому що у швидкості і прискорення різні одиниці виміру. Виходить швидкість в певний момент часу Vt = V + a * t. Ну а для кодинга Ви маєте рацію використовуємо «this.dx + this.axX», тому що вважаємо, що оновлення буде відбуватися кожну секунду.

Вітання.
На старості років вирішив зайнятися програмуванням. Досвід в С є, а в Java поки дуб-дубом.
Самий нубскій питання:
Створили проект, потім ти відразу пишеш код. А куди його вставляти щось? Я так зрозумів що треба в зайти в проект -> в папочку scr -> в свій namespace -> там створити новий файл з розширенням java і в нього вставляти код. І кожен файл обзивати соответсно. Я правий чи не правий? І чи треба потім десь використовувати щось типу #include як в С ++? Або ж Eclipse збере всі в одну велику купу? Непонятненько.

Тепер трохи менше нубскій питання. У першому лістингу чи можна використовувати enum для значного скорочення розміру коду при повному збереженні сенсу?

Ну і на довершення - у всіх статейки непогано було б на початку і в кінці статті зробити посилання на «зміст».

Зі своїм нубскім питанням частково розібрався - скачав з останнього тутора ваш проект і подивився як там зроблено. Так, як я і думав 🙂

Так само знайшов в шапці блогу пункт «уроки по андройд», так що питання з пошуком змісту так само вирішене)

Так. Сам косякнул. Де написав про метод з похибкою - там естесссссно треба брати модуль від різниці і порівнювати його з дельтою.

Всі три лістингу треба впихати в окремі файли? і як ці файли назвати? як і імена класів? де ці файли будуть знаходиться? взагалі що то я не розумію ...

А ви не могли б написати ще один клас, який би просто виводив на екран примітиви реалізовані в двигуні? Я думаю у вас це часу сильно багато не займе, зате буде непоганий приклад роботи класів.

Схожі статті