使用数组 Swift SpriteKit 生成多个硬币节点

Spawning multiple coin node(s) using an array Swift SpriteKit

我使用一个函数(如下所示)使用数组在特定位置随机生成硬币节点。

使用这个函数,我试图将多个硬币节点(彼此略有不同)合并到这个函数中,以便多个节点可以使用这个数组来生成和运行,就像第一个硬币节点一样。

我遇到的问题是,当我将另一个节点合并到此函数中或为第二个节点创建一个新的但类似的函数时,我在游戏崩溃后收到线程 1 SIGABERT 错误。

我目前为每个节点设置了两个非常相似的独立函数,但为了适应每个节点而略有不同。

 func generateCoinZero() {

    if(self.actionForKey("spawningCoinZero") != nil){return}
    let coinTimerZero = SKAction.waitForDuration(2, withRange: 7)

    let spawnCoinZero = SKAction.runBlock {
    let coinZeroTexture = SKTexture(imageNamed: "coinZero")

    self.coinZero = SKSpriteNode(texture: coinZeroTexture)
    self.coinZero.physicsBody = SKPhysicsBody(circleOfRadius: self.coinZero.size.height / 12)
    self.coinZero.physicsBody?.dynamic = false
    self.coinZero.physicsBody?.allowsRotation = false
    self.coinZero.zPosition = 1

    self.coinZero.physicsBody?.categoryBitMask = ColliderType.coinZeroCategory
    self.coinZero.physicsBody?.contactTestBitMask = ColliderType.playerCategory
    self.coinZero.physicsBody?.collisionBitMask = 0

    self.player.physicsBody?.categoryBitMask = ColliderType.playerCategory
    self.player.physicsBody?.contactTestBitMask = 0
    self.player.physicsBody?.collisionBitMask = ColliderType.boundary

    var coinPositionZero = Array<CGPoint>()
    coinPositionZero.append((CGPoint(x:250, y:139)))
    coinPositionZero.append((CGPoint(x:790, y:298)))
    coinPositionZero.append((CGPoint(x:225, y:208)))
    coinPositionZero.append((CGPoint(x:220, y:237)))

    let spawnLocationZero = coinPositionZero[Int(arc4random_uniform(UInt32(coinPositionZero.count)))]
    let actionZero = SKAction.repeatActionForever(SKAction.moveToX(+self.xScale, duration: 2.0))

    self.coinZero.runAction(actionZero)
    self.coinZero.position = spawnLocationZero
    self.addChild(self.coinZero)
    print(spawnLocationZero)
    }

  let sequenceZero = SKAction.sequence([coinTimerZero, spawnCoinZero])
    self.runAction(SKAction.repeatActionForever(sequenceZero), withKey: "spawningCoinZero") 
}

func generateCoinTwo() {

    if(self.actionForKey("spawnCoinTwo") != nil){return}
    let coinTimerTwo = SKAction.waitForDuration(2, withRange: 7)

    let spawnCoinTwo = SKAction.runBlock {

        let coinTwoTexture = SKTexture(imageNamed: "coinTwo")
        self.coinTwo = SKSpriteNode(texture: coinTwoTexture)
        self.coinTwo.physicsBody = SKPhysicsBody(circleOfRadius: self.coinTwo.size.height / 12)
        self.coinTwo.physicsBody?.dynamic = false
        self.coinTwo.physicsBody?.allowsRotation = false
        self.coinTwo.zPosition = 1
        self.addChild(self.coinTwo)

        var coinPositionTwo = Array<CGPoint>()
        coinPositionTwo.append((CGPoint(x:250, y:139)))
        coinPositionTwo.append((CGPoint(x:790, y:298)))
        coinPositionTwo.append((CGPoint(x:225, y:208)))
        coinPositionTwo.append((CGPoint(x:220, y:237)))

        let spawnLocationTwo = coinPositionTwo[Int(arc4random_uniform(UInt32(coinPositionTwo.count)))]
         let actionTwo = SKAction.repeatActionForever(SKAction.moveToX(+self.xScale, duration: 2.0))

        self.coinTwo.runAction(actionTwo)
        self.coinTwo.position = spawnLocationTwo
        self.addChild(self.coinTwo)
        print(spawnLocationTwo)
    }

    let sequenceTwo = SKAction.sequence([coinTimerTwo, spawnCoinTwo])
    self.runAction(SKAction.repeatActionForever(sequenceTwo), withKey: "spawnCoinTwo")
}

你不能addChild twice,把addChild放在runBlock之外,确保你是addChild一次。

如果你想投多个币,最好复制你的节点并添加到现场。 您可以在函数外创建一个像 coinZero 这样的节点,然后在函数内部执行如下操作:

let coinToAdd = coinZero.copy()

好吧,这里有很多问题,主要的问题是代码的极端重复和让你的 generateCoin...-函数做的太多了。所以这里是:

您在评论中声明场景应该有 两个 个硬币在不同时间在四个可能位置之一生成。如果场景有两个个硬币,那么这个场景有两个个硬币。让我们将它们创建为属性并完成它:

// Your two coin properties 
let coin1 = coinNode()
let coin2 = coinNode()

// the function from which they are created
func coinNode() -> SKSpriteNode {
    let coinNode = SKSpriteNode(imageNamed: "coinZero")
    coinNode.physicsBody = SKPhysicsBody(circleOfRadius: coinNode.size.height / 2)
    coinNode.physicsBody?.dynamic = false
    coinNode.physicsBody?.allowsRotation = false
    coinNode.zPosition = 1

    coinNode.physicsBody?.categoryBitMask = ColliderType.coinZeroCategory
    coinNode.physicsBody?.contactTestBitMask = ColliderType.playerCategory
    coinNode.physicsBody?.collisionBitMask = 0 // A ColliderType.none would be lovely...

    return coinNode
}

现在,这些硬币还没有添加到场景中,也没有合适的位置,这听起来像是另一个功能的合适范围:

func addCoin() {
    let positions = [ CGPoint(x:250, y:139), CGPoint(x:790, y:298), CGPoint(x:225, y:208), CGPoint(x:220, y:237)]
    let position = positions[Int(arc4random_uniform(UInt32(positions.count)))]

    if coin1.parent == nil {
        coin1.position = position
        addChild(coin1)
    } else if coin2.parent == nil {
        coin2.position = position
        addChild(coin2)
    }
}

最后,如果您想调用此函数,请在场景的初始化或设置中执行以下操作:

let delay = SKAction.waitForDuration(1) // or however long you want it to be between each spawn
let addCoinCall = SKAction.runBlock({ self.addCoin() })
let spawnSequence = SKAction.sequence([delay, addCoinCall])
runAction(SKAction.repeatActionForever(spawnSequence))