The Jerusalem PostA dangerous habit: Legislating hatred one step at a time - opinionESPNWhy a Tyreek Hill-Chiefs reunion makes so much senseRTP DesportoMundial de Hóquei. Seleção feminina bate ColômbiaESPN DeportesVinícius, Brahim y otros convocados ya se entrenan con Real MadridBollywood HungamaNeil Bhoopalam wants to work with Rajkumar Hirani to explore family-oriented films: “It would be a good shift for me”Daily MaverickSOCCER INTEGRITY: Senegal vs Morocco Afcon final saga set to be heard in Swiss courtPunch2027: INEC lists states with most registered votersZDF heuteAktuelle Pressemitteilungen des ZDFSCMP ChinaUS firm to make battle-tested drones in Taiwan, boosting supply chain resilienceBillboardBillboard Latin Music Week 2026 Adds Rubén Blades, Anthony Ramos, Lenny Tavárez, Tito Nieves & More to LineupThe Hollywood ReporterSherlock Holmes, But Make It Rom-Com: Lucy Hale to Lead Roku SeriesThe RegisterZombie instructions on carefully constructed web pages could trick GitHub Copilot CLI into sharing secrets
The Daily Newsstand · Free, Always
Tuesday, October 6, 2026

Физический аналоговый ввод на плоском экране в iOS игре

Translate

Как превратить обычное касание iPhone в непрерывный игровой контроллер — и вообще не показывать его на экране

Мы привыкли воспринимать сенсорный экран довольно просто: палец находится в какой‑то точке, система знает его координаты (x, y), а дальше практически вся привычная механика мобильного управления строится вокруг изменения этих координат. Нажал на кнопку, сделал свайп, потянул виртуальный стик, передвинул слайдер — в каждом случае мы так или иначе говорим телефону, где находится палец или куда он переместился.

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

Я большой фанат автосимов, и именно в них особенно хорошо почувствовал ограничение такого подхода. С кнопками и слайдерами всё прекрасно работает визуально: передвинул ползунок — увидел новое положение, нажал кнопку — увидел реакцию интерфейса. Но мне не хватало самого ощущения контроля, потому что в автомобиле работа с педалью — это не только её положение, а постоянное дозирование воздействия и обратная связь. Мне хотелось не просто видеть на экране условные 30 или 60 процентов сцепления, а чувствовать изменение прямо под пальцем, точно удерживать промежуточное значение и физически понимать, когда я приближаюсь, например, к точке схватывания.

Отсюда и появился вопрос: а обязательно ли вообще рисовать педаль? Если телефон уже способен понять, как именно палец взаимодействует со стеклом, превратить это взаимодействие в непрерывное значение и тут же вернуть человеку информацию через Taptic Engine, то, возможно, отдельный визуальный контроллер здесь вообще лишний. Палец может практически оставаться на одном месте, величина воздействия может меняться без перемещения по экрану, а важные состояния можно ощущать тактильно, а не искать глазами на полоске или шкале.

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

У касания есть не только координаты

Когда я начал разбираться, можно ли вообще получить такой аналоговый ввод без движения пальца по экрану, оказалось, что помимо привычных координат UIKit даёт ещё одну интересную характеристику касания — UITouch.majorRadius. Это приблизительный радиус области, которой палец в данный момент соприкасается с экраном, и на первый взгляд он выглядит довольно непримечательно: ещё одно свойство UITouch, которое легко однажды увидеть в документации, понять, что оно описывает геометрию касания, и больше к нему никогда не возвращаться.

Но если посмотреть на majorRadius именно с точки зрения управления, становится интереснее. Большой палец может лежать практически в одной и той же точке экрана, то есть его координаты почти не меняются:

[
(x,y) \approx const
]

При этом сам характер контакта со стеклом остаётся далеко не постоянным. Можно едва касаться экрана краем подушечки, можно немного изменить угол пальца, а можно прижать его сильнее и увеличить область соприкосновения со стеклом. Палец при этом не нужно никуда вести, искать им нужное положение на шкале или контролировать его координаты — он остаётся примерно там же, но majorRadius меняется вместе с геометрией контакта.

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

Условно разницу можно представить совсем просто:

лёгкий контакт       ●
средний контакт     ●●●
большой контакт    ●●●●●

