вторник, 8 октября 2013 г.

четверг, 26 сентября 2013 г.

Android Studio & NDK

Today I started investigating of features of native library. I used this tutorial: http://www.ntu.edu.sg/home/ehchua/programming/android/Android_NDK.html. As usually I used Android Studio (Ubuntu) and encountered the problem.

Caused by: java.lang.UnsatisfiedLinkError: Cannot load library

воскресенье, 22 сентября 2013 г.

Error android studio after update to 0.2.9

After updating studio via Check for updates and downloading patch I was getting this error during creating new project:

The following dependencies were not resolvable. See your build.gradle file for details.- com.android.support:appcompat-v7:18.0.0

    The old projects weren't opened as well. After some googling I didn't found the complete answer how to solve it on Ubuntu or found ways didn't help.
Then I removed whole android-studio. Download the latest package (it was 0.2.x) and extract it as usual. But the problem was't solved anyway.

    As this problem should be solved quickly I decided to remove all settings of android studio. In my case it was placed under ~/.AndroidStudioPreview.

cd ~/
rm -rf .AndroidStudioPreview/
rm -rf ~/Desktop/android-studio/  - removed android-studio again as it was placed on Desktop


Then extract android-studio again. This time studio has downloaded required files from gradle by herself. After that I was able to create new projects. Hope update to 0.2.9 goes smoothly.

среда, 28 августа 2013 г.

Фреймворк “Andengine” и простой пример



Фреймворк AndEngine это реализация OpenGL под андроид, ориентированная для создания игр. Этот фреймворк расчитан на 2D реализацию. В этой статье, я хочу попробовать рассказать о создании физических тел.
Библиотека AndEnginePhysicsBox2DExtension-GLES2 используется для имитирования физических тел, гравитации, трения, упругости, статические, динамические, кинетические тела и взаимодействия между ними всеми. Мне хотелось сделать игрушку наподобие этой или этой, поэтому мне нужны были только тела, методы управлениями ими и контроль над свойствами объекта. Остальные фитчи в этой статье не рассматриваются. Также, хочется заметить, что это не туториал, а скорее обзор.

Установка

Лично я воспользовалась вот этой ссылкой: Ссылка
Сначала я подняла общий проект, посмотрела разные анимации, возможности, как он вообще работает. Это было легко. Однако, когда начала подключать его в мой проект, то начали возникать проблемы. Для меня конечным вариантом стало подключение не только файлов библиотеки  AndEnginePhysicsBox2DExtension-GLES2, но и jar файла из первого тестового проекта. Выглядит ужасно, но работает. Может в будущем исправлю это.

Этапы создания игры

  1. Создание игровой активити
  2. Создание размеров игрового поля и параметров игры
  3. Загрузка ресурсов
  4. Создание игровой сцены
  5. Добавление обработчиков событий

Создание игрового класса

Весь процесс игры строится  в классе в наследованием SimpleBaseGameActivity. Здесь будут переработаны методы:
onCreateEngineOptions()
onCreateResources()
onCreateScene()

Создание размеров игрового поля и параметров игры

Метод onCreateEngineOptions() отвечает за создание размеров игры и задания различных параметров, таких как проигрывание звуков. Каждая игра начинается с рабочей области, на которой будет производится действие, где задаются параметры экрана. Так называемый объект Camera будет содержать размеры экрана:

final Camera camera = new Camera(0, 0, WIDTH, HEIGHT);

0, 0 - это верхняя левая точка экрана
WIDTH, HEIGHT - это нижняя правая

      Что дает для игры статическая ширина и высота: AndEngine сам будет изменять размер экрана в зависимости от разрешения девайса и его ширины и высоты. Это по крайней мере избавит вас от проблемы разных экранов. Игрушка будет везде выглядеть одинаково.

      Далее создаются обычно свойства игры: звук, ориентация, разрешение. Обычно делается так:
final EngineOptions engineOptions = new EngineOptions(true, ScreenOrientation.PORTRAIT_FIXED, new RatioResolutionPolicy(WIDTH, HEIGHT), camera);

true - означает делать ли приложение полноэкранным
ScreenOrientation.PORTRAIT_FIXED - назначает ориентацию игры. Помимо стандартных LANDSCAPE_FIXED и PORTRAIT_FIXED есть еще LANDSCAPE_SENSOR и PORTRAIT_SENSOR. Два последние позволяют менять ориентацию игры.
new RatioResolutionPolicy(WIDTH, HEIGHT) - Параметры для разрешения в настройки.
camera - ну и сам объект камеры
Чтобы проигрывать звуки можно сделать так:
engineOptions.getAudioOptions().setNeedsSound(true);

Есть также getTouchOptions() и getRenderOptions().

Загрузка ресурсов

Метод onCreateResources() отвечает за загрузку всех ресурсов для игры. Конечно, можно загружать их по ходу игры, но лучше все-таки делать это здесь заранее. Здесь можно загружать текстуры, свойства объектов, шрифты, музыку и разные области для объектов.
Основное создание объекта похоже на матрешку. Сначала создаем атлас, потом кусок на который крепим картинку, потом добавляем этот кусок в еще один объект Sprite, а уже его крепим на игровую площадку.
Пример:

