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

Sam*_*ent 6 timer ios sprite-kit swift

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

这是我的代码;

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..........
Run Code Online (Sandbox Code Playgroud)

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

// *** 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)


      })
Run Code Online (Sandbox Code Playgroud)

Ste*_*ves 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
    }
}
Run Code Online (Sandbox Code Playgroud)

update(),调用你的函数标志为真:

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

   if rightButtonIsPressed == true {
        moveRight()
    }

}
Run Code Online (Sandbox Code Playgroud)

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
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:

正如KoD所指出的那样,一种更简洁的方法(用于移动按钮)SKAction可以消除对标志的需求:

  1. 定义SKActionsfor moveTo x:0moveTo x:frame.widthin didMoveTo(View:)
  2. touchesBegan,在正确的对象上运行正确的SKAction,指定SKAction的键.
  3. touchesEnded,删除相关的SKAction.

您必须做一些数学计算您的对象将要移动的点数,然后根据此距离和移动速度(以每秒点数为单位)设置SKAction的持续时间.

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

  • 你得到了我的投票,但我甚至不打扰旗帜,只是在触摸开始时分配一个重复永远的动作,并删除触摸结束/触摸取消的动作 (2认同)
  • 不要移动,移动,移动到基于距离的不一致移动 (2认同)