2017-10-19 83 views
1

我正在製作一款遊戲,其中有兩個不同的功能可以保存不同類型的敵人。我想編寫一個代碼,在每10個分數之間改變一次。因此,從0-10「功能1」處於活動狀態,並且從10-20「功能2」處於活動狀態,然後再次變回,然後再返回,依此類推。Spritekit - 用計時器在兩個功能之間切換

這是我含敵人兩個功能:

var score = 0 

func createPipes() { 
    PipesHolder = SKNode() 
    PipesHolder.name = "Pipe" 


    let pipeLeft = SKSpriteNode(imageNamed: "PipeRight") 
    pipeLeft.name = "Pipe" 
    pipeLeft.anchorPoint = CGPoint(x: 0.5, y: 0.5) 
    pipeLeft.position = CGPoint(x: 300, y: 0) 
    pipeLeft.physicsBody = SKPhysicsBody(rectangleOf: pipeLeft.size) 
    pipeLeft.physicsBody?.categoryBitMask = ColliderType.Pipe 
    pipeLeft.physicsBody?.affectedByGravity = false 

    let pipeRight = SKSpriteNode(imageNamed: "PipeLeft") 
    pipeRight.name = "Pipe" 
    pipeRight.anchorPoint = CGPoint(x: 0.5, y: 0.5) 
    pipeRight.position = CGPoint(x: -300, y: 0) 
    pipeRight.physicsBody = SKPhysicsBody(rectangleOf: pipeRight.size) 
    pipeRight.physicsBody?.categoryBitMask = ColliderType.Pipe 
    pipeRight.physicsBody?.affectedByGravity = false 


    PipesHolder.zPosition = 2 
    PipesHolder.xScale = 1.5 
    PipesHolder.yScale = 0.8 
    PipesHolder.position.x = CGFloat.randomBetweenNumbers(firstNum: 
    -220, secondNum: 220) 
    PipesHolder.position.y = self.frame.height + 100 

    PipesHolder.addChild(pipeLeft) 
    PipesHolder.addChild(pipeRight) 

    self.addChild(PipesHolder) 

    let destination = self.frame.height * 2 
    let move = SKAction.moveTo(y: -destination, duration: 10) 
    let remove = SKAction.removeFromParent() 

    let moveRight = SKAction.moveBy(x: 200, y: 0, duration: 1) 

    let moveLeft = SKAction.moveBy(x: -200, y: 0, duration: 1) 


    let moveBackAndForth = 
    SKAction.repeatForever(SKAction.sequence([moveRight, moveLeft])) 


    PipesHolder.run(moveBackAndForth) 

    PipesHolder.run(SKAction.sequence([move, remove]), withKey: 
    "MovePipes") 

} 

func spawnPipes() { 
    let spawn = SKAction.run({() -> Void in 
     self.createPipes() 
    }) 

    let delay = SKAction.wait(forDuration: 1) 
    let sequence = SKAction.sequence([spawn, delay]) 

    self.run(SKAction.repeatForever(sequence), withKey: "SpawnPipes") 
} 

