Swift Clock Final*

Final Version of the Birthday Swift Clock Project

screen-shot-2016-11-02-at-11-51-08-am

Gist: https://gist.github.com/Zbeyer/200d60c4a9c35aed46f77eab6952ff62

Download Zip: clockmodulev3.zip

Source…


import SpriteKit
import XCPlayground
//SpriteKit and XCPlayground are required modules
//ZBeyer October 31st 2016
/**
    nodeGenerator
 - Parameter size: The pixel size of the circle within the clock
 - Parameter point: The x and y cooridantes within the scene where the circle will be placed
 - Parameter scene: The scene in which the node will be placed
 
 creates a SKShapeNode circle at a specified point within the specified scene
 */
func nodeGenerator(size:CGFloat, point:CGPoint, scene:SKScene) -> SKShapeNode {
    let c = SKShapeNode(circleOfRadius: size ) // Size of Circle
    c.glowWidth = 0.1
    c.fillColor = SKColor.orange
    c.position = point
    scene.addChild(c)
    return c
}

//Basic dimensions that we will use more later
let frame = CGRect(x: 0, y: 0, width: 480, height: 480)
//Center point of the frame
let midPoint = CGPoint(x: frame.size.width / 2.0, y: frame.size.height / 2.0)
//radius of the planned clockface
let r = (min(frame.height, frame.width)) * 0.333

//Create a scene, add something to it
var scene = SKScene(size: frame.size)

//Set up the view and show the scene
let view = SKView(frame: frame)
view.presentScene(scene)

//Attatch the scene view to the live preview...
XCPlaygroundPage.currentPage.liveView = view

//Constant size of each node on the clock face
let kSize:CGFloat = 24

//Place a ClockFace node in the center
let clockFace:SKShapeNode = nodeGenerator(size:r, point: CGPoint( x:midPoint.x, y:midPoint.y), scene:scene)
clockFace.fillColor = SKColor.gray


//Place a normal node in the center
let centerNode:SKShapeNode = nodeGenerator(size:4, point: CGPoint( x:midPoint.x, y:midPoint.y), scene:scene)

//Determine radian spacing...
var k2PI = 2 * M_PI
var intervalTwelve:Double =  k2PI / 12.0 //Radians
var intervalSixty = k2PI / 60.0 //Radians
var angle:Double = M_PI_2
var tickOffset = (r - kSize * 1.75)



//Hours
for index in 1...12 {
    angle -= intervalTwelve
    let node:SKShapeNode = nodeGenerator(size: kSize,
                                           point: CGPoint(
                                            x:midPoint.x + r * cos(CGFloat(angle)),
                                            y:midPoint.y + r * sin(CGFloat(angle))),
                                           scene:scene)
    let pointNode:SKShapeNode = nodeGenerator(size: 4,
                                         point: CGPoint(
                                            x:midPoint.x + (r - kSize) * cos(CGFloat(angle)),
                                            y:midPoint.y + (r - kSize) * sin(CGFloat(angle))),
                                         scene:scene)
    
    let label:SKLabelNode = SKLabelNode(text:String(index))
    node.addChild(label)
    node.fillColor = SKColor.black
    label.verticalAlignmentMode = SKLabelVerticalAlignmentMode.center
    label.horizontalAlignmentMode = SKLabelHorizontalAlignmentMode.center
    label.fontName = "Menlo-Regular"
}

//Ticks

angle = M_PI_2
for index in 1...60 {
    angle -= intervalSixty
    let pointNode:SKShapeNode = nodeGenerator(size: 0.2,
                                              point: CGPoint(
                                                x:midPoint.x + tickOffset * cos(CGFloat(angle)),
                                                y:midPoint.y + tickOffset * sin(CGFloat(angle))),
                                              scene:scene)
}


//LAST UI COMPONENTS
//HANDS
var hourHand = SKSpriteNode(imageNamed: "hour")
hourHand.anchorPoint = CGPoint(x:hourHand.anchorPoint.x, y:0)
hourHand.position = CGPoint( x:midPoint.x, y:midPoint.y)
scene.addChild(hourHand)

