Reputation:
I have 3 SKScenes in SpriteKit, Swift:
Level 1
Game Over
In Level 1 and Level 2, my character movement is done by the following code:
class Level1: SKScene, SKPhysicsContactDelegate {
func swipedRight(sender:UISwipeGestureRecognizer){
let moveRIGHT = SKAction.moveBy(CGVectorMake(60, 0), duration: 1)
Character.runAction(moveRIGHT)
}
func swipedLeft(sender:UISwipeGestureRecognizer){
let moveLEFT = SKAction.moveBy(CGVectorMake(-60, 0), duration: 1)
Character.runAction(moveLEFT)
}
let swipeRight:UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: Selector("swipedRight:"))
swipeRight.direction = .Right
view.addGestureRecognizer(swipeRight)
let swipeLeft:UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: Selector("swipedLeft:"))
swipeLeft.direction = .Left
view.addGestureRecognizer(swipeLeft)
And when the character dies in Level 1, I transition to the "Game Over" SKScene where you can retry Level 1 if you'd like.
However after going back and forth between Level 1 - Game Over - Level 1 - Game Over - Level 1 - Game Over etc, the FPS dramatically drops whenever you do a UISwipeGesture on Level 1 AND Level 2.
I then decided to remove the UISwipeGestureRecognizer from Level 1, and then purposely go back and forth between Level 1 and Game Over, and then go to Level 2. There was no FPS drop when using UISwipeGestures in Level 2 after doing this.
Therefore, my conclusion is that whenever I load a SKScene with the UISwipeGestureRecognizer over and over again, it creates this FPS drop whenever you try and initiate a swipe.
So: 1) Am I implementing this UISwipeGestureRecognizer wrongly?
2) Is there another way I can get the same effect of character movement without using UISwipeGestureRecognizer?
Thanks heaps guys!
Upvotes: 0
Views: 148
Reputation: 10674
You need to remove the gestures before transitioning to a new scene, otherwise the same gestures keep getting added over and over again which causes the FPS issues. If you for example would have different gestures in level 2 scene than level 1 scene your game will crash because the old level1 gestures have not been removed. Try this before changing scenes
guard let view = view else { return }
guard view.gestureRecognizers != nil else { return }
for gesture in view.gestureRecognizers! {
if let recognizerTap = gesture as? UITapGestureRecognizer {
view.removeGestureRecognizer(recognizerTap)
}
if let recognizerSwipe = gesture as? UISwipeGestureRecognizer {
view.removeGestureRecognizer(recognizerSwipe)
}
}
Also to make your live easier you should probably start subclassing. Consider making a BaseScene class which houses all the properties, controls, player sprite, labels etc that you show in all level scenes. Otherwise if you for example have 20 levels you need to copy way too much code. Its super simple
Make a BaseScene like so
class BaseScene: SKScene, SKPhysicsContactDelegate {
and just set up the gestures and all the stuff you need for all your levels in the ViewDidLoad method. Also use baseScene for your contact methods and other stuff you need shared between levels (gameOver method etc)
Than in your level scenes you should subclass them like so
class Level1Scene: BaseScene {
override func didMoveToView(view: SKView) {
super.didMoveToView(view) // imports everything from ViewDidLoad in base scene
// do other setUps specific to level 1 only
This wil make you code way more flexible. Say you use the Update func in BaseScene to pause the game, it will work in subclass level scenes as described above. But for example if in Level2 you need to add a method to the Update func that only runs in Level2 you can do something similar to the ViewDidLoad method. So in your Level 2 scene you could say this
override func update(currentTime: CFTimeInterval) {
super.update(currentTime) // will use all BaseScene update methods
// do something specific for level 2 only
Now if you want something in update that only runs in Level2 scene and ignores all the update Methods in BaseScene than you simply dont call
super.update(currentTime)
This applies to almost all methods, like the contact methods, touches began etc. Its the way to go.
Upvotes: 2