在 SpriteKit 中为函数添加延迟

Posted

技术标签:

【中文标题】在 SpriteKit 中为函数添加延迟【英文标题】:Add a delay to a function in SpriteKit 【发布时间】:2017-01-26 19:50:38 【问题描述】:

我希望只允许玩家每 0.7 秒发射一枚导弹。我该怎么做呢?这是我的代码。我已尝试在此站点上找到的其他方法,但它们不起作用。

func fireTorpedo() 
    if !self.player.isPaused
    
        if isSoundEffect == true 
            self.run(SKAction.playSoundFileNamed("Rocket", waitForCompletion: false))
        

        let torpedoNode = SKSpriteNode(imageNamed: "Rocket")

        torpedoNode.position = player.position
        torpedoNode.position.y += 5
        torpedoNode.physicsBody = SKPhysicsBody(circleOfRadius: torpedoNode.size.width / 2)
        torpedoNode.physicsBody?.isDynamic = true
        torpedoNode.physicsBody?.categoryBitMask = photonTorpedoCategory
        torpedoNode.physicsBody?.contactTestBitMask = alienCategory
        torpedoNode.physicsBody?.collisionBitMask = 0
        torpedoNode.physicsBody?.usesPreciseCollisionDetection = true

        self.addChild(torpedoNode)

        let animationDuration:TimeInterval = 0.5
        var actionArray = [SKAction]()
        actionArray.append(SKAction.move(to: CGPoint(x: player.position.x, y: self.frame.size.height + 10), duration: animationDuration))
        actionArray.append(SKAction.removeFromParent())
        torpedoNode.run(SKAction.sequence(actionArray))
    

【问题讨论】:

发生这种情况的背景是什么?什么代码调用fireTorpedo() 【参考方案1】:

我喜欢这样做:

class GameScene:SKScene 

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) 
        super.touchesBegan(touches, with: event)

        if action(forKey: "shooting") == nil 

            let wait = SKAction.wait(forDuration: 0.7)
            run(wait, withKey: "shooting")

            print("shot fired")
        
    

虽然在场景中发现了关键的“拍摄”,但您不能再拍摄了。在实际游戏中,这很可能是节点的一部分(动作应该在节点上运行)。

【讨论】:

【参考方案2】:

首先,在职业级别添加一个标志,指示玩家是否可以发射鱼雷。

var canFireTorpedo = true

然后,在fireTorpedo方法结束时,将canFireTorpedo设置为false,然后在0.7秒后再次设置为true:

canFireTorpedo = false
player.run(SKAction.sequence([
    SKAction.wait(forDuration: 0.7), 
    SKAction.run  [weak self] in self?.canFireTorpedo = true ]))

之后,在方法开始处检查canFireTorpedo

func fireTorpedo() 
    if canFireTorpedo 
        // put everything in the method here, including the parts I added
    

希望这段代码是不言自明的。

【讨论】:

【参考方案3】:

启动每 0.7 秒,您可以这样做:

let actionKey = "repeatLaunchMethod"

let launchMethod = SKAction.afterDelay(0.7, runBlock: 
       [weak self] in
       guard let strongSelf = self else  return 
       strongSelf.fireTorpedo()
)
// do this if you want to repeat this action forever
self.player.run(SKAction.repeatForever(launchMethod), withKey: actionKey)
// do this if you want to repeat this action only n times
// self.player.run(SKAction.repeat(launchMethod, count: 5), withKey: actionKey)

停止此操作,您可以执行以下操作:

if self.player.action(forKey: actionKey) != nil 
       self.player.removeAction(forKey: actionKey)

扩展用于使代码更具可读性:

extension SKAction 
    /**
     * Performs an action after the specified delay.
     */
    class func afterDelay(_ delay: TimeInterval, performAction action: SKAction) -> SKAction 
        return SKAction.sequence([SKAction.wait(forDuration: delay), action])
    
    /**
     * Performs a block after the specified delay.
     */
    class func afterDelay(_ delay: TimeInterval, runBlock block: @escaping () -> Void) -> SKAction 
        return SKAction.afterDelay(delay, performAction: SKAction.run(block))
    

【讨论】:

以上是关于在 SpriteKit 中为函数添加延迟的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SpriteKit 中为游戏添加音乐

调用函数 touchesBegan 时 SpriteKit 游戏延迟

减少 Spritekit 中的延迟

使用 SpriteKit 和内置物理引擎移动和跳跃精灵

如何在 Swift 中为 SpriteKit 定义类别位掩码枚举?

如何在 iOS7 SpriteKit 中为不同大小的图像设置动画?