var minuteHand = SKSpriteNode(imageNamed: "minute")
minuteHand.anchorPoint = CGPoint(x:minuteHand.anchorPoint.x, y:0)
minuteHand.position = CGPoint( x:midPoint.x, y:midPoint.y)
scene.addChild(minuteHand)

var secondHand = SKSpriteNode(imageNamed: "second")
secondHand.anchorPoint = CGPoint(x:secondHand.anchorPoint.x, y:0)
secondHand.position = CGPoint( x:midPoint.x, y:midPoint.y)
scene.addChild(secondHand)

//S

let secNode:SKShapeNode = nodeGenerator(size:8, point: CGPoint( x:0, y:0), scene:scene)
let secLabel:SKLabelNode = SKLabelNode(text:"S")
secLabel.fontName = "Menlo-Bold"
secLabel.fontSize = 16
secNode.addChild(secLabel)
secLabel.verticalAlignmentMode = SKLabelVerticalAlignmentMode.center
secLabel.horizontalAlignmentMode = SKLabelHorizontalAlignmentMode.center

//M
let minNode:SKShapeNode = nodeGenerator(size:8, point: CGPoint( x:0, y:0), scene:scene)
let minLabel:SKLabelNode = SKLabelNode(text:"M")
minLabel.fontSize = 16
minLabel.fontName = "Menlo-Bold"
minNode.addChild(minLabel)
minLabel.verticalAlignmentMode = SKLabelVerticalAlignmentMode.center
minLabel.horizontalAlignmentMode = SKLabelHorizontalAlignmentMode.center

//H
let hourNode:SKShapeNode = nodeGenerator(size:8, point: CGPoint( x:0, y:0), scene:scene)
let hourLabel:SKLabelNode = SKLabelNode(text:"H")
hourLabel.fontSize = 16
hourLabel.fontName = "Menlo-Bold"
hourNode.addChild(hourLabel)
hourLabel.verticalAlignmentMode = SKLabelVerticalAlignmentMode.center
hourLabel.horizontalAlignmentMode = SKLabelHorizontalAlignmentMode.center

// CLOCK LOGIC
class Test {
    func run() {
        var timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.toc), userInfo: nil, repeats: true)
    }
    
    @objc func toc() {
        let calendar = NSCalendar(calendarIdentifier: NSCalendar.Identifier.gregorian)
        var components = calendar!.components([.hour, .minute, .second], from: NSDate() as Date)
        let hour = components.hour! % 12
        angle = M_PI_2
        angle -= intervalTwelve * Double(hour)
        hourNode.position = CGPoint( x:midPoint.x + tickOffset * cos(CGFloat(angle)),
                                     y:midPoint.y + tickOffset * sin(CGFloat(angle)))
        hourHand.run(SKAction.rotate(toAngle: CGFloat(angle + M_PI_2 + M_PI), duration: 0))
        let minute = components.minute! % 60

        angle = M_PI_2
        angle -= intervalSixty * Double(minute)
        minNode.position = CGPoint( x:midPoint.x + tickOffset * cos(CGFloat(angle)),
                                    y:midPoint.y + tickOffset * sin(CGFloat(angle)))
        minuteHand.run(SKAction.rotate(toAngle: CGFloat(angle + M_PI_2 + M_PI), duration: 0))

        let second = components.second! % 60
        angle = M_PI_2
        angle -= intervalSixty * Double(second)
        secNode.position = CGPoint( x:midPoint.x + tickOffset * cos(CGFloat(angle)),
                                    y:midPoint.y + tickOffset * sin(CGFloat(angle)))
        secondHand.run(SKAction.rotate(toAngle: CGFloat(angle + M_PI_2 + M_PI), duration: 0))
    }
}

let test = Test()
test.run()
RunLoop.main.run(until: Date(timeIntervalSinceNow: 100))


Bookmark and Share

Leave a Reply

Your email address will not be published. Required fields are marked *