关闭CallBack仅保留在Swift中创建的最后一个对象

时间:2015-08-07 16:33:10

标签: swift sprite-kit closures

我不确定标题是否适合我的问题,但我的问题如下。

首先,我将谈谈我是如何遇到这个问题的。基本上,我正在创建一个游戏(你可以想象),它有一个主人和许多敌人(AI)。因此,MainPlayer将四处移动,敌人会追逐他。你可以想象,MainPlayer的位置会在每一帧(也许)更新,我还需要更新敌人的追逐位置(这是主角的位置)。所以我正在使用Closure来做到这一点。我没有使用数组来存储所有敌人并且每帧更新它的原因是因为敌人可以被杀死并且会在我设置的时间内随机产生新的敌人。如果我使用数组,它有点棘手且不安全。

所以,回到我的问题,我创建了这个GameScene class的开头:

typealias CallBacks = () -> Void
var playerDidMoveCallBacks: CallBacks?

这是我的创建enemy class :(回调最底层)

// Create Enemies
func createEnemyAtPosition(position: CGPoint) {

    let enemyNode = EnemyNode()
    enemyNode.name = "ENEMY_NODE"
    enemyNode.position = position
    enemyNode.setScale(1.5)
    addChild(enemyNode)

    let sprite = SKSpriteNode(imageNamed: "enemyWisp")
    enemyNode.addChild(sprite)

    enemyNode.physicsBody = SKPhysicsBody(circleOfRadius: sprite.size.width / 2)
    enemyNode.physicsBody?.dynamic = true
    enemyNode.physicsBody?.categoryBitMask = CollisionCategoryBitMask.Enemy
    enemyNode.physicsBody?.collisionBitMask = 0
    enemyNode.physicsBody?.contactTestBitMask = CollisionCategoryBitMask.ThrowingKnife | CollisionCategoryBitMask.Player
    enemyNode.physicsBody?.usesPreciseCollisionDetection = true

    let distanceWillCollideWithPlayer = sqrt(pow(enemyNode.position.x - self.playerNode.position.x, 2) + pow(enemyNode.position.y - self.playerNode.position.y, 2))
    let durationWillColldeWithPlayer = NSTimeInterval(distanceWillCollideWithPlayer / self.enemyMovingSpeed)

    let enemyMoveAction = SKAction.moveTo(self.playerNode.position, duration: durationWillColldeWithPlayer)
    enemyNode.runAction(enemyMoveAction)
    println("\((unsafeAddressOf(enemyNode)))")
    // Update Player Position
    playerDidMoveCallBacks = {() -> Void in
        let distanceWillCollideWithPlayer = sqrt(pow(enemyNode.position.x - self.playerNode.position.x, 2) + pow(enemyNode.position.y - self.playerNode.position.y, 2))
        let durationWillColldeWithPlayer = NSTimeInterval(distanceWillCollideWithPlayer / self.enemyMovingSpeed)
        println("\((unsafeAddressOf(enemyNode)))")
        let enemyMoveAction = SKAction.moveTo(self.playerNode.position, duration: durationWillColldeWithPlayer)
        enemyNode.runAction(enemyMoveAction)
    }
}

当我知道我的英雄改变位置时,我会像这样叫callback

if self.playerDidMoveCallBacks != nil {
            self.playerDidMoveCallBacks!()
}

但这只适用于最后创建的对象,我认为这是有道理的。任何人都可以给我一个解决方案吗?

2 个答案:

答案 0 :(得分:0)

你想要的是一系列回调。

var playerDidMoveCallBacks:[CallBack]?

当关闭时捕获每个敌人时,你可以迭代数组并调用每个回调。

for callback in playerDidMoveCallBacks {
    callback()
}

但是0x141E的解决方案更好。

问题在于,当你调用闭包时,敌人不再存在,但是闭包会抓住可能导致奇怪行为的物体。 (幽灵的敌人)

答案 1 :(得分:0)

在0x141E的帮助下,我在func update创建了这行代码并解决了我的问题

// Update Enemies Position
    for childNode in children {
        let childSprite = childNode as? SKNode
        if (childSprite?.name == "ENEMY_NODE") {
            let distanceWillCollideWithPlayer = sqrt(pow(CGFloat(childSprite!.position.x) - self.playerNode.position.x, 2) + pow(CGFloat(childSprite!.position.y) - self.playerNode.position.y, 2))
            let durationWillColldeWithPlayer = NSTimeInterval(distanceWillCollideWithPlayer / self.enemyMovingSpeed)
            let enemyMoveAction = SKAction.moveTo(self.playerNode.position, duration: durationWillColldeWithPlayer)
            childSprite!.runAction(enemyMoveAction)
        }
    }