// fields
public BitmapTextureAtlas mBallTextureAtlas;
public ITextureRegion mBallTextureRegion;
public Sprite mBallSprite;
// create object
public Ball(float pX, float pY, VertexBufferObjectManager pVertexBufferObjectManager, TextureManager textureManager) {
        mBallTextureAtlas = new BitmapTextureAtlas(textureManager, 128, 128, TextureOptions.BILINEAR);
        mBallTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(mBallTextureAtlas,BallGameApp.getAppContext(), "ball.png", 0, 2);
        mBallSprite = new Sprite(pX, pY, mBallTextureRegion, pVertexBufferObjectManager);
        mBallTextureAtlas.load();
 }

Попробуем разобраться почему так сложно получается.
Сначала создаем атлас - то, где будет отображаться картинка. Атлас не может быть меньше размеров картинки. Обратите внимание, что размеры являются степенью 2. AndEngine может конечно и другие размеры поддерживать, но реализация такая, что для картинки 150х150 будет выделяться место как для 256х256. Атлас может быть больше картинки, но это тоже перерасход памяти, или в случае повторения картинки.
textureManager - помогает загрузить эту самую картинку.
TextureOptions.BILINEAR - указывает каким способом отображения нужно работать с картинкой. В большинстве случаев хватает BILINEAR_PREMULTIPLYALPHA или BILINEAR. Также здесь можно указать, чтобы картинка повторялась - таким образом вы можете держать в приложении картинку 4х4, а закрашивать ей 256х256.

     ITextureRegion - вытягивает картинку из папки assets и грузит ее на атлас. Если вы грузите несколько картинок на атлас, то вам пригодятся 2 последних параметра, которые указывают, куда именно грузить ту или иную картинку. ITextureRegion позволяет также создавать анимированные картинки, когда одно изображение содержит несколько и они показываются одно за другим. В этом случае нужно использовать createTiledFromAsset вместо createFromAsset.
Здесь, вроде разобрались. Картинки загрузили, но почему же они не отображаются? А дальше можно работать только со Sprite’ами. Именно они подгружаются в игру. Создается Sprite из координат верхнего левого угла, того самого ITextureRegion и pVertexBufferObjectManager.  Последняя строчка  mBallTextureAtlas.load(); загружает ресурсы в программу, но отнюдь не на игровую площадку. Однако, если забыть указать эту строку, то вместо объектов на поле будут черные квадраты.
     Таким образом можно создать простой объект-картинку. Выше был пример отдельного класса для него, однако можно сделать все из функции  onCreateResources. Тогда реализация будет выглядеть так:

mBallTextureAtlas = new BitmapTextureAtlas(getTextureManager(), 128, 128, TextureOptions.BILINEAR);
        mBallTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(mBallTextureAtlas,BallGameApp.getAppContext(), "ball.png", 0, 2);
        mBallSprite = new Sprite(pX, pY, mBallTextureRegion, getVertexBufferObjectManager());
        mBallTextureAtlas.load();


Подходим к загрузке картинок на игровую площадку. Это происходит в onCreateScene(). Сцена держит в себе все объекты, которые нужно отображать. Сначала создается эта самая сцена.

mScene = new Scene();
// background
mScene.attachChild(mBallSprite);

и в общем-то все. Можно запустить и посмотреть на картинку.

Создание тел

Дальше, например, если мы захотим сделать из картинки тело, со всеми вытекающими свойствами, то это делается так.
Зададим физические свойства среды

PhysicsWorld mPhysicsWorld = new PhysicsWorld(new Vector2(0, SensorManager.GRAVITY_EARTH), false);

Для вектора можно задавать и другие параметры, отличные от GRAVITY_EARTH. Есть даже GRAVITY_SATURN, вдруг кому пригодится. Вектор этот нужен, как вы уже поняли, для охарактеризования физической среды.  Перейдем к созданию физических свойств тела:
FixtureDef mBallFixture = PhysicsFactory.createFixtureDef(mBallWeight, 0, 0);
1 параметр означает жесткость шарика, он может быть и float.
2 параметр - это эластичность
3  параметр - это отскок.
Если вы создаете шарик из железа, то параметры могут быть и по 0. Вес шарика никак не влияет на его скорость. Хотя может, я что неправильно сделала.
Далее создадим сам объект тела на основе этих физических свойств.

Body mBallBody = PhysicsFactory.createCircleBody(physicsWorld, mBallSprite, BodyDef.BodyType.StaticBody, mBallFixture);

Так как у нас шарик, то и конструктор мы берем для круга. Существуют и другие для треугольников, квадратов и прочего. На любой цвет и вкус так сказать. В конструкторе передаем среду, картинку объекта, тип тела и свойства. Типов тела 3: статические, динамические и кинетические. Статические никуда не двигаются, динамические двигаются и кинетические не двигаются, но могут быть сдвинуты другим телом.

То, что мы подставили картинку в тело, еще не означает, что они вместе. Нужно их соединить таким нехитрым способом:

mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(mBallSprite, mBallBody, true, true))

2 последних параметра означают, что 1 - тело может изменять позицию и 2 - тело можно вращать.
Последний этап прикрепить “физический мир” к сцене:
mScene.registerUpdateHandler(mPhysicsWorld);

Таким образом, создания тела происходит в таком порядке:

onCreateResources() - создаем картинку-спрайт, физический мир, можем даже физические свойства здесь создать. Загрузим картинку. Создаем тело.
onCreateScene()     -   Регистрируем связь между объектом и картинкой. Грузим картинку на сцену. Пробуем запустить. Теперь на экране должен быть объект, который перемещается в зависимости от наклона экрана.