2017-10-19 77 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