按住时如何使Button不断调用函数(SpriteKit)

时间:2016-12-19 10:04:53

标签: ios swift timer sprite-kit

我正在使用精灵套件制作游戏,当您按住左/右移动按钮时,我希望我的角色在屏幕上移动。问题是他只在轻敲按钮时移动,而不是按住。我到处寻找解决方案,但似乎没有任何效果!

这是我的代码;

class Button: SKNode
{
   var defaultButton: SKSpriteNode // defualt state
   var activeButton: SKSpriteNode  // active state

   var timer = Timer()

   var action: () -> Void

   //default constructor
   init(defaultButtonImage: String, activeButtonImage: String, buttonAction: @escaping () -> Void )
   {
      //get the images for both button states
      defaultButton = SKSpriteNode(imageNamed: defaultButtonImage)
      activeButton = SKSpriteNode(imageNamed: activeButtonImage)

      //hide it while not in use
      activeButton.isHidden = true 
      action = buttonAction

      super.init()

      isUserInteractionEnabled = true

      addChild(defaultButton)
      addChild(activeButton)    
   }

   //When user touches button
   override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?)
   {
      action()

      //using timer to repeatedly call action, doesnt seem to work...
      self.timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(getter: Button.action), userInfo: nil, repeats: true)

      //swtich the image of our button
      activeButton.isHidden = false
      defaultButton.isHidden = true

   }

   code..........

在我的游戏场景中......

// *** RIGHT MOVEMENT ***
      let rightMovementbutton = Button(defaultButtonImage: "arrow", activeButtonImage: "arrowActive", buttonAction:
      {

         let moveAction = SKAction.moveBy(x: 15, y: 0, duration: 0.1)
         self.player.run(moveAction)


      })

1 个答案:

答案 0 :(得分:6)

您知道何时触摸按钮,因为调用了touchesBegan。然后,您必须设置一个标志以指示按下按钮。

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    let touch = touches.first!
    if leftButton.containsPoint(touch.locationInNode(self)) {
        leftButtonIsPressed = true
    }
    if rightButton.containsPoint(touch.locationInNode(self)) {
        rightButtonIsPressed = true
    }
}

update()中,将您的函数调用为标志为真:

update() {
   if leftButtonIsPressed == true {
        moveLeft()
    }

   if rightButtonIsPressed == true {
        moveRight()
    }

}

在为该按钮调用touchesEnded时,将标志设置为false:

override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
    let touch = touches.first!
    if leftButton.containsPoint(touch.locationInNode(self)) {
        leftButtonIsPressed = false
    }
    if rightButton.containsPoint(touch.locationInNode(self)) {
        rightButtonIsPressed = flase
    }
}

修改

正如KoD所指出的那样,一种更简洁的方法(用于移动按钮)是SKAction,它不需要标志:

  1. SKActionsmoveTo x:0定义moveTo x:frame.width didMoveTo(View:)
  2. touchesBegan中,在正确的对象上运行正确的SKAction 指定SKAction的密钥。
  3. touchesEnded中,删除相关的SKAction。
  4. 你必须做一些数学计算你的物体必须移动多少点,然后根据这个距离和移动速度(以每秒点数计)设置SKAction的持续时间。

    或者,(感谢KnightOfDragons)创建一个SKAction.MoveBy x:,移动一小段距离(根据你想要的移动速度),持续时间为1/60秒。触摸按钮时永远重复此操作(SKAction.repeatForever),并在释放按钮时删除重复的SKAction。