【问题标题】:Swift 3 Bullet Firing DelaySwift 3 子弹发射延迟
【发布时间】:2017-01-24 20:12:33
【问题描述】:

在我的游戏中,你点击屏幕上的任意位置,子弹就会朝那个方向飞去。唯一的问题是你可以尽可能快地拍摄。有什么办法可以在每次拍摄后添加延迟。所以我想拍,等1秒再拍。这是我在 touchesEnded 中的代码:

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {

    guard let touch = touches.first else {
        return
    }
    let touchLocation = touch.location(in: self)

    //Set up initial location of bullet and properties
    let bullet = SKSpriteNode(imageNamed: "bullet")
    bullet.name = "Bullet"
    bullet.position = player.position
    bullet.setScale(0.75)
    bullet.zPosition = 1
    bullet.physicsBody = SKPhysicsBody(circleOfRadius: bullet.size.width/2)
    bullet.physicsBody?.isDynamic = true
    bullet.physicsBody?.categoryBitMask = PhysicsCategory.Projectile
    bullet.physicsBody?.contactTestBitMask = PhysicsCategory.Monster
    bullet.physicsBody?.collisionBitMask = PhysicsCategory.None
    bullet.physicsBody?.usesPreciseCollisionDetection = true

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

    //Stops Bullet from shooting backwards
    if (offset.y < 0) { return }

    addChild(bullet)

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

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

    //Add the shoot amount to the current position
    let realDest = shootAmount + bullet.position

    //Create the actions

    if currentGameState == gameState.inGame {
    let actionMove = SKAction.move(to: realDest, duration: 1.0)
    let actionMoveDone = SKAction.removeFromParent()
    bullet.run(SKAction.sequence([actionMove, actionMoveDone]))
    }

}

感谢您的帮助。

【问题讨论】:

  • 发射子弹时启动计时器。在下一次触摸时,检查计时器是否已经过了一秒。如果有,拍摄并重新启动计时器,否则忽略。
  • 这很简单,可以通过多种方式完成。一种方法是使用键运行操作。所以,你发射一颗子弹,然后对一个玩家执行一个持续一秒钟的动作,这意味着你的射击被锁定。因此,每次您尝试发射子弹时,您都会检查此操作键是否存在于特定节点上。
  • 我有机会获得这两种方法的代码吗?对不起,这里是初学者

标签: swift sprite-kit delay projectile


【解决方案1】:

这是一种更简单的方法,基于 Date 的使用:

var time = Date()

func shoot(after timeInterval: Double) {
    guard Date() - timeInterval > time else {
        print("WAIT")
        return
    }
    print("SHOOT")
    time = Date() // reset the timer
}

// CALL THIS INSIDE touchesEnded
shoot(after: 1)

只需根据您的需要进行修改:]

【讨论】:

  • 那么我是否要创建变量“时间”然后创建这个函数,然后我在哪里将拍摄(之后:1)放在我的触摸结束函数中?感谢您的帮助
  • 我把所有东西都放进去了,但还是一样。我觉得我很愚蠢。
【解决方案2】:

您可以查看RxSwiftThrottle 实现,以获得一种可能的解决方案。 Throttle 用于限制在定义的时间间隔内创建的事件数量:

let timeIntervalSinceLast: RxTimeInterval

if let lastSendingTime = _lastSentTime {
   timeIntervalSinceLast = now.timeIntervalSince(lastSendingTime)
}
else {
   timeIntervalSinceLast = _parent._dueTime
}

let couldSendNow = timeIntervalSinceLast >= _parent._dueTime

if couldSendNow {
   self.sendNow(element: element)
   return
}

【讨论】:

    【解决方案3】:

    您可以使用操作键来执行此操作。操作键是使操作可识别的字符串。

    这种情况下如何使用?

    正如我在 cmets 中已经说过的,您将发射子弹,然后在特定节点上使用键运行一个动作,该动作将持续一秒钟。这个键/动作的存在意味着武器被锁定。因此,每次尝试发射子弹时,都要检查此密钥是否存在于特定节点上。操作完成后,密钥也将自动删除。代码如下:

    import SpriteKit
    
    let kLockWeaponActionKey = "kLockWeaponActionKey"
    
    class GameScene: SKScene {
    
    
        func shoot(atPoint targetLocation:CGPoint){
    
            // 1 check if weapon is unlocked, or return
            guard self.action(forKey: kLockWeaponActionKey) == nil else {
    
                print("Weapon locked")
    
                return
            }
    
            let bullet = SKSpriteNode(color: .purple, size: CGSize(width: 20, height: 20))
    
            addChild(bullet)
    
            let shoot = SKAction.move(to: targetLocation, duration: 3)
    
            //2 shoot
            bullet.run(shoot)
    
            //3 lock weapon
            self.run(SKAction.wait(forDuration: 1), withKey: kLockWeaponActionKey)
        }
    
        override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    
            if let touch = touches.first {
    
                let targetLocation = touch.location(in: self)
    
                self.shoot(atPoint:targetLocation)
    
            }
        }
    }
    

    如果您尝试快速发送垃圾邮件,您会在控制台中看到一条日志:“武器已锁定”。

    【讨论】:

      猜你喜欢
      • 2017-07-05
      • 2020-10-12
      • 1970-01-01
      • 1970-01-01
      • 2017-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-08
      相关资源
      最近更新 更多