Положение пальца при этом почти не изменилось, а majorRadius изменился. Получается дополнительный управляющий параметр, который существует практически независимо от перемещения пальца по экрану: вместо привычного вопроса «куда пользователь передвинул палец?» меня начинает интересовать другое — что сейчас происходит с контактом пальца в той точке, где он уже находится?

Это не Force Touch

Здесь есть важный нюанс, без которого вся идея начинает звучать немного магически: majorRadius не измеряет настоящую силу нажатия. Нельзя получить значение в points, перевести его в ньютоны и сказать, например, что 40 pt = 4 Н. iPhone в данном случае оценивает геометрию области контакта со стеклом, а не измеряет приложенную к нему силу.

Для моей задачи это оказалось не так критично. Подушечка пальца мягкая, поэтому вместе с изменением характера нажатия меняется её деформация и, соответственно, площадь контакта со стеклом. Связь здесь не настолько простая, чтобы считать majorRadius датчиком давления, но человеку вполне по силам намеренно и довольно плавно менять этот параметр.

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

От majorRadius к 0…1

На практике быстро выясняется, что просто взять majorRadius и отправить его напрямую в физику машины нельзя. У всех разные пальцы, разный хват телефона и угол касания; более того, даже один человек через несколько минут может немного перехватить устройство, и привычный диапазон изменится. Поэтому абсолютное значение радиуса само по себе мне практически ничего не даёт — нужен диапазон, относительно которого его можно интерпретировать.

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

[
[r_{min},r_{max}]
]

и могу нормализовать текущее измерение:

[
u = \frac{r‑r_{min}}{r_{max}‑r_{min}}
]

с ограничением результата диапазоном

[
0 \leq u \leq 1.
]

После этого остальной игре уже совершенно необязательно знать, что где‑то внутри вообще существует majorRadius. Для неё это обычная аналоговая ось, по которой приходят значения вроде 0.00 → 0.18 → 0.41 → 0.63 → 0.82 → 1.00.

Правда, появляется следующая проблема: сигнал немного гуляет. Палец физически не может удерживать абсолютно одинаковую форму контакта, плюс само измерение слегка меняется от события к событию, поэтому после нормализации нужна фильтрация. Причём здесь довольно легко переборщить: сильное сглаживание действительно делает сигнал красивее, но одновременно добавляет ощущение задержки, а для педали это гораздо неприятнее небольшого шума.

В итоге весь входной тракт у меня сводится примерно к такой цепочке:

палец
  ↓
геометрия контакта
  ↓
UITouch.majorRadius
  ↓
персональная калибровка
  ↓
нормализация
  ↓
фильтрация
  ↓
0...1
  ↓
игровая физика

На этом этапе технически уже получился аналоговый ввод, но вместе с ним появилась другая проблема, которая в итоге оказалась для меня даже интереснее самого majorRadius: если я действительно хочу убрать с экрана слайдер или изображение педали, откуда человек должен понимать, где он сейчас находится внутри диапазона 0...1?

Если не глазами, то пальцем

У обычного слайдера с этим всё просто. Посмотрел на него — и сразу увидел:

[████████░░] 80%

Если визуальный контроллер исчезает, эту информацию нужно каким‑то образом вернуть пользователю. И здесь я понял, что смотрел только на половину возможностей самого устройства: экран умеет не только получать физический сигнал от пальца, потому что рядом с ним есть Taptic Engine, способный вернуть физический сигнал обратно человеку.

Получается уже совсем другая схема:

         палец
           ↓
    геометрия контакта
           ↓
    UITouch.majorRadius
           ↓
 калибровка + фильтрация
           ↓
          0...1
           ↓
    игровая механика
           ↓
     состояние системы
           ↓
      Core Haptics
           ↓
     Taptic Engine
           ↓
         палец
           ↺

И вот здесь идея для меня действительно поменялась. Сначала я просто искал способ получить необычный аналоговый input, а в результате пришёл к замкнутому циклу: я меняю контакт пальца, телефон интерпретирует это изменение, симуляция реагирует, устройство отвечает тактильно, я чувствую этот ответ и немного корректирую палец.

То есть обратная связь возвращается непосредственно туда же, откуда пришёл управляющий сигнал.

Haptics как часть самого контроллера

В такой конструкции haptics уже не очень хочется использовать как обычное «нажал кнопку — телефон завибрировал». Гораздо полезнее связать характер отклика с состоянием аналогового сигнала, чтобы палец получал информацию о том, что происходит внутри невидимой шкалы.