func createRedEnemies() { 
    let enemyHolder = SKNode() 
    enemyHolder.name = "Holder" 

    let enemyLeft = SKSpriteNode(imageNamed: "Enemy") 
    let enemyMiddle = SKSpriteNode(imageNamed: "Enemy") 
    let enemyRight = SKSpriteNode(imageNamed: "Enemy") 

    enemyLeft.name = "Enemy" 
    enemyLeft.anchorPoint = CGPoint(x: 0.5, y: 0.5) 
    enemyLeft.position = CGPoint(x: 200, y: 0) 
    enemyLeft.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: 
    enemyLeft.size.width - 5, height: enemyLeft.size.height - 5)) 
    enemyLeft.physicsBody?.categoryBitMask = ColliderType.Enemy 
    enemyLeft.physicsBody?.collisionBitMask = 0 
    enemyLeft.physicsBody?.affectedByGravity = false 


    enemyMiddle.name = "Enemy" 
    enemyMiddle.anchorPoint = CGPoint(x: 0.5, y: 0.5) 
    enemyMiddle.position = CGPoint(x: 0, y: 0) 
    enemyMiddle.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: 
    enemyMiddle.size.width - 5, height: enemyMiddle.size.height - 5)) 
    enemyMiddle.physicsBody?.categoryBitMask = ColliderType.Enemy 
    enemyLeft.physicsBody?.collisionBitMask = 0 
    enemyMiddle.physicsBody?.affectedByGravity = false 


    enemyRight.name = "Enemy" 
    enemyRight.anchorPoint = CGPoint(x: 0.5, y: 0.5) 
    enemyRight.position = CGPoint(x: -200, y: 0) 
    enemyRight.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: 
    enemyRight.size.width - 5, height: enemyRight.size.height - 5)) 
    enemyRight.physicsBody?.categoryBitMask = ColliderType.Enemy 
    enemyLeft.physicsBody?.collisionBitMask = 0 
    enemyRight.physicsBody?.affectedByGravity = false 


    enemyHolder.zPosition = 2 

    enemyHolder.position.y = self.frame.height + 100 
    enemyHolder.position.x = CGFloat.randomBetweenNumbers(firstNum: 
    -100, secondNum: 100) 

    enemyHolder.addChild(enemyLeft) 
    enemyHolder.addChild(enemyMiddle) 
    enemyHolder.addChild(enemyRight) 

    self.addChild(enemyHolder) 

    let destination = self.frame.height * 4 
    let move = SKAction.moveTo(y: -destination, duration: 9) 
    let remove = SKAction.removeFromParent() 

    enemyHolder.run(SKAction.sequence([move, remove]), withKey: 
    "MoveEnemies") 

} 

func spawnEnemies() { 
    let spawn = SKAction.run({() -> Void in 
     self.createRedEnemies() 
    }) 

    let delay = SKAction.wait(forDuration: 0.4) 
    let sequence = SKAction.sequence([spawn, delay]) 

    self.run(SKAction.repeatForever(sequence), withKey: "SpawnEnemies") 

} 

這裏是我對我在「didMove」添加移動功能的代碼:

func shiftEnemies() { 

    if score >= 0 && score <= 10 { 
     spawnEnemies() 
    } else if score >= 11 && score <= 20 { 
     spawnPipes() 
    } else if score >= 21 && score <= 30 { 
     spawnEnemies() 
    } else if score >= 31 && score <= 40 { 
     spawnPipes() 
    } 

} 

兩個問題「 shiftedEnemies()」。第一個是顯而易見的,我不能爲每10個分數寫一個代碼。第二個問題是這個代碼甚至不能工作。 「SpawnEnemies()」是唯一顯示的功能。 「spawnPipes()」不會顯示,永遠。當我修復問題編號1時,可能會解決第二個問題。

Thx guys!

回答

1

SpawnEnemies功能是被調用的唯一功能的原因是因爲你把功能shiftEnemiesdidMove(toView:)方法和didMove(toView:)只被調用一次,當您出示您的場景

我的建議是嘗試調用其中所添加的得分(最有可能在你的didBeginContact法)在代碼的部分功能shiftEnemies()

+0

感謝您的回答@E。赫卡比!我正在使用計數器來添加我在「didMove」函數中添加的分數。 「計數器= Timer.scheduledTimer(一個時間間隔:TimeInterval所(1),靶:自,選擇器: 」incrementScore「,用​​戶信息:無,重複:真)」 – Flinigan

+0

然後在函數 「incrementScore」 添加 「shiftEnemies」 功能,使得函數被調用每一個得分加 –

1

所以,你要通過調用spawnenemies,當比分變爲過去的10的倍數,切換到通話spawnPipes和啓動然後回到spawnEnemies在10等的下一個倍數?

只要有一個bool稱爲shouldSpawnEnemies:

