Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
299 views
in Technique[技术] by (71.8m points)

ios - How to make a Button continually call a function when held down (SpriteKit)

I'm making a game using sprite kit and I want my Character to move across the screen when you hold down the left/right move button. The problem is that he only moves when the button is tapped, not held. I have looked everywhere for a solution but nothing seems to work!

Here's my code;

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..........

In my game scene...

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


      })
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You know when the button is touched because touchesBegan is called. You then have to set a flag to indicate that the button is pressed.

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

In update(), call your function that flag is true:

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

   if rightButtonIsPressed == true {
        moveRight()
    }

}

You set the flag to false when touchesEnded is called for that button:

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

Edit:

As pointed out by KoD, a cleaner way to do this (for movement buttons) is with SKAction which removes the need for the flag:

  1. Define SKActions for moveTo x:0 and moveTo x:frame.width in didMoveTo(View:)
  2. In touchesBegan, run the correct SKAction on the correct object specifying a key for the SKAction.
  3. In touchesEnded, remove the relevant SKAction.

You'll have to do some maths to calculate how many points your object will have to move and then set a duration for the SKAction based upon this distance and a movement speed (in points per second).

Alternatively, (thanks to KnightOfDragons for this) create a SKAction.MoveBy x: which moves a small distance (based upon your desired movement speed) and with a duration of 1/60s. Repeat this action forever (SKAction.repeatForever) when the button is touched and remove the repeating SKAction when the button is released.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...