大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处.
如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! 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)
}
}