var shouldSpawnEnemies = true // Start by spawning enemies 

(如果你想通過產卵管開始,初始化這false)。

在初始化哪些功能應切換比分:

var switchFunctionScore = 10 

把財產守望你的分數。當分數超過'開關'分數時,將bool設置爲指示要使用哪個功能false。然後設置功能應該切換的下一個分數。

var score : int = 0 { 
    didSet { 
     if (score >= switchFunctionScore) && oldValue < switchFunctionScore) { 
     shouldSpawnEnemies = !shouldSpawnEnemies 
     switchFunctionScore += 10 
     } 
    } 

然後,無論何時您需要調用其中一個函數,只是檢查的shouldSpawnEnemies值:

if shouldSpawnenemies { 
    spawnEnemies 
} else { 
    spawnPipes 
} 
+0

這個偉大的工程時間,但我會在SpriteKit遊戲 – Knight0fDragon

+0

沒錯使用定時器提的問題 - 沒有看到這一點。 Flinigan - 不使用計時器 - 使用SKAction以指定的時間間隔調用你的函數。 Sprite-Kit不知道定時器,他們可以搞亂遊戲循環。 –

+0

該解決方案將與計時器工作,只需要記在事件發生時 – Knight0fDragon

0

我會避免使用定時器,定時器工作的SpriteKit時系統之外,所以對我來說,你的遊戲作弊,我會不斷地退出和返回的應用程序,因爲計時器基於實時而不是遊戲時間,遊戲之外花費的時間仍將被考慮。

你想要做的是使用SKActionwait(duration:),「序列, 'run(_ block:)repeatForeverrepeat(_:count)

要做到這一點,你需要把它分解爲若干步驟:

月1日,我們要等待1秒防火功能1:

let wait1Sec = SKAction.wait(duration:1) 
let function1 = SKAction.run({[weak self] in self?.function1()}) 
let seq1 = SKAction.sequence([wait1Sec,function1]) 

第二,我們要創建一個重複10次的動作:

let repeat1 = SKAction.repeat(seq1,count:10) 

第三,我們要爲功能2再次做到這一點:

let function2 = SKAction.run({[weak self] in self?.function2()}) 
let seq2 = SKAction.sequence([wait1Sec,function2]) 
let repeat2 = SKAction.repeat(seq2,count:10) 

最後,我們希望在2相結合,並運行它indefinetely

let seqForever = SKAction.sequence([repeat1,repeat2]) 
let repeatForever = SKAction.repeatForever(seqForever) 

現在我們已經有了動作,我們可以將其附加到現場一次

scene.run(repeatForever,withKey:"forever") 

您現在有一個解決方案,將不斷地開火方法在10秒內10次,然後在10秒內再次切換到另一個函數10次,重複一次。

override func didMove(to view:SKView) 
{ 
    let wait1Sec = SKAction.wait(duration:1) 
    let function1 = SKAction.run({[weak self] in self?.function1()}) 
    let seq1 = SKAction.sequence([wait1Sec,function1]) 
    let repeat1 = SKAction.repeat(seq1,count:10) 

    let function2 = SKAction.run({[weak self] in self?.function2()}) 
    let seq2 = SKAction.sequence([wait1Sec,function2]) 
    let repeat2 = SKAction.repeat(seq2,count:10) 

    let seqForever = SKAction.sequence([repeat1,repeat2]) 
    let repeatForever = SKAction.repeatForever(seqForever) 
    scene.run(repeatForever,withKey:"forever") 
} 
+0

謝謝騎士!我試着在代碼中添加它。不知道我是否正確地把它放入。我把所有的代碼放在「shiftEnemies()」中,但結果是完全不同的。這與開始於功能,然後它只是普與兩種功能,也倍增,至少在功能上的所有SKSpriteNodes。 – Flinigan

+0

你應該只把它稱爲一次 – Knight0fDragon

+0

是的,我沒有一次調用它。我的意思是當我開始比賽時發生的事情。 – Flinigan