[英]Spritekit - Shifting between two functions with a timer
我正在制作一個游戲,其中有兩個不同的功能可以容納不同類型的敵人。 我想編寫一個每10分在兩者之間轉換的代碼。 因此,從0-10開始,“功能1”處於活動狀態,從10-20開始,“功能2”處於活動狀態,然后它又變回來,然后又變回來,依此類推。
這是我包含敵人的兩個功能:
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時,第二個問題可能會解決。
謝謝你們!
SpawnEnemies
函數是唯一被調用的函數的原因是因為您將函數shiftEnemies
放在了didMove(toView:)
方法中,並且在呈現場景時didMove(toView:)
只被調用了一次
我建議嘗試在要添加分數的代碼部分中調用函數shiftEnemies()
(最有可能在您的didBeginContact方法中)
因此,您想從調用spawnenemies
開始,並且當分數超過10的倍數時,切換到調用spawnPipes
,然后在下一個10的倍數處返回spawnEnemies
, spawnEnemies
?
只需添加一個名為shouldSpawnEnemies的布爾值:
var shouldSpawnEnemies = true // Start by spawning enemies
(如果要從產生管道開始,請將其初始化為false
)。
初始化應切換功能的分數:
var switchFunctionScore = 10
在您的得分上加入房地產觀察家。 當分數超過“切換”分數時,將指示要使用的功能的布爾值設置為false
。 然后設置下一個應切換功能的分數。
var score : int = 0 {
didSet {
if (score >= switchFunctionScore) && oldValue < switchFunctionScore) {
shouldSpawnEnemies = !shouldSpawnEnemies
switchFunctionScore += 10
}
}
然后,無論何時需要調用以下功能之一; 只需檢查shouldSpawnEnemies
的值shouldSpawnEnemies
:
if shouldSpawnenemies {
spawnEnemies
} else {
spawnPipes
}
我會避免使用Timer,Timer在SpriteKit時間系統之外運行,因此,為了讓我在您的游戲中作弊,我可以不斷退出並返回該應用程序,並且由於Timer基於實時而不是游戲時間,因此該時間就是在游戲之外花費的費用仍將被考慮在內。
您想要做的是使用SKAction
wait(duration:)
,'sequence , 'run(_ block:)
repeatForever
和repeat(_:count)
為此,您需要將其分解為以下步驟:
首先,我們要等待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並無限期運行
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")
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.