Polling for device movement with Core Motion
Apple provides the Core Motion framework to expose precise information on the iOS device's orientation in physical space. We can use this data to move our player on the screen when the user tilts their device in the direction they want to move. This unique style of input offers new gameplay mechanics in mobile games.
You will need a physical iOS device for this Core Motion section. The iOS simulator in Xcode does not simulate device movement. However, this section is only a learning exercise and is not required to finish the game we are building. Our final game will not use Core Motion. Feel free to skip the Core Motion section if you cannot test with a physical device.
Implementing the Core Motion code
It is very easy to poll for device orientation. We will check the device's position during every update and apply the appropriate force to our player. Follow these steps to implement the Core Motion controls:
- In
GameScene.swift
, near the very top, add a newimport
statement after theimport SpriteKit
line:import CoreMotion
- Inside the
GameScene
class, add a new constant namedmotionManager
and instantiate an instance ofCMMotionManager
:let motionManager = CMMotionManager()
- Inside the
GameScene
class'sdidMove
function, add the following code at the bottom. This lets Core Motion know that we want to poll the orientation data, so it needs to start reporting data:self.motionManager.startAccelerometerUpdates()
- Finally, add the following code to the bottom of the
update
function to poll the orientation, build an appropriate vector, and apply a physical force to the player's character:// Unwrap the accelerometer data optional: if let accelData = self.motionManager.accelerometerData { var forceAmount: CGFloat var movement = CGVector() // Based on the device orientation, the tilt number // can indicate opposite user desires. The // UIApplication class exposes an enum that allows // us to pull the current orientation. // We will use this opportunity to explore Swift's // switch syntax and assign the correct force for the // current orientation: switch UIApplication.shared.statusBarOrientation { case .landscapeLeft: // The 20,000 number is an amount that felt right // for our example, given Pierre's 30kg mass: forceAmount = 20000 case .landscapeRight: forceAmount = -20000 default: forceAmount = 0 } // If the device is tilted more than 15% towards // vertical, then we want to move the Penguin: if accelData.acceleration.y> 0.15 { movement.dx = forceAmount } // Core Motion values are relative to portrait view. // Since we are in landscape, use y-values for x-axis. else if accelData.acceleration.y< -0.15 { movement.dx = -forceAmount } // Apply the force we created to the player: player.physicsBody?.applyForce(movement) }
Run the project. You can slide Pierre across the ice by tilting your device in the direction you want to move. Great work—we have successfully implemented our first control system.
Note
Notice that Pierre falls through the ground when you move him too far in any direction. Later in this chapter, we will improve the ground, continuously repositioning it to cover the area beneath the player.
This is a simple example of using Core Motion data for player movement; we are not going to use this method in our final game. Still, you can extrapolate this example into advanced control schemes in your own games.
Note
Checkpoint 4-A
The code up to this point is available in this chapter's code resources.