1

I have been working on a Flappy Bird type game for a couple of days now in Sprite Kit. I am new to programming so I have been trying to teach myself to make the game through various online videos and tutorials. I have come to the point where I need to create a scoring system that will display the current score on the screen in real time. I have looked and looked for a good tutorial on this but have had no luck finding one. I have a score label set up already in the code below. I have included below my entire scene. All I need to know is how to update the score label text each time the bird flies through a pipe. Any advice or suggestions would be greatly appreciated, thank you.

//
//  ArcheryScene.swift
//  FlappyBird (swift)
//
//  Created by Brandon Ballard on 1/6/15.
//  Copyright (c) 2015 Brandon Ballard. All rights reserved.
//

import UIKit
import SpriteKit

class ArcheryScene: SKScene, SKPhysicsContactDelegate {

var bird = SKSpriteNode()
var pipeUpTexture = SKTexture()
var pipeDownTexture = SKTexture()
var pipesMoveAndRemove = SKAction()
var impulse = 1
var count = 0
var scoreLabel = SKLabelNode()
let scoreLabelName = "scoreLabel"

let pipeGap = 150.0

enum ColliderType:UInt32 {
    case BIRD = 1
    case PIPE = 2
}

override func didMoveToView(view: SKView) {
    /* Setup your scene here */

    backgroundColor = SKColor.cyanColor()

    //physics
    self.physicsWorld.gravity = CGVectorMake(0.0, -15.0);
    self.physicsWorld.contactDelegate = self

    //Bird
    var birdTexture = SKTexture(imageNamed:"Bird")
    birdTexture.filteringMode = SKTextureFilteringMode.Nearest

    bird = SKSpriteNode(texture: birdTexture)
    bird.setScale(0.6)
    bird.position = CGPoint(x: self.frame.width * 0.35 + 20, y: self.frame.size.height * 0.95)

    bird.physicsBody = SKPhysicsBody(circleOfRadius: bird.size.height / 2.0)
    bird.physicsBody?.dynamic = true
    bird.physicsBody?.allowsRotation = true
    bird.physicsBody?.affectedByGravity = true
    bird.physicsBody!.collisionBitMask = ColliderType.BIRD.rawValue
    bird.physicsBody!.contactTestBitMask = ColliderType.PIPE.rawValue
    self.addChild(bird)

    //Ground
    var groundTexture = SKTexture(imageNamed: "Ground")

    var sprite = SKSpriteNode(texture: groundTexture)
    sprite.setScale(2.0)
    sprite.position = CGPointMake(self.size.width / 2, sprite.size.height / 2.0)

    self.addChild(sprite)

    var ground = SKNode()

    ground.position = CGPointMake(0, groundTexture.size().height + 0)
    ground.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(self.frame.size.width, groundTexture.size().height * 2.0))
    ground.physicsBody?.dynamic = false
    self.addChild(ground)

    //Score Label

    scoreLabel = SKLabelNode(fontNamed: "ScoreLabel")
    scoreLabel.name = scoreLabelName
    scoreLabel.fontSize = 125
    scoreLabel.fontColor = SKColor.whiteColor()
    scoreLabel.text = "\(count)"
    println(size.height)
    scoreLabel.position = CGPointMake(frame.size.width / 2, frame.size.height / 14)
    self.addChild(scoreLabel)

    //Pipes

    //Create the Pipes

    pipeUpTexture = SKTexture(imageNamed: "PipeUp")
    pipeDownTexture = SKTexture(imageNamed: "PipeDown")

    //Movement of Pipes

    let distanceToMove = CGFloat(self.frame.size.width + 2.0 * pipeUpTexture.size().width)
    let movePipes = SKAction.moveByX(-distanceToMove, y: 0.0, duration: NSTimeInterval(0.01 * distanceToMove))
    let removePipes = SKAction.removeFromParent()

    pipesMoveAndRemove = SKAction.sequence([movePipes,removePipes])

    //Spawn Pipes

    let spawn = SKAction.runBlock({() in self.spawnPipes()})
    let delay = SKAction.waitForDuration(NSTimeInterval(2.0))
    let spawnThenDelay = SKAction.sequence([spawn,delay])
    let spawnThenDelayForever = SKAction.repeatActionForever(spawnThenDelay)