Например, начало диапазона можно вообще оставить спокойным, затем при приближении к важной области постепенно добавить едва заметный отклик, а в определённой точке дать короткий хорошо различимый импульс. Для сцепления такой точкой естественно становится зона схватывания:

0.0 ───────────── 0.4 ─── 0.6 ───────────── 1.0
                         ↑
                  зона схватывания

Получается своего рода невидимая шкала, которую не нужно постоянно видеть глазами, потому что некоторые её состояния можно почувствовать пальцем.

Конечно, настоящей педалью стекло от этого не становится. У физической педали есть ход, сопротивление механизма, изменение усилия, и нога получает огромное количество информации, которую Taptic Engine воспроизвести не способен. Но моей целью и не было полностью симулировать механику педали — мне хотелось вернуть хотя бы часть потерянной физической информации другим доступным каналом.

И именно здесь обнаруживается интересное следствие всей конструкции: если положение пальца не определяет значение напрямую, а важные состояния этого значения можно почувствовать, визуальный контроллер перестаёт быть обязательным.

Контроллер, который можно не рисовать

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

┌────────────────────────────────────┐
│                                    │
│               GAME                 │
│                                    │
│ [ STICK ]                [ GAS ]   │
│                          [ BRAKE ] │
└────────────────────────────────────┘

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

┌────────────────────────────────────┐
│                                    │
│                                    │
│               GAME                 │
│                                    │
│                                    │
└────────────────────────────────────┘

     ↑                          ↑
  сцепление                    газ
     │                          │
  большой                     большой
   палец                       палец

Управление никуда не исчезло, просто ему больше не обязательно занимать место на дисплее. И для меня это намного интереснее, чем возможность сделать ещё одну необычную виртуальную педаль: можно попробовать убрать интерфейс управления, вообще не убирая само управление.

Стекло вместо UI

Если немного отойти от конкретной реализации, разница здесь получается скорее концептуальной. Обычный мобильный интерфейс предлагает сначала визуальный объект, а уже через него значение:

палец
  ↓
нарисованный контроллер
  ↓
положение контроллера
  ↓
значение
  ↓
игровая система

В моём случае промежуточный визуальный слой можно убрать:

        палец
          ↕
        стекло
          ↕
геометрия контакта
          ↕
  аналоговый input
          ↕
   игровая система
          ↕
       haptics
          ↕
        палец

Экран одновременно остаётся дисплеем, работает как сенсорная поверхность и участвует в обратной связи. Чтобы получить условные 70% на обычном слайдере, мне нужно передвинуть палец примерно в положение 70%; здесь же палец может почти не менять координаты, а значение при этом свободно двигаться, например, 20% → 37% → 52% → 68% → 61% → 74%.

Из‑за этого взаимодействие начинает ощущаться не как перемещение элемента UI, а скорее как физический жест, интенсивность которого можно дозировать.

Как это работает в ClutchLab

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

        ЛЕВАЯ РУКА                         ПРАВАЯ РУКА

        большой палец                      большой палец
             ↓                                  ↓
      геометрия контакта                 геометрия контакта
             ↓                                  ↓
        majorRadius                         majorRadius
             ↓                                  ↓
          0...1                              0...1
             ↓                                  ↓
        СЦЕПЛЕНИЕ                            ГАЗ
             └──────────────┬───────────────────┘
                            ↓
                  физическая модель
                            ↓
                     поведение машины

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

И здесь замыкается уже более интересный цикл:

изменяю контакт пальца
          ↓
изменяется положение сцепления
          ↓
подхожу к зоне схватывания
          ↓
получаю тактильный отклик
          ↓
удерживаю контакт
          ↓
корректирую газ второй рукой
          ↓
машина реагирует
          ↓
снова корректирую оба пальца
          ↺

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

Где всё это начинает ломаться

При всей привлекательности идеи ограничений у неё хватает. majorRadius не измеряет реальную силу, Taptic Engine не создаёт сопротивления пальцу, у стекла нет механического хода, поэтому такая система не заменит настоящую педаль, аналоговый триггер геймпада или любой другой физический контроллер, который действительно сопротивляется движению пользователя.

Есть и более практическая проблема: majorRadius сильно зависит от человека. Размер пальца, угол, хват телефона и положение рук меняют рабочий диапазон, поэтому то, что хорошо настроено под меня, необязательно будет так же хорошо ощущаться у другого игрока. Из‑за этого реальная реализация оказалась не одной хитрой строчкой с UITouch.majorRadius, а цепочкой вполне обычных инженерных компромиссов:

