Первая игра на Android. Часть 1. Подготовка проекта

Не так давно мне в руки попалась отличная книга Beginning Android C++ Game Development. В ней доходчиво объясняются преимущества использования NDK и, как следует из названия книги, как писать игрушки для Android. Опираясь на информацию полученную из этой книги я напишу этот пост. Ранее я упоминал как создать простейший проект с использованием NDK. Но сейчас мы предпримем немного другой подход. Для нашего проекта нам не потребуется использовать Java вообще. И все это благодаря чудесной библиотеки входящей в состав NDK - androidnativeapp_glue

И так. Если у вас еще не установлена SDK или NDK, то вы можете найти их по ссылкам: SDK и NDK. После установки, не забудьте указать адрес NDK в Eclipse. Эту настройку можно найти по адресу: Window>Preferences>Android>NDK. Если все в порядке, то мы с чистой душей можем начать создавать проект для нашей первой игры.

  1. Создаем проект Android Applocation Project (File>New>Project)
  2. Указываем имя проекта, пакета и пр.
  3. В качестве минимальной версии API указываем версию не ниже 9-й.
  4. Снимаем галочки с Create custom launcher icon и Create activity.
  5. Finish!

     После создания проекта, нам надо добавить NDK в проект. Для этого жмем правой кнопкой по проекту и выбираем пункт Android Tools>Add Native Support... . Указываем имя библиотеки которую будем запускать. Я ничего не менял. Теперь, раскрыв проект в Project Explorer мы можем увидеть свежесозданную папку jni. Настал через настроить Android Manifest.

  6. Открываем AndroidManifest.xml и переходим на вкладку Application.

  7. Меняем значение в поле Theme на Theme.NoTitleBar.Fullscreen (это можно сделать через Browse), чтобы приложение развернулось на весь экран без каких либо заголовков.
  8. Значение Has Code выставляем в true
  9. Опускаемся к Application Nodes и жмем Add. Выбираем Activity и OK.
  10. В настройках Activity нажмем на Browse и снимем галочку с Display classes from sources of project ''. Выбираем NativeActivity и жмем OK.
  11. Тут же в поле Label вписываем @string/app_name. А в поле Screen Orientationlandscape.
  12. Возвращаясь к Application Nodes нажимаем на только что созданный Activity и снова на Add.
  13. На этот раз мы создаем Meta Data. В поле Name вводим android.app.libname, а в LabelLOCALMODULE.
  14. Тем же путем добавляем к Activity  Intent Filter. А в Intent Filter добавляем Action и Category.
  15. Содержимое поля Name для Actionandroid.intent.action.MAIN.
  16. А для Category -  android.intent.category.LAUNCHER.

На этом все. В результате получится что то подобное:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"  
    package="ftp27.game.firstgame"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="9"
        android:targetSdkVersion="18" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@android:style/Theme.NoTitleBar.Fullscreen" android:hasCode="true">
        <activity android:label="@string/app_name" android:name="android.app.NativeActivity">
            <meta-data />
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>

</manifest>  

 Теперь настал черед настроить мейкфайлик NDK. Вы можете его найти в папке проекта в директории jni под названием Android.mk. Тут нужно сделать совсем немного:

Добавим библиотеки, которые будем использовать

LOCAL_LDLIBS := -llog -landroid -lEGL -lGLESv2  

Добавим Glue библиотеку о которой говорилось выше. 

LOCAL_STATIC_LIBRARIES := android_native_app_glue  

Ну и напоследок 

$(call import-module, android/native_app_glue)

В результате получится такой Android.mk:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := FirstGame  
LOCAL_SRC_FILES := FirstGame.cpp  
LOCAL_LDLIBS := -llog -landroid -lEGL -lGLESv2  
LOCAL_STATIC_LIBRARIES := android_native_app_glue

include $(BUILD_SHARED_LIBRARY)

$(call import-module, android/native_app_glue)

 Теперь необходимо указать в NDK минимальную версию API, которую мы будем использовать. Она указывается в файлике Application.mk в попке jni. По умолчанию он не создается. Посему создадим его в папке jni и впишем одну единственную строчку. 

APP_PLATFORM := android-9  

Теперь можно проверить. Все ли вы сделали правильно. Для этого нажмем правой кнопкой на проекте и Build Project. На выходе консоли Output будет что то вроде:

**** Build of configuration Default for project FirstGame ****

/home/ftp27/adt-bundle-linux/ndk/ndk-build all 
[armeabi] Compile++ thumb: FirstGame <= FirstGame.cpp
[armeabi] Compile thumb  : android_native_app_glue <= android_native_app_glue.c
[armeabi] StaticLibrary  : libandroid_native_app_glue.a
[armeabi] StaticLibrary  : libstdc++.a
[armeabi] SharedLibrary  : libFirstGame.so
[armeabi] Install        : libFirstGame.so => libs/armeabi/libFirstGame.so

**** Build Finished ****

Во время работы нам может пригодиться отладка. Она включается таким образом:

  1. Правой кнопкой на проекте Build Configurations>Manage
  2. Создаем новую конфигурацию с именем, например, Debug и устанавливаем копирование настроек с Default. OK!
  3. Правой кнопкой на проекте Properties>C/C++ Build. Переключаем настройку на Debug и снимаем галочку с Use default build command
  4. Для того чтобы отладка работала необходимо чтобы в поле было значение: ndk-build NDK_DEBUG=1

Все. Сохраняем настройки и теперь мы можем выбрать конфигурацию сборки в Build Configurations>Set Active. В результате повторной сборки можете увидеть введенную вами строчку

/home/ftp27/adt-bundle-linux/ndk/ndk-build NDK_DEBUG=1 all

 На этом мы закончили с настройкой нашего проекта. Теперь мы можем перейти к самому интересному. Написанию самой игры.

Весь результат на GitHub: Тык!