...

суббота, 22 августа 2015 г.

Разработка HTML5 игры под Android с нуля и до релиза

Вместо вступления


Потратив несколько суток подряд (без перерыва на сон) на изучение поддержки HTML5 всеми любимыми Android-гаджетами, решил, что данной теме стоит уделить внимание. В статье постараюсь раскрыть по шагам все этапы (конечно же базовые/ключевые/основные) создания HTML5 Игрового приложения для Android от идеи до релиза самого APK файла. Возможно, ничего нового я и не открою маститым разработчикам, но для новичков постараюсь описать все как можно проще, со скриншотами и пояснениями.

image

Желающих узнать подробнее приглашаю под кат.

Идея


Вообще много можно говорить о потенциале Android, о развитии HTML5 и об их взаимодействии. Я этого делать не буду. Так что, сразу к делу.

Идея создания игры под Android наверняка заседает в разумах десятков сотен разработчиков, и тех, кто себя таковыми считает. Я не исключение.

Почему HTML5? — JavaScript единственный язык, который я учил Нативность. Пишешь игру на JS, а затем для абсолютно любой ОС создаешь обертку в удобном виде и на любом Языке.

Весь процесс будет разбит на несколько шагов а итоговое приложение будет состоять из двух частей:
— Обертка (в данном случае для Android)
— Игра

Шаг 1. Написание самой игры


Еще одним плюсом написания игры на HTML5 является тот факт, что для тестирования не требуется куча запущенных программ, IDE, эмуляторов и так далее. Нужен лишь браузер (в моем случае это Chromium) и текстовый редактор (BlueFish)

Игра будет несложной: есть синий прямоугольник и есть зеленый прямоугольник. Задача игрока — перетащить синий прямоугольник на зеленый в обход красного, который перемещается по игровому полю в произвольном направлении.

Для разработки игры буду использовать J2ds (игровой движок).

Код готовой игры:

index.html
<!DOCTYPE html>
<html> 
 <head>
  <script type="text/javascript" src="j2ds/engineMath.js"></script>
  <script type="text/javascript" src="j2ds/engineKey.js"></script>   
  <script type="text/javascript" src="j2ds/engineDOM.js"></script>
  <script type="text/javascript" src="j2ds/engine2D.js"></script>
  <script type="text/javascript" src="j2ds/engineNet.js"></script>
  <script type="text/javascript" src="j2ds/engineParticles.js"></script>
  <script type="text/javascript" src="j2ds/enginePE.js"></script>  
  <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
  <meta name="viewport" content="width=device-width,user-scalable=no" />  
  <title>Demo Game on J2ds v.0</title>
 </head>

<body id="gameBody">

 <canvas id="iCanvas" width="500" height="280"></canvas>
<br>
<div id="hint"></div>

<script type="text/javascript">
// Инициализируем устройство ввода
initInput('gameBody');

// Создаем сцену
scene= createScene('iCanvas', '#aeeaae');

// Стартуем в полноэкранном режиме
scene.fullScreen(true);

post= createPost(scene);

score= 5;

// Создаем прямоугольники

blue= createRect(vec2di(100, 100), vec2di(30, 30), 'blue');

green= createRect(vec2di(300, 200), vec2di(30, 30), 'green');
green.dX= -1; green.dY= 1;

red= createRect(vec2di(16, 200), vec2di(30, 30), 'red');
red.dX= 1; red.dY= -1;

restart= createRect(vec2di(430, 10), vec2di(60, 60), '#ad21ad');


GameOver= function() {
        // Обрабатываем позицию касания / мыши
 input.upd(scene);
 // Выводим текст
 scene.drawText(vec2di(5,5), 'Score: '+score);
 // Выводим текст
 scene.drawTextOpt(vec2df(140, 100), 'Проиграл!',
    'bold 40px Courier New', '#326598');
 if (input.lClick && input.onNode(restart)) setActivEngine(Game);   
 restart.draw(scene);
}

Success= function() {
        // Обрабатываем позицию касания / мыши
 input.upd(scene);
 // Выводим текст
 scene.drawText(vec2di(5,5), 'Score: '+score);
 // Выводим текст
 scene.drawTextOpt(vec2df(140, 100), 'Победа!',
    'bold 40px Courier New', '#326598');
 if (input.lClick && input.onNode(restart)) setActivEngine(Game);   
 restart.draw(scene);
}


