Разработка Box2D игры под Android

16 ноября 2011 г.

Хотелось бы рассказать о своем опыте создания приложения под систему Android. Для начала немного истории. Все началось с того, что мой друг практически каждый день рассказывал мне о сладкой жизни разработчика игр и о том, что за Андроидом будущее. И со временем я заразился его энтузиазмом, хотя с программированием дела у меня обстояли довольно не сладко. Но сказано — сделано, и мы приступили к разработке своего приложения.

Любое дело начинается с идеи. И если вы с детства хотели написать игру, то непременно этой игрой должен быть 3D шутер. Ну а как же: Doom 2, Quake 2, Duke Nukem и иже с ними. Но недостаток опыта сделал свое дело и поэтому создание клона Crysis пришлось отложить на потом. К счастью, эпичных 2D игр тоже достаточно, поэтому решили все же начать с них.

С идеей определились, дальше — реализация. Чтобы облегчить себе жизнь и не использовать чистый Android API нужно было найти подходящий фреймворк. Так как в то время я только постигал азу программирования на JAVA, мой коллега выбрал LibGDX. Как я считаю, этот выбор оказался правильным, так как из ныне существующих бесплатных фреймворков LibGDX является наиболее функциональным и уж точно самым документированным. Так как разработка 2D игры для двух программистов показаласось нам слишком легкой задачей (наивные), то было решено, что каждый будет делать свою игру сам.

С идеей я определился довольно быстро. Хотелось что-то типа тетриса, но с тачскрином и дополнительными функциями. Вот что из этого в итоге получилось:

image

В этой игре (а назвал я ее, кстати, Equilibrium) необходимо так разместить разные блоки — квадраты, окружности и прямоугольники выше разделительной линии, чтобы они не упали на землю и не заставили балансир коснуться пола. Основной проблемой было связать Box2D и графические спрайты. В конечном итоге получился такой код:

Vector2 pos = ball.getPosition().sub(//вектор равен параметрам box2D тела GameAssets.sb12.getWidth()/2,//sb12-графический спрайт
GameAssets.sb12.getHeight()/2);
// float angleDeg = ball.getAngle() * MathUtils.radiansToDegrees;
//вносим в переменную angleDeg текущий угол тела
GameAssets.sb12.setPosition((pos.x+9.6f)*40, (pos.y+5.6f)*40);
//связываем позицию спрайта с 2D телом (почему именно такие числа написано чуть ниже)
GameAssets.sb12.setRotation(angleDeg);
//связываем угол

Все эти действия происходят каждый фрейм в методе render(). Но так как в Box2D не рекомендуется использовать объекты с длиной/шириной более 10 метров то я установил значение 1метр=40 пикселей и использовал для такую формулу для определения параметров положения спрайта:

((pos.x-6-boxSize+origin x *40, (pos.y-10-boxSize+origin y)*40)

где 6 и 10-половинные ширина и высота экрана в Box2D метрах, origin x & y — половинные размеры спрайтов, а 40 — количество пикселей в метрах. Для каждого такого блока я создал отдельный класс, в котором метод touchDown(), реализующий нажатие, создавал новую фигуру.

Условием поражения считалось определение коллизи любого предмета с полом, а условием победы — формула типа

if(sq_1.c==16){//количество блоков, которые необходимо разместить
wintime+=deltaTime;//после выполнения условия начинается отсчет времени
if(wintime>1.48&&wintime>1.52)//временной промежуток
last_body_y1=sq_1.squares_1[7].getPosition().y;//первое положение тела
if(wintime>1.98&&wintime>2.02)//временной промежуток
last_body_y2=sq_1.squares_1[7].getPosition().y;//второе положение тела
if((wintime>2.01)&&(last_body_y1-last_body_y2)>0.1&&loose==false)//проверка на покой тела win=true;
if(wintime>2.02) wintime=1.47f;//если условие не выполнено, то цикл повторяется снова }

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

Теги: рубрика Android
  • Похожие статьи
  • Предыдущие из рубрики