Мордобой

image
В нашем дворе всегда играли в «Мордобойку». А в Москве, оказалось, её называют «Дуля».
И вот, в эти выходные, когда завтрак уже давно закончился, я случайно сыграл в позабытую забаву. Спустя 30 лет.
Ба-ац! Бу-ум! Йо-пт…
Вытерев следы чужой крови на руках, я сел за клавиатуру и твердо решил.

Сейчас! Или никогда.


И написал игру под iOS — встречайте Мордобойку, берегите руки, Сеня.
Как я моделировал движение мяча и веревки, грабил уже краденное, оптимизировал код под iPhone 4S, вспоминал (и тут же забывал) уравнения Лагранжа второго рода в обобщенных координатах, экспроприировал картинки и звуки Му — читайте в нашем журнале.

Итак, Мордобойка была ..., кстати, а что такое Мордобойка?

Кратко о правилах


Мяч веревкой привязан к верхней точке столба. Столб высотой не менее 6 метров. Игроки бьют по мячу руками (как в волейболе) и пытаются закрутить веревку вокруг столба — каждый в свою сторону. На чужую половину заходить нельзя. Зацепы, двойные удары запрещены.

Моделирование движения сферического маятника


Почему-то я считал, что движение сферического маятника очень легко алгоритмизировать. Расписываем силы, действующие на маятник. Сила тяжести и реакция натяжения нити.

// X, Y, Z - координаты мяча, где Y - высота над уровнем моря, она же вертикальное смещение по экрану смартфона, X - горизонт смартфона
// L - длина нити
// R -расстояние от мяча до точки крепления нити (0,0,0)
R = sqrt(X*X+Y*Y+Z*Z);
// g - ускорение свободного падения в пикселах в секунду за секунду. Типичное значение для Земли 9.8 м/с^2, для экрана смартфона 400 п/с^2
// G - сила тяжести
// N - реакция нити
// U, V, W - скорости точки, VB - абсолютное значение скорости
VB = sqrt(U*U+V*V+W*W);
G=g;
N=g*Y/R+VB*VB/R;
// нить мягкая, то есть мнется легко
if (N<0) N=0;

Вычисляем скорости по каждой оси, исходя из второго закона Ньютона.

// dt - шаг по времени, в моем случае dt=0.025 сек, что соответствует 40 кадрам в секунду
U += -dt*N*X/R;
W += -dt*N*Z/R;
V += dt*(G - N*Y/R);


И находим новые значения координат мяча.

X += dt*U;
Y += dt*V;
Z += dt*W;

В верхней полусфере реакция нити может быть отрицательной, что означает режим свободного падения.
Соответственно, во всех случаях, когда R<L, реакцию веревки обнуляем.

Все просто, не так ли? Однако бытовой точности моей численной схеме не хватило. К 10-15 секунде игры накапливались бешеные ошибки вычислений. Схема разностная. А это залет, воин.
Я стал хитрить. Рисовал сцену по-прежнему 40 раз в секунду, а вычисления делал в 10 раз чаще, соответсвенно уменьшив шаг интегрирования с 0.025 до 0.0025. Стало лучше, но ненадолго.
Поменял float на double.
Стало чуть лучше, но нет.
В 100 раз? Нет, Карл. Путь в никуда.
На этом первый день моего программирования завершился, параллельно я завел два проекта Reel the Rope и Face Off в Apple Store, стащил картинки мяча и веревки у Зептолабова, звуки из приложений VolleyBeach и BasketBall, и выбрал главного героя, которого надо победить.
В первом варианте это был Болванчик, стыренный из статьи на Хабре, опубликованной в этот день. Я ленив, что было под рукой — то и использовал.
image
Рисунок 1. Главный соперник Болванчик

Забыл, чей блог, поэтому благодарю авторов идеи заочно.
Песок и небо вытащил из первой Angry Birds и сразу сотворил две заставки для старых iPhone 960 на 640, и для новых 1136 на 640.
image
Рисунок 2. Заставка в игре Мордобойка

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

Изображение мяча я решил поменять — все таки Зептолабов известный чувак, может и заяву в органы накатать.
Я, как бывший чемпион Челябинска-70 по волейболу, знаю толк в мячах и поэтому только Mikasa.
Набрав запрос на картинки мячей Микаса, я долго хохотал, упав под стол.

Оставляю на ваш суд, какая картинка первична)
image

День второй


Проснувшись утром и плотно позавтракав, я уж было собрался пообедать. Как вдруг позвонил Владяс. У Владяса голова — круглая как шар, и я понял

Только сферические координаты


Бросился к клавиатуре и уничтожил все декартовое, все что написал в первый день. Именно не забил комментариями, а грубо стер. Нах. Никогда не храните старые лыжи на балконе. Это вам любой пожарный скажет. Итак, вводим два переменных угла и оставляем в качестве третей переменной радиус-вектор R.

image

Уравнения стали проще, но подводные камни — острее.

Продолжение следует.

Короткое видео для нетерпеливых

© Habrahabr.ru