Работа с элементами контроллера

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

Используйте профили контроллера для отображения физических проверок на игровые вводы

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

Профиль контроллера реализован как класс в платформе Игрового контроллера. Таблица 3-1 перечисляет доступные профили и соответствующее свойство на GCController класс.

Табличные 3-1  профили Игрового контроллера

Профиль

Класс реализации

Свойство GCController

Игровой планшет (стандартное расположение органов управления)

GCGamepad

игровой планшет

Расширенный Игровой планшет (расширенное расположение органов управления)

GCExtendedGamepad

extendedGamepad

Чтобы определить, поддерживает ли контроллер профиль, считайте свойство, соответствующее профиль на контроллере GCController объект. Если значение nil, контроллер не поддерживает тот профиль. Иначе, возвращенный объект профиля используется для доступа к элементам управления.

Вот некоторые инструкции для работы с профилями:

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

Различные виды элементов представлены классами в платформе Игрового контроллера. Все элементы контроллера получены из GCControllerElement класс, реализующий общие способы поведения. Каждый класс профиля представляет одно или более свойств, представляющих значения управления. Таблица 3-2 перечисляет доступные типы элемента и классы, реализующие их.

Табличные 3-2  типы элемента Игрового контроллера

Тип элемента

Класс реализации

Значение элемента

Кнопка

GCControllerButtonInput

Число с плавающей точкой между 0 и 1. Также может быть считан как булево значение, утверждающее, нажимается ли кнопка.

Ось

GCControllerAxisInput

Число с плавающей точкой между -1 и 1.

Геймпад (Геймпад)

GCControllerDirectionPad

Читайте или как две оси или как четыре направленных кнопки.

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

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

Чтение значений элемента непосредственно

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

Перечисление 3-1 показывает возможную реализацию этого понятия. Этот метод предназначается, чтобы быть вызванным каждый раз, когда кадр обрабатывается. Например, если Ваша игра создается с Набором Sprite, Вы могли бы опросить информацию об элементе из сцены update: метод. Перечисление 3-1 читает три элемента на расширенном профиле игрового планшета. thumbstick используется для управления тягой космического корабля, и два триггера используются, чтобы запустить лазеры или запустить ракеты.

Перечисление 3-1  , Опрашивающее элементы профиля

- (void) readControlInputs
{
    GCExtendedGamepad *profile = self.myController.extendedGamepad;
    if (profile.rightTrigger.isPressed)
        [self fireLasers];
    if (profile.leftTrigger.isPressed)
        [self launchMissile];
    [self applyThrust: profile.leftThumbstick.yAxis.value];
}

В этом примере, pressed свойство используется для оружия, но свойство значения используется для тяги поставки. Оружие может только быть в одном из двух состояний: увольнение или не увольнение. Однако тяга поставки вычисляется на основе как далеко игровые движения thumbstick, таким образом, value свойство должно использоваться вместо этого.

Регистрация, которую вызовут, когда изменяется элемент

Когда элемент изменяется, в некоторых играх лучше быть вызванным в точный момент. Например, Вы могли бы хотеть гарантировать, что нажатие кнопки всегда обнаруживается, даже если нажатие происходит между кадрами. Для реализации этого Вы регистрируете обработчик изменения. Платформа Игрового контроллера обрабатывает и обновляет профили на основном потоке. Каждый раз, когда это обновляет значение элемента в профиле, любые обработчики для того элемента вызывают. Обработчик может быть зарегистрирован на объекте профиля или определенном элементе в профиле. Когда обработчик создается на объекте профиля, его вызывают каждый раз, когда изменяется любой элемент на профиле. Если многократные значения на изменении профиля одновременно, обработчик вызывают один раз для каждого изменившегося элемента. Если обработчик регистрируется на элементе, обработчик вызывают каждый раз, когда обновляются тот элемент или любой из дочерних элементов того элемента.

Перечисление 3-2 реализует обработчик на объекте профиля. В этом примере код проверяет два триггера, чтобы определить, был ли любой нажат.

Перечисление 3-2  , Регистрирующее обработчик значения для профиля

GCExtendedGamepad *profile = self.myController.extendedGamepad;
profile.valueChangedHandler = ^(GCExtendedGamepad *gamepad, GCControllerElement *element)
    {
        if ((gamepad.rightTrigger == element) && gamepad.rightTrigger.isPressed)
            [self fireLasers];
        if ((gamepad.leftTrigger == element) && gamepad.leftTrigger.isPressed)
            [self launchMissile];
    };

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

Перечисление 3-3  , Регистрирующее отдельные обработчики значения для элементов профиля

GCExtendedGamepad *profile = self.myController.extendedGamepad;
profile.rightTrigger.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed)
    {
        if (pressed)
            [self fireLasers];
    };
profile.leftTrigger.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed)
    {
        if (pressed)
            [self launchMissile];
    };

Используйте снимки для сериализации вводов контроллера

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

  • Чтение вводов в одном потоке и затем передача их к другому потоку для обработки.

  • Передача контроллера вводит по сети.

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

Существует один класс снимка для каждого класса профиля. Каждый вид снимка реализован как подкласс класса профиля, представляющего сохраняемый профиль. Для создания нового снимка вызовите объект профиля saveSnapshot метод. Поскольку объект снимка является также объектом профиля, считайте его значения, как Вы были бы с регулярным объектом профиля. Можно часто использовать тот же код, который Вы уже записали, чтобы обработать вводы контроллера и использовать его на снимках вместо этого.

Для выравнивания снимка в двоичный файл, который можно отправить по сети или сохранить на диск Вы читаете снимок snapshotData свойство. При предыдущем сохранении объекта данных можно считать его данные одним из двух способов:

  • Выделите новый объект снимка для класса, используемого, чтобы создать двоичных данных и инициализировать его с initWithSnapshotData: метод.

  • Присвойтесь NSData возразите против существующего объекта снимка snapshotData свойство. Когда Вы делаете это, все элементы в снимке обновляются, и вызывают любые обработчики, присвоенные объекту снимка.

Рекомендации для определенных типов элемента

Вот некоторые инструкции для кнопки и thumbstick типов элемента.

Кнопки и триггеры

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

Thumbsticks и геймпад

В прошлом средства управления thumbstick на контроллерах были проблематичны, требуя, чтобы дополнительная работа в игровом коде компенсировала мертвую зону thumbstick или значения управления, превысившие допуски устройства. При портировании кода с другой платформы необходимо отключить этот код при обеспечении кода к iOS или OS X. Платформа Игрового контроллера автоматически выполняет эти вычисления для Вас.