// Описываем игровое состояние Game
Game= function() {
 // Обрабатываем позицию касания / мыши
 input.upd(scene);

 // Выводим текст
 scene.drawText(vec2di(5,5), 'Score: '+score);

 blue.color= input.lClick?'yellow' : 'blue';

 if (input.lClick)  
 {
  red.move(vec2di(red.dX, red.dY));
  green.move(vec2di(green.dX, green.dY));  
  
  
  blue.move(
   vec2df(
    blue.getPosition().x > input.pos.x ? -1*score/2 : 1*score/2,
    blue.getPosition().y > input.pos.y ? -1*score/2 : 1*score/2    
   ) )
  ;
  
  
  if (green.collisionScene(scene).x != 0) green.dX= -green.dX;
  if (green.collisionScene(scene).y != 0) green.dY= -green.dY;
  if (red.collisionScene(scene).x != 0) red.dX= -red.dX;
  if (red.collisionScene(scene).y != 0) red.dY= -red.dY;
 
 }

 if (blue.collision(red)) {
  input.cancel(); score-= 1;
  setActivEngine(GameOver);
  red.setPosition(vec2df(200, 100));
  blue.setPosition(vec2df(50, 50));
 }

 if (blue.collision(green)) {
  input.cancel(); score+= 1;
  setActivEngine(Success);
  red.setPosition(vec2df(200, 100));
  blue.setPosition(vec2df(50, 50));
  blue.setPosition(vec2di(Random(0, 450), Random(0, 250)));
 }


 // Вращаем прямоугольники
 blue.turn(1); 
 green.turn(720/blue.getDistance(green)); 
 red.turn(Random(1, 5));
        
        
        // Отрисовываем объекты
        green.draw(scene); blue.draw(scene); red.draw(scene);

 //post.motionBlur(4);
 
}

// Стартуем игру с игровым состоянием Game и FPS 25
startGame(Game, 30);
</script>

</body>
</html>




На качество кода игры внимания можно не обращать, ибо не это цель статьи. Хотя конечно, можно оптимизировать сколько угодно, этот процесс вообще наверное бесконечен.

Шаг 2. Android Studio. Создание обертки для игры


Я не собираюсь ни с кем мериться крутостью той или иной IDE для разработки под Android, а покажу на примере Android Studio. Для работы нам потребуется:
— Java машина (под мою Linux подходит OpenJDK);
— Дистрибутив Android Studio.

Скачиваем, устанавливаем.

Как только все установите (Этих двух программ достаточно), запускайте Android Studio.

image

Откроется стартовое окно (если первый запуск), если не первый — то откроется сама IDE, но сути не меняет, пройдем в SDK Manager:

image

Тут нужно галочками отметить необходимые вам версии Android, с которыми вы будете работать, в моем случае это Android 4.4.2, вы можете выбрать хоть все сразу.

Главное — выберете обязательно «Tools» и «Extras» и нажимайте «install packages».

Как только у вас все скачалось, запустится IDE с унылым серым фоном и несколькими кнопками, жмем первую и создаем новый проект. Если IDE запустилась сразу в рабочем состоянии, то: «File->New->New Project»

image
Заполняем необходимые поля, и жмем Next

image
Выбираем нужную версию андроида и Next

image
Тут выбираем Blank Activity (пустой шаблон с Hello, World!)

В следующем окне заполняем данные для создания классов, я менять не буду для наглядности:

image

Торжественно жмем Finich и ждем, пока IDE все сконфигурирует и подготовит для работы.

image

Откроется окно с дизайнером форм. Оно не такое, как в Lazarus, Delphi, но что-то схожее все равно имеется:

image

Не спешите ничего менять или что-то щелкать, настройка еще не окончена. Открываем «Tolls->Android->AVD Manager» для настройки эмулятора.

image

Тут, если ничего нет, жмем «Cereate Virtual Device», если есть, можете не создавать новый, у меня уже был, т.к. я «натыкал» его, пока разбирался. Если же вам нужно создать новый эмулятор, то там все просто:
1. Выбираем размер экрана и модель телефона
2. Выбираем версию андроида (у меня 4.4.2)
3. Настраиваем устройство.

На третьем шаге подробнее:

image

Т.К. игра у нас вытянута по горизонтали, выбрать нужно ландшафтный режим.

Когда все настройки введены, жмем на зеленый треугольник и запускаем эмулятор. После запуска ждем, когда устройство полностью загрузится и запустится ОС:

image

Это окно не закрывайте, в нем будет происходить эмуляция. Теперь можно вернуться в редактор, и изменить ориентацию в дизайнере форм:

image

Можно запускать! Вот теперь точно можно.

Если появится запрос на выбор эмулятора — то можно поставить галочку внизу:

image

Мои поздравления! Все работает, проверено!

image

Сворачиваем наш эмулятор (Но не закрываем!) и переходим в редактор, Там все немного сложнее (чуть-чуть).
Переключиться нужно в режим «Text». У вас в activity_main описаны все элементы, которые есть на форме. Включая саму форму. Да и не форма это вовсе.

Т.к. мы делаем игру в HTML5, а тут у нас только обертка для игры, удаляем весь текст и вставляем следующее:

