简体   繁体   中英

How can I move a sprite while simultaneously firing a projectile in SpriteKit?

I am trying to write some logic using Swift 4 and SpriteKit to allow the user to move the spaceship around using a drag action while also allowing them to shoot a projectile. I can drag the spaceship around with my left thumb, but once I begin shooting with my right thumb by tapping, the spaceship stops moving.

I have enabled 'enableMultiTouch' in the viewDidLoad(). I feel as though I am very close to having this working, I am just missing a piece to allow a user to do both at the same time. Thanks in advance.

Here is what I have so far:

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

    if player.contains(touchLocation) {
      playerIsTouched = true
    } else {
      // 2 - Set up initial location of projectile
      let projectile = SKSpriteNode(imageNamed: "projectile")
      projectile.position = player.position

      projectile.physicsBody = SKPhysicsBody(circleOfRadius: projectile.size.width/2)
      projectile.physicsBody?.isDynamic = true
      projectile.physicsBody?.categoryBitMask = PhysicsCategory.projectile
      projectile.physicsBody?.contactTestBitMask = PhysicsCategory.monster
      projectile.physicsBody?.collisionBitMask = PhysicsCategory.none
      projectile.physicsBody?.usesPreciseCollisionDetection = true

      // 3 - Determine offset of location to projectile
      let offset = touchLocation - projectile.position

      // 4 - Bail out if you are shooting down or backwards
      if offset.x < 0 {
        return
      } else {
        run(SKAction.playSoundFileNamed("laser-shot-basic.wav", waitForCompletion: false))
        shotsFired += 1
        accuracyLabel.text = "\(trunc((shotsHit/shotsFired*100) * 10)/10)% Accuracy"
      }

      // 5 - OK to add now - you've double checked position
      addChild(projectile)

      // 6 - Get the direction of where to shoot
      let direction = offset.normalized()

      // 7 - Make it shoot far enough to be guaranteed off screen
      let shootAmount = direction * 1000

      // 8 - Add the shoot amount to the current position
      let realDest = shootAmount + projectile.position

      // 9 - Create the actions
      let actionMove = SKAction.move(to: realDest, duration: 2.0)
      let actionMoveDone = SKAction.removeFromParent()
      projectile.run(SKAction.sequence([actionMove, actionMoveDone]))
    }

    if pauseButton.contains(touchLocation) {

      run(gameLostSound, completion: {
        let scene = LevelSelectScene(size: self.size)
        self.view?.presentScene(scene)
      })


    }
//    for touch: AnyObject in touches {
//      let pointOfTouch = touch.location(in: self)
//      let previousPointOfTouch = touch.previousLocation(in: self)
//
//      let amountDragged = pointOfTouch.x - previousPointOfTouch.x
//
//      player.position.x += amountDragged
//    }

  }

  override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    if (playerIsTouched == true) {
      player.position = (touches.first?.location(in: self))!
    }
  }

  override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    // 1 - Choose one of the touches to work with
    guard let touch = touches.first else {
      return
    }
    let touchLocation = touch.location(in: self)


    if playerIsTouched {
      playerIsTouched = false
    }

  }

When you tap-to-fire that will cause two events: a 'begins' and an 'ends' event. However your touchesEnded method does not distinguish which touch has just ended, and sets your playerIsTouched parameter to false, thus further movement ceases.

There are multiple ways of fixing this, depending on the larger and future structure of the app, but one way would be: in touchesEnded , use the location of the touch to determine whether it is the drag touch that has ended and only reset playerIsTouched if that is the case.

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