raw majorRadius
      ↓
calibration
      ↓
normalization
      ↓
filtering
      ↓
game input
      ↓
haptic tuning

Причём haptic tuning здесь оказался не менее важен, чем обработка самого входа. Если слишком сильно фильтровать majorRadius, педаль начинает ощущаться ватной; если сделать haptics слишком агрессивными, через некоторое время они начинают раздражать; если слишком слабыми — мозг быстро перестаёт воспринимать их как полезную информацию. А заметная задержка между изменением контакта и тактильным ответом вообще довольно быстро разрушает ощущение того, что палец взаимодействует с чем‑то цельным.

Поэтому это одна из тех механик, которые практически бессмысленно оценивать только по коду или в симуляторе. Самое важное происходит не внутри UIKit и даже не внутри игровой физики — оно происходит в петле между пальцем, стеклом и Taptic Engine, а значит, почти каждое изменение приходится проверять непосредственно на устройстве.

И это не только про педали

ClutchLab просто оказался местом, где мне понадобился такой тип управления, но сама идея никак не привязана к автомобилям. Потенциально тот же принцип можно попробовать использовать для натяжения лука, сжатия пружины, хвата предмета, торможения, курка, заряда способности или даже управления каким‑нибудь музыкальным параметром — везде, где двух состояний «нажато / не нажато» мало и хочется дать человеку возможность дозировать действие, удерживать промежуточное значение и постоянно его корректировать.

Не думаю, что majorRadius внезапно должен заменить обычные жесты или слайдеры. Во многих интерфейсах они очевиднее, точнее и просто привычнее. Мне интересен сам факт, что у сенсорного экрана есть ещё один вариант взаимодействия, который обычно остаётся где‑то на уровне технической характеристики касания, хотя потенциально его можно сделать частью игровой механики.

Плоский экран как аналоговый инструмент

В итоге UITouch.majorRadius оказался для меня скорее отправной точкой, чем главной идеей эксперимента. Гораздо интереснее то, что iPhone позволяет построить двустороннее физическое взаимодействие: с одной стороны, телефон считывает изменение контакта пальца, а с другой — способен через Taptic Engine вернуть этому же пальцу информацию о состоянии системы.

Если собрать весь путь целиком, получается такая петля:

                    ┌───────────────────────┐
                    │        ПАЛЕЦ          │
                    └───────────┬───────────┘
                                │
                                │ меняется контакт
                                ↓
                    ┌───────────────────────┐
                    │   ГЕОМЕТРИЯ КАСАНИЯ   │
                    │ UITouch.majorRadius   │
                    └───────────┬───────────┘
                                │
                                ↓
                    ┌───────────────────────┐
                    │ КАЛИБРОВКА + ФИЛЬТР   │
                    │        0...1          │
                    └───────────┬───────────┘
                                │
                                ↓
                    ┌───────────────────────┐
                    │   ИГРОВАЯ СИСТЕМА     │
                    │ физика / состояние   │
                    └───────────┬───────────┘
                                │
                                ↓
                    ┌───────────────────────┐
                    │     CORE HAPTICS      │
                    │    Taptic Engine      │
                    └───────────┬───────────┘
                                │
                                │ физический отклик
                                ↓
                    ┌───────────────────────┐
                    │        ПАЛЕЦ          │
                    └───────────┬───────────┘
                                │
                                └─────── ↺

И вот эта петля для меня в итоге важнее конкретного API. Touchscreen необязательно воспринимать только как плоский монитор, на котором мы вынуждены рисовать кнопки, стики и ползунки, чтобы потом взаимодействовать с их изображениями. Само стекло уже может участвовать в управлении: принимать физическое действие человека и через устройство возвращать ему физическую обратную связь.

Контроллер при этом может быть невидимым, величину ввода необязательно постоянно показывать на экране, а сам дисплей можно практически целиком оставить игре.

Поэтому главная идея для меня здесь всё‑таки не в необычной педали на iPhone и даже не в хитром применении UITouch.majorRadius. Интереснее возможность немного иначе посмотреть на поверхность, которой мы касаемся сотни раз в день: не как на место, где нужно сначала нарисовать контроллер, а как на аналоговый инструмент, которым уже можно управлять напрямую.

View the original on Хабр →

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.