大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;)
该挑战的目的是僵尸碰到敌人时,将其设置为无敌模式,具体要求如下:
• You should create a variable property to track whether or not the zombie is invincible. • If the zombie is invincible, you shouldn’t bother enumerating the scene’s cat ladies. • If the zombie collides with a cat lady, don’t remove the cat lady from the scene. Instead, set the zombie as invincible. Next, run a sequence of actions that first makes the zombie blink 10 times over three seconds, then runs the block of code described below. • Theblockofcodeshouldsethiddentofalseonthezombie,makingsurehe’s visible at the end no matter what, and set the zombie as no longer invincible.
书上的实现如下:
func zombieHitEnemy(enemy: SKSpriteNode) { enemy.removeFromParent() runAction(enemyCollisionSound) invincible = true let blinkTimes = 10.0 let duration = 3.0 let blinkAction = SKAction.customActionWithDuration(duration) { node, elapsedTime in let slice = duration / blinkTimes let remainder = Double(elapsedTime) % slice node.hidden = remainder > slice / 2 } let setHidden = SKAction.runBlock() { self.zombie.hidden = false self.invincible = false } zombie.runAction(SKAction.sequence([blinkAction, setHidden])) } func checkCollisions(){ if invincible { return } var hitEnemies: [SKSpriteNode] = [] enumerateChildNodesWithName("enemy") { node, _ in let enemy = node as! SKSpriteNode if CGRectIntersectsRect( CGRectInset(node.frame, 20, 20), self.zombie.frame) { hitEnemies.append(enemy) } } for enemy in hitEnemies { zombieHitEnemy(enemy) } }
我觉得有几点可以完善的地方:
- 每次都需要新建blinkAction,有点浪费.可以使用共享Action
- 僵尸变为无敌后,如果敌人出现够快还是会删除其他敌人
我把blinkAction设置为lazy的计算属性,然后直接在场景子节点枚举中处理与敌人的碰撞,然后直接跳出遍历,这可以保证只会删除第一个碰撞的敌人:
lazy var blinkAction:SKAction = { let blinkTimes = 10.0 let duration = 3.0 let blinkAction = SKAction.customActionWithDuration(duration){node,elapsedTime in let slice = duration/blinkTimes let remainder = Double(elapsedTime) % slice node.hidden = remainder > slice / 2 } return blinkAction }() func checkCollisions(){ if zombieInvincible{ return } var hitEnemies:[SKSpriteNode] = [] enumerateChildNodesWithName("enemy"){node,stop in let enemy = node as! SKSpriteNode if CGRectIntersectsRect(CGRectInset(enemy.frame, 20, 20), self.zombie.frame){ hitEnemies.append(enemy) self.zombieInvincible = true let seq = SKAction.sequence([self.blinkAction,SKAction.runBlock(){ self.zombie.hidden = false self.zombieInvincible = false }]) self.zombie.runAction(seq) stop.memory = true } } for enemy in hitEnemies{ zombieHitEnemy(enemy) } }