    self.runAction(spawnThenDelayForever)

    }

func spawnPipes() {

    let pipePair = SKNode()
    pipePair.position = CGPointMake(self.frame.size.width + pipeUpTexture.size().width * 2, 0)
    pipePair.zPosition = -10

    let height = UInt32(self.frame.size.height / 4)
    let y = arc4random() % height + height

    var pipeDown = SKSpriteNode(texture: pipeDownTexture)
    pipeDown.setScale(2.0)////////
    pipeDown.position = CGPointMake(3.0, CGFloat(y) + pipeDown.size.height + CGFloat(pipeGap) )

    pipeDown.physicsBody = SKPhysicsBody(rectangleOfSize: pipeDown.size)
    pipeDown.physicsBody?.dynamic = false
    pipeDown.physicsBody!.affectedByGravity = false
    pipeDown.physicsBody!.collisionBitMask = ColliderType.PIPE.rawValue
    pipePair.addChild(pipeDown)

    var pipeUp = SKSpriteNode(texture: pipeUpTexture)
    pipeUp.setScale(2.0)
    pipeUp.position = CGPointMake(0.0, CGFloat(y))

    pipeUp.physicsBody = SKPhysicsBody(rectangleOfSize: pipeUp.size )
    pipeUp.physicsBody?.dynamic = false
    pipeUp.physicsBody!.affectedByGravity = false
    pipeUp.physicsBody!.collisionBitMask = ColliderType.PIPE.rawValue
    pipePair.addChild(pipeUp)

    pipePair.runAction(pipesMoveAndRemove)
    self.addChild(pipePair)

}

func didBeginContact(contact: SKPhysicsContactDelegate) {

    impulse = 0

    let fadeOut = SKAction.sequence([SKAction.waitForDuration(3.0)])

    let welcomeReturn = SKAction.runBlock({
        let Transition = SKTransition.revealWithDirection(SKTransitionDirection.Down, duration: 1.0)
        let welcomeScene = GameScene(fileNamed: "GameScene")
        welcomeScene.scaleMode = .AspectFill
        self.scene!.view?.presentScene(welcomeScene, transition: Transition)
    })

    let sequence = SKAction.sequence([fadeOut, welcomeReturn])
    self.runAction(sequence)
}

override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
    /* Called when a touch begins */

    for touch: AnyObject in touches {

        let location = touch.locationInNode(self)

        if bird.position.y > (self.frame.size.height * 0.999){
            impulse = 0
        }

        if impulse == 1 {
            bird.physicsBody?.velocity = CGVectorMake( 0, 0 )
            bird.physicsBody?.applyImpulse(CGVectorMake(0,25))
        }

    }
}

override func update(currentTime: CFTimeInterval) {
    /* Called before each frame is rendered */
}
}
CodeSmile
  • 64,284
  • 20
  • 132
  • 217
BCRwar1
  • 189
  • 5
  • 21
  • See the "Flappy Fly" tutorial, it's for cocos2d but same principle can be applied to SK. Basically you'll need a physics body between the pipes that the player can pass through but still generates a collision event. – CodeSmile Jan 07 '15 at 19:23

1 Answers1

1

Just set up an invisible sprite between your pipes. when your bird passes through it, you can detect that and increase your score.

you can make an invisible sprite like this

let scoreSprite = SKSpriteNode(color: SKColor.clearColor(), size: theSize)

add a physics body to that, and youre good to go.

hamobi
  • 7,940
  • 4
  • 35
  • 64
  • Thank you very much this solves half of my problem, the only thing I need to know now is how to make the score update when the bird passes through the invisible sprite. I already have a didBeginContact() function to detect the bird making contact with another sprite however when this function is called the game ends. – BCRwar1 Jan 07 '15 at 19:41
  • have you looked at the answer here? http://stackoverflow.com/questions/20572309/detecting-collisions-in-sprite-kit theres a lot of examples of how to handle collisions on the internet using spritekit. that didbegincontact method isnt just useful for seeing if there is contact. its useful for detecting which contacts are being made – hamobi Jan 07 '15 at 19:46