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

时间:2016-06-16 06:22:31

标签: arrays swift sprite-kit collision-detection skphysicsbody

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

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

我遇到的问题是,当我将另一个节点合并到此函数中或为第二个节点创建一个新的但类似的函数时,我在游戏崩溃后得到一个Thread 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")
}

enter image description here

2 个答案:

答案 0 :(得分:2)

好的,这里有很多问题,主要是代码的极端重复,让你的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)) 

答案 1 :(得分:1)

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

如果你想放多个硬币,最好复制你的节点并添加到场景中。 你可以创建一个像coinZero这样的节点,然后在函数里面执行类似的操作:

let coinToAdd = coinZero.copy()