简体   繁体   中英

Move object while holding button in Swift

I have a little Space Invaders game and I added two buttons leftButton and rightButton and I want the ship to move as long as one of the buttons is touched AND HELD in the proper direction.

I made it move in the right direction but I have to tap the button repeatedly, but I want ship to move WHILE the player is holding the button.

For simplicity I only posted code for the left button as I believe the way to code the other button is identical:

class GameScene: SKScene {
   var leftButton = SKSpriteNode()
   var ship = SKSpriteNode()

   override func didMove(to view: SKView) {
       leftButton = self.childNode(withName: "left") as! SKSpriteNode
       ship = self.childNode(withName: "player") as! SKSpriteNode
   }

   override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
       for touch: AnyObject in touches {
           let pointTouched = touch.location(in: self)

           if leftButton.contains(pointTouched) {
               player.position.x -= 30
           }
      }
   }
}

Use an Action for that. There are other ways to implement this, but this will work for you.

First add a func moveBy that takes the direction you want your ship to go and a key: String . You will use these in your touchesBegan later.

func moveShip (moveBy: CGFloat, forTheKey: String) {
    let moveAction = SKAction.moveBy(x: moveBy, y: 0, duration: 1)
    let repeatForEver = SKAction.repeatForever(moveAction)
    let seq = SKAction.sequence([moveAction, repeatForEver])

    //run the action on your ship
    player.run(seq, withKey: forTheKey)
}

TouchesBegan:

        if leftButton.contains(pointTouched) {
            moveShip(moveBy: -30, forTheKey: "left")
        }

        if rightButton.contains(pointTouched) {
            moveShip(moveBy: 30, forTheKey: "right")
        }

EDIT:

touchesEnded:

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    player.removeAction(forKey: "left")
    player.removeAction(forKey: "right")
}

You can use SKAction for that: `

class GameScene: SKScene {
  var leftButton = SKSpriteNode()
  var ship = SKSpriteNode()
       let Left = SKAction.repeatForever(
        SKAction.sequence([
            SKAction.wait(forDuration: 0.5),
            SKAction.run({
              SKAction.move(by: CGVector(dx: -30, dy: 0), duration:0.5)
            }  )]))
 //This SKAction will repeat it self forever, until the action is removed. It's build from a sequence of to other actions, move and wait.
  override func didMove(to view: SKView) {
      leftButton = self.childNode(withName: "left") as! SKSpriteNode
     ship = self.childNode(withName: "player") as! SKSpriteNode
   }

  override func touchesBegan(_ touches: Set<UITouch>, with event:UIEvent?) {
      for touch: AnyObject in touches {
          let pointTouched = touch.location(in: self)

          if leftButton.contains(pointTouched) {
         self.run(Left, withKey: "left")
    //Keys will help you remove actions, as well as to remove certain actions, sorting them by group
          }
    }
 }
     override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?)   {
    self.removeAction(forKey: "left")

}
     }

UPDATE The way you code your button is really weird I do it this way and it always works: `

 if let touch = touches.first{
          let pos = touch.location(in: self)
          let node = self.atPoint(pos)
          if node == button {

              if let view = view {

                   //your code

            }

         }}

`

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM