Pull to refresh

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

Приветствую хаброчитателей, хотелось бы рассказать о своем опыте создания приложения под систему 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;//если условие не выполнено, то цикл повторяется снова
}


В общем это ключевые моменты игры, хотя чтобы описать все возникщие трудности не хватит никакой статьи. Если будет интересно, то напишу продолжение.
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.