В SkiBot управлять лыжником можно касаниями экрана или мышкой. Я хотел, чтоб было управление ещё и джойстиком, чтобы игрок мог выбрать самый удобный ему вариант, но когда до него дошло дело обнаружилось неочевидное препятствие. Раз уж я обещал истории с внутренней кухни, то вот рассказ о том, что я пытался сделать и почему у меня не получилось.
Способы управления
Необычная схема управления SkiBot вдохновлена игрой Ski Stunt Simulator, в которую я немало залипал в прошлом. Двигая мышкой вправо и влево мы плавно наклоняем лыжника в один или другой бок, двигая вниз и вверх заставляем его приседать и выпрямляться. В современной игре, конечно, недостаточно поддержки мыши. Для игры на смартфоне или планшете обязательно нужна поддержка тачскрина, а ещё хорошо бы поддерживать геймпад, раз уж таковой может быть подключен и к планшету, и к ПК.
Сделать управление для тачскрина оказалось не сложно. Просто говоря, достаточно заметить точку в которой палец коснулся экрана и, пока палец опущен, его движения вокруг этой точки можно использовать точно так же как используются движения мышки (на самом деле, управлять на тачскрине оказалось чуточку труднее чем мышкой, почему и как я с этим справлялся, расскажу в другой раз).
А вот с джойстиками управление отказалось работать сразу и совсем — лыжника мотало из стороны в сторону, вместо наклонов он опрокидывался, вместо прыжка только вяло дёргал ногами. Я-то ожидал что физический джойстик станет работать точно как экранный, но на деле играть оказалось невозможно.
Сначала я искал ошибку в собственном коде, но в итоге пришёл к тому что стик геймпада это неидеальное устройство с кучей механических изъянов, неравномерностями и обязательной «мёртвой зоной». Которые к тому же меняются от одной модели к другой.
Разные стики
Вот три джойстика, которые помогали мне налаживать управление — фирменный проводной геймпад XBOX 360, дешёвый китайский Speedlink Strike, и джойстик-брелок MOCUTE 032.



Обнаружилось что у всех трёх устройств стики работают по-разному. Чтобы показать разницу я записал выдаваемые координаты при отклонении рычажков и получил своего рода «карты движения» стиков.


Из карт видно что джойстик XBOX (слева) и брелок (справа) достоверно показывают положение стика как в активной области, так и внутри мёртвых зон. Однако у потенциометров MOCUTE слишком резкие пружины, из-за которых стик «прилипает», не только в центре диапазона, но по всей длине осей. Даже напрягая палец, стик невозможно поместить в желаемую точку, если она находится слишком близко к одной оси или другой. Из-за этого свободно управлять стиком получается только во внешних углах диапазона.
Совершенно по-особенному оказался устроен китайский Speedlink. Вместо нормальной рабочей области и мёртвой зоны в центре, у вертикальной и горизонтальной осей просто вырезана середина (половина!) их диапазона. То есть, вместо фактического положения для оси просто рапортуется 0. Если этого мало — снаружи рабочего диапазона есть ещё +-4мм хода, внешняя неактивная зона, перемещения в которой джойстик вовсе не измеряет.

Получается вот такая абсурдная схема. Нормально джойстик работает только в зелёных углах. В жёлтых областях одна из осей обнулена. В красных областях движения стика не обрабатываются никак. Карта движений для этого безобразия оказалась бесполезна — в ней видны только зелёные области.
У меня нет объяснения почему джойстик спроектирован так. Скорее всего, это следствие его крайней дешевизны. Вообще его потенциометры измеряют положение нормально, в той области которая не вырезана. Это мог бы быть не самый точный, но вполне функциональный девайс. Зато я теперь знаю, за что отдаю дополнительные рубли при покупке фирменного геймпада.
Из любопытства я также сделал карту контроллера Nintendo Switch Pro (хотя SkiBot на Switch вероятно никогда не попадёт). Неожиданно здесь мёртвая зона оказалась не в середине рабочей области, а сдвинута вправо и вниз.

Значение для SkiBot
Видно что качественные «фирменные» джойстики сильно отличаются равномерным движением по всей области и мягкой «мёртвой зоной». Такой девайс, вероятно, мог бы более-менее успешно заменить экранный джойстик. Но у игрока может оказаться и недорогой геймпад со странной схемой работы, от которого лыжник будет только дёргаться и опрокидываться, и это полностью вне моего контроля. Получается, как бы я ни налаживал код, я не могу обеспечить управляемость в игре.
По-хорошему, для геймпада нужно создавать свою отдельную схему управления, чтобы наклоняться, приседать, подпрыгивать и проходить уровни можно было даже с самым фиговым девайсом. Только сделать так чтобы эта схема не просто работала, но и использовать её было интересно и весело, совсем непросто, и думаю в итоге получится совсем другая по ощущениям игра. Пока же я нехотя решил что лучший вариант из доступных — убрать поддержку геймпада вовсе. Так на сегодняшний день в игре её и нет.
Другие различия
У трёх геймпадов есть и другие различия, менее существенные для SkiBot, но в целом достаточно поучительные и интересные чтобы о них упомянуть.
Разрешение
При калибровке в Windows видно, что устройства имеют разное разрешение. Фирменный джойстик XBOX выдаёт 16-битные значения от 0 до 65536, то есть различает 32 тысячи разных положений влево от центра, и 32 тысячи вправо. У двух моделей подешевле всего 256 положений (8 бит) от одного края до другого.
Компактный стик карманного джойстика отклоняется всего на +-2мм, поэтому восьми бит достаточно для покрытия диапазона с достаточной точностью. А вот у полноразмерного джойстика XBOX рабочий ход уже целых 14мм, и те же восемь бит уже серьёзно ограничили бы его точность.
Качество сборки
У самого дешёвого геймпада обнаружился люфт стиков. При обычном использовании это не бросается в глаза, но при замерах оказывается что грибок болтается свободно на 1мм (а это 1/7 его рабочего хода, между прочим).
Циркулярность
Из карт видно ещё одно различие геймпадов — разная циркулярность. Хотя у всех описанных моделей стик движется в гнезде круглой формы, на карте более-менее правильный круг получается только у Switch Pro. XBOX приводит положение стика в квадрат со скруглёнными углами, а MOCUTE (и у Speedlink) получается вовсе просто квадрат.
Для схемы управления SkiBot существенно, чтобы от джойстика можно было получать достоверное положение и траекторию движения пальца. Если при движении по кругу стик выдаёт какую-то другую фигуру то управление будет искажённым и труднопредсказуемым. Это кстати верно и для других жанров игр, хотя наверное не так важно.
Стики в других играх
Интересно то как разные игры дополнительно обрабатывают данные джойстиков, чтобы взять под контроль неидеальность работы стиков. На Reddit есть интересный пост с иллюстрациями: The Core Reasons Thumbsticks are Inaccurate : r/truegaming

Даже созданная под геймпад Xbox игра игнорирует любое движение в красной области. В зелёных областях засчитывается диагональное движение, а в синих — только прямолинейное по одной оси или по другой. В затенённой области засчитывается ускорение. Впрочем, автор поста такое грубое вмешательство в работу стиков не одобряет.
Вывод
Я ошибался, думая что раз экранный джойстик может заменить механический, то получится сделать и наоборот. Конечно удобно было бы для разных устройств применить одну схему управления, а не налаживать отдельную, но реальность вносит свои коррективы.
Можно вспомнить что и у экранных джойстиков есть свои особенности, например отсутствие тактильной обратной связи о положении стика под пальцем. Особенность же физического стика о которой нужно помнить — это его механическая неидеальность.
Добавить комментарий