簡體   English   中英

Spritekit-使用計時器在兩個功能之間切換

[英]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的倍數處返回spawnEnemiesspawnEnemies

只需添加一個名為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:) repeatForeverrepeat(_: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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM