Недавно мы делали веб-игру про сбор пирамиды. Там мы использовали 3Д-движок и симуляцию физики. И в целом получилась залипательная веб-игра. Вот предыдущие этапы:
- Сделали трёхмерную браузерную игру, где нужно ставить блоки друг на друга и набрать как можно больше очков.
- Адаптировали игру под мобильные телефоны, чтобы тачскрин нормально обрабатывал все нажатия и жесты.
Ключевое слово — веб: игра работает только в браузере и только при наличии интернета. На этот раз мы превратим страницу с игрой в полноценное приложение для Android. При этом мы не будем пользоваться онлайн-конструкторами, а сделаем всё по-настоящему — в среде разработки и с кодом на Java.
Наш план таков:
- Подготовить файлы для упаковки в игру: скачать скрипты из интернета, перепривязать их к нашей игре на компьютере.
- Сделать новый проект в Android Studio.
- В проекте сделать WebView — это виртуальное окно браузера внутри приложения. В нём будет работать игра.
- Настроить WebView так, чтобы он поддерживал нашу игру и все нужные функции.
- Упаковать получившийся проект в виде приложения для Android.
Результат можно скачать сразу: вот приложение, которое получилось у нас таким нехитрым способом:
⭐️ Скачать apk
Подготовка
Главное, что нам понадобится из инструментов, — официальная среда разработки Android Studio. У нас есть про неё отдельная статья: что это такое, зачем нужно и как установить. Качаем с официального сайта и устанавливаем.
Так как наша игра должна работать без интернета, то это значит, что все ресурсы тоже должны быть доступны локально, прямо с телефона. В HTML-файле мы подключаем два внешних скрипта — их тоже нужно будет скачать:
<!-- подключаем Three.js -->
<script src='https://cdnjs.cloudflare.com/ajax/libs/three.js/r124/three.min.js'></script>
<!-- подключаем Cannon.js -->
<script src='https://cdnjs.cloudflare.com/ajax/libs/cannon.js/0.6.2/cannon.min.js'></script>
<!-- подключаем наш скрипт -->
<script src="./script.js"></script>
Для этого копируем адрес скрипта из кода страницы, вставляем в браузер и сохраняем то, что открылось, как js-файл.
Скрипты кладём в ту же папку, что и остальные файлы с игрой. Вот что должно по итогу у нас получиться с файлами:

После этого исправляем пути к скриптам в html-файле, чтобы они подтягивались из той же папки, а не из интернета:
<!-- подключаем Three.js -->
<script src='three.min.js'></script>
<!-- подключаем Cannon.js -->
<script src='cannon.min.js'></script>
<!-- подключаем наш скрипт -->
<script src="script.js"></script>
Сохраняем страницу и открываем её в браузере. Если мы всё сделали правильно, то «Пирамида» запустится как обычно — с красивой графикой и реакцией на нажатия.
Создаём новый проект в Android Studio
Запускаем Android Studio и выбираем Empty Activity:

После этого выбираем язык Java, а всё остальное оставляем без изменений:

Если это ваш первый запуск, программа начнёт качать разные служебные файлы — это нормально, нужно просто немного подождать.

Когда всё загрузится и запустится, перед нами появится окно с новой программой в Android Studio.
Добавляем файлы
Чтобы программа смогла загрузить в себя все файлы от игры, нам нужно создать в проекте специальную папку — assets — и скопировать в неё всё, что у нас есть. Для этого нужно пройти несколько неочевидных шагов:
- Создать папку внутри проекта в Android Studio.
- Найти папку на диске.
- Скопировать в папку все нужные файлы.
Создаём папку так: в левой верхней части щёлкаем правой кнопкой мыши по папке app и в появившемся меню выбираем New → Folder → Assets Folder:

Перед нами появится окно, которое спрашивает, к чему будет относиться папка. Ничего не меняем и просто нажимаем Finish:

Теперь щёлкаем правой кнопкой мыши на появившейся папке и выбираем Open in → Explorer:

Перед нами появится окно проводника с нашей папкой assets. Заходим в неё и копируем туда все игровые файлы, которые мы собрали в самом начале:

Смотрим в панель файлов Android Studio, чтобы убедиться, что всё получилось и система увидела наши файлы:

Пишем код
Нам было бы здорово видеть и дизайн, и код, поэтому выбираем слева в колонке файлов res → layouts → activity_main.xml и переключаем вид в режим Split в правом верхнем углу:

В этом же файле activity_main.xml есть блок, который начинается с команды <TextView — удаляем весь блок (название и 7 команд ниже) и вместо него пишем <WebView>. Среда разработки умная, поэтому, как только мы начнём писать код, она автоматически предложит нам создать новый блок. Нажимаем энтер, когда появится подсказка:

Вот команды, которые нужно добавить в этот файл:
<WebView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/webview"></WebView>
В итоге у нас должен получиться такой блок:

Нажимаем ⌘+S или Ctrl+S, чтобы всё сохранить .
Теперь переходим к другому файлу — MainActivity.java — и добавляем в него такой код:

setContentView(R.layout.activity_main);
WebView webView=findViewById(R.id.webview);
webView.getSettings().setJavaScriptEnabled(true);
webView.loadUrl("javascript:addLayer(x, z, width, depth, direction)");
webView.loadUrl("javascript:generateBox(x, y, z, width, depth, falls)");
webView.loadUrl("javascript:addOverhang(x, z, width, depth)");
webView.loadUrl("javascript:cutBox(topLayer, overlap, size, delta)");
webView.loadUrl("javascript:init()");
webView.loadUrl("javascript:startGame()");
webView.loadUrl("javascript:eventHandler()");
webView.loadUrl("javascript:splitBlockAndAddNextOneIfOverlaps()");
webView.loadUrl("javascript:missedTheSpot()");
webView.loadUrl("javascript:animation(time)");
webView.loadUrl("javascript:updatePhysics(timePassed)");
webView.loadUrl("javascript:window.addEventListener()");
webView.loadUrl("file:///android_asset/index.html");
Смысл тут в том, что мы сначала создаём новый элемент — просмотрщик веб-контента, потом разрешаем ему выполнять скрипты, а затем перечисляем все функции, которые у нас объявлены в основном скрипте вместе с параметрами вызова. Это нужно для того, чтобы Java знала, что это можно выполнять.
Нажимаем Shift+F10, чтобы запустить приложение в эмуляторе, — видим, что справа появился виртуальный телефон с началом нашей игры, но ничего не двигается. Это связано с тем, что встроенный эмулятор плохо работает с трёхмерной графикой и не может показать всё, что мы от него хотим. Главное, зачем нам это было нужно, — убедиться, что программа нашла все наши файлы, загрузила их и скрипт тоже заработал.

Компилируем приложение
Если нам нужен apk-файл, который можно установить на телефон, чтобы проверить игру по-настоящему, нам надо скомпилировать весь проект. Для этого выбираем в верхнем меню Build → Build Bundle(s) / APK(s) → Build APK(s):

Когда всё будет готово, внизу появится уведомление, что файл готов. Нажимаем на locate, чтобы перейти к файлу в проводнике:


Этот файл можно скачать себе на телефон с Android, установить его и поиграть в «Пирамиду» даже без интернета.