iOS 7 Game Controller Tutorial
Learn how to add control your games with a joystick in this iOS 7 game controller tutorial! By Jake Gundersen.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
iOS 7 Game Controller Tutorial
45 mins
- Supported Game Controller Types
- Game Controller Design Considerations
- Getting Started
- Connecting Hardware Controllers
- Connecting the Thumb Stick
- Connecting in the Middle of a Game
- Supporting the Pause Button
- Serializing Controller Inputs
- Playing Back Serialized Controller Data
- Setting the LED Player Indicator
- Where To Go From Here?
Connecting Hardware Controllers
First, make sure your controller is on and paired to your device, following the instructions that came with your controller.
Next, you’ll add some code to connect your game with the controller. Start by opening HUDNode.m and importing the GameController framework:
@import GameController;
Then, add a new GCController property to your private interface:
@property (nonatomic, strong) GCController *controller;
Now you can add the code that interacts with the hardware. Add the following method to HUDNode.m:
- (void)toggleHardwareController:(BOOL)useHardware {
//1
if (useHardware) {
//2
self.alpha = 0.0;
//3
self.controller = [GCController controllers][0];
//4
if (self.controller.gamepad) {
//5
__weak typeof(self) weakself = self;
[self.controller.gamepad.buttonA setValueChangedHandler:^(GCControllerButtonInput *button, float value, BOOL pressed) {
weakself.aPushed = pressed;
}];
[self.controller.gamepad.buttonX setValueChangedHandler:^(GCControllerButtonInput *button, float value, BOOL pressed) {
weakself.shouldDash = pressed;
}];
//Add controller pause handler here
}
} else {
//7
self.alpha = 1.0;
self.controller = nil;
}
}
There are two profiles. The gamepad profile and the extended gamepad profile. The extended gamepad profile has all the controls that the gamepad profile has plus a bunch more. In this app you are going to support both profiles by adding code that responds to both the dpad and the left analog stick. But, for now you are just adding support for the A and B buttons.
There are two ways to access the game controller object for input. First, you can query the state of these properties and read the state of the various buttons and controls. Alternatively, you can set the changeHandler
which executes a block every time the state changes. For the buttons, you use change handlers.
I’ve mapped the A button on the controller to the A button in the HUD and the X button on the controller to the B button in the HUD. This is the most comfortable way to use both dash and jump on the physical control.
- First, you are passing in a boolean to this method. Passing in
YES
will initiate and set up the methods to handle the input from the controller. It will also hide the on screen HUD. PassingNO
will reveal the on screen HUD and reset the controller. - In this part you are just hiding the on screen controls by setting the entire node’s alpha to 0.0.
- Here, you set the property to the GCController object that controls the first controller connected. GCController has a
controllers
class method that returns an array of all the connected hardware. In this app you will only ever communicate with the first controller in the array. You can connect up to four controllers to a single iOS device.There are two profiles. The gamepad profile and the extended gamepad profile. The extended gamepad profile has all the controls that the gamepad profile has plus a bunch more. In this app you are going to support both profiles by adding code that responds to both the dpad and the left analog stick. But, for now you are just adding support for the A and B buttons.
- In this section you check for the presence of the gamepad profile. If you need to know what profile your controller supports you check for the
.gamepad
property or the.extendedGamepad
property. If the property is not supported, accessing the property will returnnil
. - Next, you set up the change handlers that will be called when the button is pressed. In this case, it’s very simple. You set the
aPushed
(orshouldDash
) property to the value ofpressed
.
Each button or control has a property on thegamePad
(orextendedGamePad
) object.There are two ways to access the game controller object for input. First, you can query the state of these properties and read the state of the various buttons and controls. Alternatively, you can set the
changeHandler
which executes a block every time the state changes. For the buttons, you use change handlers.I’ve mapped the A button on the controller to the A button in the HUD and the X button on the controller to the B button in the HUD. This is the most comfortable way to use both dash and jump on the physical control.
- If the method is passed
NO
, you reset the alpha property to 1.0 (revealing the HUD) and set thecontroller
property tonil
.
Now that you have that method in place, it’s time to connect to a controller. First, you will handle the case when a controller is already connected when the app starts. Make sure your bluetooth enables controller is paired with your device or plug your lightning connected controller in (when it’s time to test again).
Find the comment ‘//Add hardware controller code here’ in initWithSize and add this code:
if ([[GCController controllers] count]) {
[self toggleHardwareController:YES];
}
This will check for any existing controllers and if it finds one or more, it will run the method you just added.
Note: If you have a controller that connects to the lightning cable, testing gets tricky because you have to disconnect your Xcode connected cable to plug your controller in. So, from now on, testing will be several steps:
You won’t be able to get logs in that case either, so you may need to create a logging SKLabelNode or do something else to debug issues. You won’t be relying on any specific NSLog statements in this tutorial, but if you get stuck or need to debug something, you won’t be able to do that with a lightning connected controller. If you have a bluetooth controller this will be easier.
- Build and run.
- Disconnect from your Mac.
- Connect the controller.
- Run your app by tapping on it.
Note: If you have a controller that connects to the lightning cable, testing gets tricky because you have to disconnect your Xcode connected cable to plug your controller in. So, from now on, testing will be several steps:
- Build and run.
- Disconnect from your Mac.
- Connect the controller.
- Run your app by tapping on it.
You won’t be able to get logs in that case either, so you may need to create a logging SKLabelNode or do something else to debug issues. You won’t be relying on any specific NSLog statements in this tutorial, but if you get stuck or need to debug something, you won’t be able to do that with a lightning connected controller. If you have a bluetooth controller this will be easier.
Go ahead and connect your controller and run the app. The HUD should be gone and you should be able to dash and jump using the buttons.