Introduction
In the previous chapter, I started talking about the video game creation process, from project setup to adding the background. Now, I’m going to add the player and physics to it.
You can download the project here.
First Step
The first step is to initialize player
using SKSpriteNode
, set up player.position
, and add player
as a child node.
SKSpriteNode - is an onscreen graphical element that can be initialized from an image or a solid color.
self.player = SKSpriteNode(imageNamed: "shuttle")
player.position = CGPoint(x: self.frame.size.width / 2, y: player.size.height / 2 + 20)
self.addChild(player)
Second Step
The second step is to remove Earth’s gravity effect from the physics world, because the player will be looking into the screen from a top-down perspective and gravity effects make no difference for it.
self.physicsWorld.gravity = CGVector(dx: 0, dy: 0)
Third Step
The third step is to add contactDelegate
to be able to respond when physics bodies come into contact.
SKPhysicsContactDelegate - An object that implements the SKPhysicsContactDelegate protocol can respond when two physics bodies with overlapping
contactTestBitMask
values are in contact with each other in a physics world. You can use the contact delegate to play a sound or execute game logic, such as increasing a player’s score when a contact event occurs.
self.physicsWorld.contactDelegate = self
private let alienCategory: UInt32 = 0x1 << 1
private let photonTorpedoCategory: UInt32 = 0x1 << 0
alien.physicsBody?.categoryBitMask = alienCategory
alien.physicsBody?.contactTestBitMask = photonTorpedoCategory
alien.physicsBody?.collisionBitMask = 0
torpedoNode.physicsBody?.categoryBitMask = photonTorpedoCategory
torpedoNode.physicsBody?.contactTestBitMask = alienCategory
torpedoNode.physicsBody?.collisionBitMask = 0
torpedoNode.physicsBody?.usesPreciseCollisionDetection = true
// MARK: - SKPhysicsContactDelegate
extension GameScene: SKPhysicsContactDelegate {
func didBegin(_ contact: SKPhysicsContact) {
var firstBody: SKPhysicsBody
var secondBody: SKPhysicsBody
if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
firstBody = contact.bodyA
secondBody = contact.bodyB
} else {
firstBody = contact.bodyB
secondBody = contact.bodyA
}
if (firstBody.categoryBitMask & photonTorpedoCategory) != 0 && (secondBody.categoryBitMask & alienCategory) != 0 {
torpedoDidCollideWithAlien(torpedoNode: firstBody.node as! SKSpriteNode, alienNode: secondBody.node as! SKSpriteNode)
}
}
}
didBegin(_:)
is an instance method called when two bodies first contact each other.
Additionally
We need to add scoreLabel
to track the player’s score:
self.scoreLabel = SKLabelNode(text: "Score: 0")
scoreLabel.position = CGPoint(x: self.frame.size.width / 2, y: self.frame.size.height - 50)
scoreLabel.fontName = "AmericanTypewriter-Bold"
scoreLabel.fontSize = 36
scoreLabel.fontColor = UIColor.white
score = 0
self.addChild(scoreLabel)
gameTimer
to add an alien every 0.75 milliseconds:
self.gameTimer = Timer.scheduledTimer(timeInterval: 0.75, target: self, selector: #selector(addAlien), userInfo: nil, repeats: true)
motionManager
to change the user’s position using the accelerometer:
self.motionManager = CMMotionManager()
motionManager.accelerometerUpdateInterval = 0.1
motionManager.startAccelerometerUpdates(to: OperationQueue.current!) { (data: CMAccelerometerData?, error: Error?) in
if let accelerometerData = data {
let acceleration = accelerometerData.acceleration
self.xAcceleration = CGFloat(acceleration.x) * 0.75 + self.xAcceleration * 0.25
}
}
touchesEnded
method to fire a torpedo:
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
fireTorpedo()
}
didSimulatePhysics
method to change the player’s position:
override func didSimulatePhysics() {
player.position.x += xAcceleration * 50
if player.position.x < 0 {
player.position = CGPoint(x: self.frame.size.width, y: player.position.y)
} else if player.position.x > self.frame.size.width {
player.position = CGPoint(x: 0, y: player.position.y)
}
}
Summarizing
It was an amazing experience. I was surprised that the entire game was less than 200 lines of code. I tried my best to create a step-by-step instruction of the game creation process. I hope this article will be helpful for you.