tutorial - xcode game教學



替代UISwipeGestureRecognizer? (1)

在SpriteKit中有3個SKScenes,Swift:

  • 1級

  • 遊戲結束

  • 2級。

在1級和2級,我的角色移動是由以下代碼完成的:

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)

當角色死於1級時,我轉換到“遊戲結束”SKScene,如果您願意,可以重試1級。

然而,當在1級 - 遊戲結束 - 1級 - 遊戲結束 - 1級 - 遊戲結束等之間來回移動時,無論何時在1級和2級上進行UISwipeGesture,FPS都會大幅下降。

然後,我決定從Level 1中刪除UISwipeGestureRecognizer,然後有意地在Level 1和Game Over之間來回切換,然後轉到Level 2.在這樣做之後,在Level 2中使用UISwipeGestures時沒有FPS丟棄。

因此,我的結論是,每當我一次又一次地加載一個帶有UISwipeGestureRecognizer的SKScene,每當你嘗試並開始一個滑動時,它就會創建這個FPS。

所以:1)我是否錯誤地實現了這個UISwipeGestureRecognizer?

2)是否有另一種方法可以在不使用UISwipeGestureRecognizer的情況下獲得相同的角色移動效果?

感謝堆傢伙!


在轉換到新場景之前,您需要刪除手勢,否則相同的手勢會一再重複添加,從而導致FPS問題。 例如,如果您在二級場景中的手勢與一級場景中的手勢不同,則您的遊戲將因為舊的level1手勢未被移除而崩潰。 在改變場景之前試試這個

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)
    }
 }

也為了讓你的生活更輕鬆,你應該開始繼承。 考慮製作一個BaseScene類,其中包含您在所有關卡場景中顯示的所有屬性,控件,玩家精靈,標籤等。 否則,如果你例如有20個級別,你需要復制太多的代碼。 它超級簡單

像這樣做一個BaseScene

 class BaseScene: SKScene, SKPhysicsContactDelegate {

只需在ViewDidLoad方法中設置所有級別所需的手勢和所有東西即可。 還可以使用baseScene為您的聯繫方式和其他你需要的級別之間共享的東西(gameOver方法等)

在你的關卡場景中,你應該像這樣子類化它們

  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

這將使你的代碼更靈活。 假設您使用BaseScene中的更新功能來暫停遊戲,它將在上述的子類級別場景中工作。 但是,例如,如果在Level2中需要將方法添加到僅在Level2中運行的Update func,則可以執行類似於ViewDidLoad方法的操作。 所以在你的二級場景中你可以這樣說

 override func update(currentTime: CFTimeInterval) {
     super.update(currentTime) // will use all BaseScene update methods

    // do something specific for level 2 only

現在,如果你想要更新的東西,只能在Level2場景中運行,並忽略BaseScene中的所有更新方法,而不是簡單地調用

 super.update(currentTime)

這適用於幾乎所有的方法,如聯繫方式,觸摸開始等它的路要走。





sprite-kit