Kā jau ziņots, tad ar iOS 7 Apple ir ieviesuši atbalstu 2 veidu spēļu kontrolieru savienošanai ar iOS ierīcēm (iPad, iPhone, iPod) – bezvadu kontrolieri (nesen iznācis SteelSeries) un kontrolieri, kas fiziski piestiprināti pie ierīces un komunicē izmantojot Lightning savienojumu (pagaidām tikai Moga un Logitech kontrolieri). Tā kā šobrīd internetā nav praktiski nekādas informācijas par to, kā programmēt lietotnes šiem kontrolieriem, nolēmu uzrakstīt pamācību (pirmkoda faili pieejami šeit). Nesen kādam vācu uzņēmumam vārdā “MOGA” aizsūtīju sevis veidotās spēles aprakstu un lūgumu atsūtīt pāris kontrolierus testēšanai, un viņi nekavējoties to arī izdarīja.

Atšķirībā no Android kontrolieriem, ar iOS viss ir daudz vienkāršāk, jo Apple pieprasa, ka visi kontrolieri seko stingriem standartiem gan pogu skaita, izvietojuma un nosaukumu ziņā (A, B, X, Y, L1, L2, R1, R2), gan arī tehniskajā ziņā. Interesanti ir tas, ka šīs prasības nosaka, ka A, B, X un Y pogām jābūt analogām t.i. jāziņo, cik spēcīgi tās ir nospiestas, un tas arī lieliski darbojas.

featuresHIDGameControllerExtendedFormFittingSample_2xfeaturesHIDGameControllerExtendedNonFormFittingSample_2x

Zemāk redzams MOGA kontrolieris uzmaukts uz iPhone 5.

IMG_5628

Diemžēl pagaidām (domāju, nākotnē nekas nemainīsies) vienīgais veids, kā saņemt ievadi no iOS 7 kontrolieriem, ir izmantojot Objective-C programmēšanas valodu. Lai iegūtu sarakstu ar visiem kontrolieriem, jāizmanto GCController klases statisko īpašību controllers, kurā tiek glabāts saraksts ar visiem šobrīd pieejamajiem kontrolieriem. Ievadi jūs varat iegūt no vadāmierīces (gamepad), kas glabājas GCController gamepad īpašībā. Ja vadamierīce ir paplašināta (extended) t.i. tam ir vairākas sviras un L2 un R2 taistiņi, tad tiem var piekļūt izmantojot extendedGamepad īpašību (ja kontrolieris nav paplašīnāts, šī īpašība atgriezīs Nil). Vai kontrolieris ir fiziski piestiprināts pie ierīces, var noskaidrot izmantojot GCController īpašību attachedToDevice.

NSArray* controllers = GCController.controllers;
for (GCController* controller in controllers)
{
  if (controller.attachedToDevice)
  {
    GCGamepad* gamepad = controller.gamepad;
    //strādājam ar vadāmierīci
  }
}

Cik noprotu, tad enerģijas taupīšanas nolūkos, ieslēdzot lietotni, šis kontrolieru saraksts ir tukšs.  Lai pieprasītu iOS ieslēgt visus kontrolierus un atgriest to sarakstu, ir jāpierakstās uz GCControllerDidConnectNotification paziņojumu. Ja grib uzzināt arī, ja kāds kontrolieris tiek atvienots no iOS ierīces, jāpierakstās uz GCControllerDidDisconnectNotification paziņojumu.

[[NSNotificationCenter defaultCenter] addObserver:self
  selector:@selector(handleConnected:)
  name:GCControllerDidConnectNotification
  object:nil];

[[NSNotificationCenter defaultCenter] addObserver:self
  selector:@selector(handleDisconnected:)
  name:GCControllerDidDisconnectNotification
  object:nil];

Kad esam saņēmuši paziņojumu par ierīces pievienošanos, varam izskriet cauri visam ierīču sarakstam un pierakstīties uz vadāmierīces pogu (dpad, buttonA, buttonB utt.) izmaiņu paziņojumiem (valueChangedHandler).

NSArray* controllers = GCController.controllers;
for (GCController* controller in controllers)
{
  if (controller.attachedToDevice)
  {
    controller.gamepad.dpad.valueChangedHandler =
      ^(GCControllerDirectionPad* dpad, float xValue, float yValue) {
        //bultiņu taustiņu apstrādes kods
      };

    controller.gamepad.buttonA.valueChangedHandler =
      ^(GCControllerButtonInput* button, float value, BOOL pressed) {
        //A pogas apstrādes kods
      };

    if (controller.extendedGamepad)
    {
      controller.extendedGamepad.leftThumbstick.valueChangedHandler =
        ^(GCControllerDirectionPad* dpad, float xValue, float yValue) {
          //kods, kas apstrādā kreiso sviru
      };
    }
    break;
  }
}

Ja Bluetooth kontrolieris nav sapārots ar iOS ierīci, tad ierīču meklēšanu var uzsākt ar startWirelessControllerDiscoveryWithCompletionHandler, bet apstādināt ar stopWirelessControllerDiscovery metodēm. Tikko kāda ierīce atrasta, tā tiks izsaukta.GCControllerDidConnectNotification paziņojums.

[GCController startWirelessControllerDiscoveryWithCompletionHandler:
  ^(void){ /*meklēšana pabeigta*/ }];

Ceru, ka šī pamācība jums noderēs jūsu veidotajos projektos. Savus labojumus, papildinājumus un komentārus varat atstāt zemāk vai arī sūtīt uz elviss[at]elviss[punkts]lv. Pilnu kodu varat apskatīt šeit.