<RelativeLayout xmlns:android="http://ift.tt/nIICcg"
    xmlns:tools="http://ift.tt/LrGmb4" android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    tools:context=".MainActivity">

    <WebView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:id="@+id/webView"
        android:clickable="true"
        android:scrollbars="none" />
</RelativeLayout>

Теперь, если опять переключиться на дизайн, то выглядеть будет иначе:
image

Как видно, теперь вместо «Hello, World» во всю красуется растянутый на весь экран — WebView. Этот объект и является нашим «окном» в игровой мир.

Можете запустить даже, посмотреть, будет белый экран. Идем дальше.

А дальше нам нужно перейти в наш проект, для этого слева открываем поле «Project» и выбираем вкладку «Android», если не выбрана:

image
В этой вкладке представлена структура проекта и все его внутренние файлы и ресурсы.

Заголовок спойлера

Нам требуется найти файл «манифест» и дописать в определение «application» следующую строку:
android:hardwareAccelerated="true"

Пришло время поработать над функционалом нашего «браузера», ведь это именно он! Открываем класс «MainActivity.java» и удаляем все лишнее, оставив только основное:

Заголовок спойлера
package com.soft.skaner.demogamehtml5;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }


}


Если не забыли, мы в файле activity_main добавили WebView, обратите внимание на выделенную жирным строчку:
<WebView
android:layout_width=«fill_parent»
android:layout_height=«fill_parent»
android:id="@+id/webView"
android:clickable=«true»
android:scrollbars=«none» />

Нам нужно объявить объект класса WebView.

Для этого к списку импортов дописываем:

import android.webkit.WebView;


А затем объявляем наш объект myWeb внутри класса MainActivity:
protected WebView myWeb;


Теперь, после строчки setContentView(R.layout.activity_main); вставляем следующий код:
        /* Находим наш браузер */
        myWeb= (WebView) findViewById(R.id.webView);

        /* Настраиваем наш браузер */
        myWeb.getSettings().setUseWideViewPort(true);
        myWeb.setInitialScale(1);
        myWeb.getSettings().setJavaScriptEnabled(true);
        
        /* Загружаем страничку */
        myWeb.loadUrl("file:///android_asset/index.html");

Вот что получилось у меня в редакторе:

image

А вот, что в эмуляторе:

image

Если у вас так же — мы на верном пути!

Осталось дело за небольшим:
Там, где мы подгружаем страницу нашему браузеру, путь к файлу выглядит так: «http://file/android_asset/index.html»
Следует учесть, что любые файлы мы можем хранить внутри нашей игры, имея к ним доступ.

В нашем случае ключевая папка: «android_asset», давайте ее создадим (да, по умолчанию ее нет в проекте):
«File -> New -> Folder -> Assets folder», откроется окно где достаточно просто согласиться с IDE.
Заметили? В проекте появилась новая папка:

image

Жмем по ней правой кнопкой мыши -> «Show in Files», откроется системный проводник (в моем случае Nautilus), обратите внимание на путь к папке. Имейте так же ввиду, что папка называется «assets», но доступ к ней идет через «android_asset».

image

Дальше все совсем просто — копируем нашу игру в папку assets:

image

Файл index.html — это тот самый index из начала этой статьи. Ну что, пробуем запустить!

image

Небольшой совет: тестировать лучше всего на реальном устройстве посредством USB, так результаты теста будут нагляднее, да и управлять мышью не самый удобный вариант, не говоря уже о множественном нажатии.

Шаг 3. Android Studio. Сборка приложения и его подписывание


Когда игра вами полностью отлажена (в браузере или на эмуляторе), обертка полностью готова и все этапы разработки позади, можно собирать приложение. Android Studio позволяет собирать приложения и подписывать их вашими ключами.

Для создания ключей в этой IDE есть специальная утилита «KeyTool».

Переходим к созданию исполняемого файла приложения («Build -> Generate Signed APK»):

image

Если ранее ключей и алиасов вы не создавали, нажимайте «Create New». Заполнить поля можете на свое усмотрение, достоверность данных целиком лежит на вас.

image

Первое поле — это путь к папке, в которую будет сохранен ключ. Форма после нажатия Ok заполнится автоматически:

image

Для последующих приложений создавать новые ключи не обязательно, вы можете подписывать вашим ключем и другие приложения, именно для этого и есть кнопка «Choose Existing».

На следующем шаге IDE попросит у вас еще раз ввести пароль, а затем указать папку для сохранения APK файла.

image

Теперь можете расслабиться и попить, к примеру, кофе.Система начала компиляцию, результат в статусбаре:

image

После того, как компиляция завершится, система вам об этом сообщит.

image
image

Теперь достаточно переместить файл на телефон / планшет и установить, как обычное приложение.

Результат:

image
image

Вы можете его так же скачать и проверить на своем устройстве: J2ds Demo HTML5

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

Комментариев нет:

Отправить комментарий