I added a label to the main GameScene that displays how many monsters you have killed. Also added a new variable to the init in GameOverScene to pass in the number of monsters killed so it shows in the Win or Lose screen.
class GameScene: SKScene, SKPhysicsContactDelegate {
// 1
let player = SKSpriteNode(imageNamed: "player")
**var monstersDestroyed = 0**
**var myLabel = SKLabelNode(fontNamed: "Arial")**
override func didMove(to view: SKView) {
// 2
backgroundColor = SKColor.white
// 3
player.position = CGPoint(x: size.width * 0.1, y: size.height * 0.5)
// 4
addChild(player)
physicsWorld.gravity = CGVector.zero
physicsWorld.contactDelegate = self
run(SKAction.repeatForever(
SKAction.sequence([
SKAction.run(addMonster),
SKAction.wait(forDuration: 1.0)
])
))
let backgroundMusic = SKAudioNode(fileNamed: "background-music-aac.caf")
backgroundMusic.autoplayLooped = true
addChild(backgroundMusic)
**myLabel.text = "Monsters Killed = 0"**
** myLabel.fontSize = 20**
** myLabel.fontColor = SKColor.black**
** myLabel.position = CGPoint(x: size.width * 0.2, y: size.height * 0.9)**
** addChild(myLabel)**
}
func random() -> CGFloat {
return CGFloat(Float(arc4random()) / 0xFFFFFFFF)
}
func random(min: CGFloat, max: CGFloat) -> CGFloat {
return random() * (max - min) + min
}
func addMonster() {
// Create Sprite
let monster = SKSpriteNode(imageNamed: "monster")
monster.physicsBody = SKPhysicsBody(rectangleOf: monster.size) // 1
monster.physicsBody?.isDynamic = true // 2
monster.physicsBody?.categoryBitMask = PhysicsCategory.Monster // 3
monster.physicsBody?.contactTestBitMask = PhysicsCategory.Projectile // 4
monster.physicsBody?.collisionBitMask = PhysicsCategory.None // 5
// Determine where to spawn the monster along the Y axis
let actualY = random(min: monster.size.height/2, max: size.height - monster.size.height/2)
// Position the monster slightly off-screen along the right edge,
// and along a random position along the Y axis as calculated above
monster.position = CGPoint(x: size.width + monster.size.width/2, y: actualY)
// Add the monster to the scene
addChild(monster)
// Determine speed of the monster
let actualDuration = random(min: CGFloat(2.0), max: CGFloat(4.0))
// Create the actions
let actionMove = SKAction.move(to: CGPoint(x: -monster.size.width/2, y: actualY), duration: TimeInterval(actualDuration))
let actionMoveDone = SKAction.removeFromParent()
let loseAction = SKAction.run() {
let reveal = SKTransition.flipHorizontal(withDuration: 0.5)
**let gameOverScene = GameOverScene(size: self.size, won: false, monstersKilled: self.monstersDestroyed)**
self.view?.presentScene(gameOverScene, transition: reveal)
}
monster.run(SKAction.sequence([actionMove, loseAction, actionMoveDone]))
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
run(SKAction.playSoundFileNamed("pew-pew-lei.caf", waitForCompletion: false))
// 1 - Choose one of the touches to work with
guard let touch = touches.first else {
return
}
let touchLocation = touch.location(in: self)
// 2 - Set up initial location of projectile
let projectile = SKSpriteNode(imageNamed: "projectile")
projectile.position = player.position
projectile.physicsBody = SKPhysicsBody(circleOfRadius: projectile.size.width/2)
projectile.physicsBody?.isDynamic = true
projectile.physicsBody?.categoryBitMask = PhysicsCategory.Projectile
projectile.physicsBody?.contactTestBitMask = PhysicsCategory.Monster
projectile.physicsBody?.collisionBitMask = PhysicsCategory.None
projectile.physicsBody?.usesPreciseCollisionDetection = true
// 3 - Determine offset of location to projectile
let offset = touchLocation - projectile.position
// 4 - Bail out if you are shooting down or backwards
if (offset.x < 0) { return }
// 5 - OK to add now - you've double checked position
addChild(projectile)
// 6 - Get the direction of where to shoot
let direction = offset.normalized()
// 7 - Make it shoot far enough to be guaranteed off screen
let shootAmount = direction * 1000
// 8 - Add the shoot amount to the current position
let realDest = shootAmount + projectile.position
// 9 - Create the actions
let actionMove = SKAction.move(to: realDest, duration: 2.0)
let actionMoveDone = SKAction.removeFromParent()
projectile.run(SKAction.sequence([actionMove, actionMoveDone]))
}
func projectileDidCollideWithMonster(projectile: SKSpriteNode, monster: SKSpriteNode) {
print("Hit")
projectile.removeFromParent()
monster.removeFromParent()
monstersDestroyed += 1
myLabel.text = "Monsters Killed = " + String(monstersDestroyed)
if(monstersDestroyed > 30) {
let reveal = SKTransition.flipHorizontal(withDuration: 0.5)
**let gameOverScene = GameOverScene(size: self.size, won: true,**
** monstersKilled: self.monstersDestroyed)**
self.view?.presentScene(gameOverScene, transition: reveal)
}
}
func didBegin(_ contact: SKPhysicsContact) {
// 1
var firstBody: SKPhysicsBody
var secondBody: SKPhysicsBody
if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
firstBody = contact.bodyA
secondBody = contact.bodyB
} else {
firstBody = contact.bodyB
secondBody = contact.bodyA
}
// 2
if ((firstBody.categoryBitMask & PhysicsCategory.Monster != 0) &&
(secondBody.categoryBitMask & PhysicsCategory.Projectile != 0)) {
projectileDidCollideWithMonster(projectile: firstBody.node as! SKSpriteNode, monster: secondBody.node as! SKSpriteNode)
}
}
}
class GameOverScene: SKScene {
init(size: CGSize, won:Bool, **monstersKilled: Int** ) {
super.init(size: size)
backgroundColor = SKColor.white
let message = won ? "You Won! :]" : "You Lose! :[ "
let label = SKLabelNode(fontNamed: "Chalkduster")
label.text = message
label.fontSize = 40
label.fontColor = SKColor.black
label.position = CGPoint(x: size.width/2, y: size.height/2)
addChild(label)
**let label2 = SKLabelNode(fontNamed: "Chalkduster")**
** label2.text = "Monsters Killed = " + String(monstersKilled)**
** label2.fontSize = 20**
** label2.fontColor = SKColor.black**
** label2.position = CGPoint(x: size.width/2, y: size.height/3)**
** addChild(label2)**
run(SKAction.sequence([
SKAction.wait(forDuration: 3.0),
SKAction.run() {
let reveal = SKTransition.flipHorizontal(withDuration: 0.5)
let scene = GameScene(size: size)
self.view?.presentScene(scene, transition:reveal)
}
]))
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}