In this post, we covered how to move an object on the screen; this time, we’re going to control it. However, before we do, let’s change the game orientation to landscape only, as that’s really the only thing that makes sense on an iPhone for this type of game.
Landscape
The first thing to do is to change the code in the GameViewController to force the orienetation to landscape:
override var shouldAutorotate: Bool {
return true
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
if UIDevice.current.userInterfaceIdiom == .phone || UIDevice.current.userInterfaceIdiom == .pad {
return .landscape
} else {
return .all
}
}
When you run the simulator, the game will now appear on its side; to rectify that, select Hardware -> Rotate Left*:
Control
As you may have noticed from the previous post, we do have a modicum of control over the rectangle; let’s now change that so that we can press to the left and have it move left, or on the right and have it move right.
Left and Right
It turns out that this is pretty easy once you understand how the co-ordinates work in Swift:
override func touchesBegan(\_ touches: Set<UITouch>, with event: UIEvent?) {
for t in touches {
self.touchDown(atPoint: t.location(in: player!))
}
}
And the touchDown function:
func touchDown(atPoint pos : CGPoint) {
print (pos.x, pos.y)
var halfWidth = (player?.frame.width)! / 2;
if (pos.x < -halfWidth) {
playerSpeed? -= CGFloat(1.0);
} else if (pos.x > halfWidth) {
playerSpeed? += CGFloat(1.0);
}
}
Finally, we need the update event to do something with the playerSpeed:
override func update(\_ currentTime: TimeInterval) {
// Called before each frame is rendered
player?.position.x += playerSpeed!
}
Now we have a game where we can move the player left and right.
Tidy up
To clean up the screen before we get into firing, it would be nice if the player was lower down the screen, and a slightly different colour:
func CreatePlayer() -> SKShapeNode {
let playerSize = CGSize(width: 100, height: 10)
let player = SKShapeNode(rectOf: playerSize)
print(self.frame.minY, self.frame.maxY, self.frame.minX, self.frame.maxX, self.frame.width, self.frame.height)
player.position = CGPoint(x:self.frame.midX, y:-150)
player.strokeColor = SKColor(red: 0.0/255.0, green: 0.0/255.0, blue: 200.0/255.0, alpha: 1.0)
player.lineWidth = 1
player.physicsBody = SKPhysicsBody(rectangleOf: playerSize)
player.physicsBody?.affectedByGravity = false
player.physicsBody?.isDynamic = true
return player
}
Remember, this is a landscape only game.
Fire
Okay - so firing is just an extra clause in our touchDown function:
func touchDown(atPoint pos : CGPoint) {
print (pos.x, pos.y)
var halfWidth = (player?.frame.width)! / 2;
if (pos.x < -halfWidth) {
playerSpeed? -= CGFloat(1.0);
} else if (pos.x > halfWidth) {
playerSpeed? += CGFloat(1.0);
} else {
Fire()
}
}
func Fire() {
let bullet = CreateBullet(point: (player?.position)!)
self.addChild(bullet)
}
func CreateBullet(point : CGPoint) -> SKShapeNode {
let bulletSize = CGSize(width: 1, height: 10)
let bullet = SKShapeNode(rectOf: bulletSize)
//print(self.frame.minY, self.frame.maxY, self.frame.minX, self.frame.maxX, self.frame.width, self.frame.height)
bullet.position = point
bullet.strokeColor = SKColor(red: 0.0/255.0, green: 0.0/255.0, blue: 200.0/255.0, alpha: 1.0)
bullet.lineWidth = 4
bullet.physicsBody = SKPhysicsBody(rectangleOf: bulletSize)
bullet.physicsBody?.affectedByGravity = false
bullet.physicsBody?.isDynamic = true
bullet.name = "bullet"
return bullet
}
All we’ve actually done here is to create a new rectangle, and sourced it right at the centre of the player. We’ve added it to the self construct, so the automatic rendering will pick it up; next, we need to move it:
override func update(\_ currentTime: TimeInterval) {
// Called before each frame is rendered
player?.position.x += playerSpeed!
self.enumerateChildNodes(withName: "bullet") {
(node, \_) in
node.position.y += 1
}
}
Footnotes
* Remember, when holding an iPhone or iPad, the button should always be on the right hand side - without wishing to judge, anyone that feels different is wrong, and very possibly evil.
References
https://stackoverflow.com/questions/475553/how-can-i-test-landscape-view-using-the-iphone-simulator