├── 0-For-Instructor
├── 1-Overview.key
├── 2-Demo.markdown
├── 3-LabImages
│ └── SCNSceneRendererDelegate.png
├── 3-LabInstructions.markdown
├── 4-ChallengeInstructions.markdown
└── 5-Conclusion.key
├── 1-Starter
├── 1-Overview.pdf
└── SCNFrogger-1
│ ├── SCNFrogger.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── SCNFrogger.xccheckout
│ └── xcuserdata
│ │ └── kim.xcuserdatad
│ │ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ ├── SCNFrogger.xcscheme
│ │ └── xcschememanagement.plist
│ ├── SCNFrogger
│ ├── AppDelegate.swift
│ ├── Array2D.swift
│ ├── Base.lproj
│ │ └── Main.storyboard
│ ├── Constants.swift
│ ├── EarlyGameBoy.ttf
│ ├── GameLevel.swift
│ ├── GameScene.swift
│ ├── GameViewController.swift
│ ├── HandNode.swift
│ ├── Images.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ ├── Contents.json
│ │ │ ├── Icon-40.png
│ │ │ ├── Icon-40@2x-1.png
│ │ │ ├── Icon-40@2x.png
│ │ │ ├── Icon-40@3x.png
│ │ │ ├── Icon-60@2x.png
│ │ │ ├── Icon-60@3x.png
│ │ │ ├── Icon-76.png
│ │ │ ├── Icon-76@2x.png
│ │ │ ├── Icon-Small.png
│ │ │ ├── Icon-Small@2x-1.png
│ │ │ ├── Icon-Small@2x.png
│ │ │ └── Icon-Small@3x.png
│ │ ├── rwdevcon-bg.imageset
│ │ │ ├── Contents.json
│ │ │ └── rwdevcon-bg.png
│ │ └── rwdevcon-logo.imageset
│ │ │ ├── Contents.json
│ │ │ └── rwdevcon-logo.png
│ ├── Info.plist
│ ├── LabelNode.swift
│ ├── LaunchScreen.xib
│ ├── SKTUtils
│ │ ├── CGFloat+Extensions.swift
│ │ ├── CGPoint+Extensions.swift
│ │ ├── CGVector+Extensions.swift
│ │ ├── Int+Extensions.swift
│ │ ├── SKAction+Extensions.swift
│ │ ├── SKAction+SpecialEffects.swift
│ │ ├── SKColor+Extensions.swift
│ │ ├── SKNode+Extensions.swift
│ │ ├── SKTAudio.swift
│ │ ├── SKTEffects.swift
│ │ ├── SKTTimingFunctions.swift
│ │ └── Vector3.swift
│ └── assets.scnassets
│ │ ├── Models
│ │ ├── car.dae
│ │ └── frog.dae
│ │ ├── Sounds
│ │ └── jump.wav
│ │ └── Textures
│ │ ├── hand.png
│ │ ├── hand@2x.png
│ │ ├── hand_click.png
│ │ ├── hand_click@2x.png
│ │ └── model_texture.tga
│ └── SCNFroggerTests
│ ├── Info.plist
│ └── SCNFroggerTests.swift
├── 2-Demo
├── 2-Demo.html
└── SCNFrogger-2
│ ├── SCNFrogger.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── SCNFrogger.xccheckout
│ └── xcuserdata
│ │ └── kim.xcuserdatad
│ │ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ ├── SCNFrogger.xcscheme
│ │ └── xcschememanagement.plist
│ ├── SCNFrogger
│ ├── AppDelegate.swift
│ ├── Array2D.swift
│ ├── Base.lproj
│ │ └── Main.storyboard
│ ├── Constants.swift
│ ├── EarlyGameBoy.ttf
│ ├── GameLevel.swift
│ ├── GameScene.swift
│ ├── GameViewController.swift
│ ├── HandNode.swift
│ ├── Images.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ ├── Contents.json
│ │ │ ├── Icon-40.png
│ │ │ ├── Icon-40@2x-1.png
│ │ │ ├── Icon-40@2x.png
│ │ │ ├── Icon-40@3x.png
│ │ │ ├── Icon-60@2x.png
│ │ │ ├── Icon-60@3x.png
│ │ │ ├── Icon-76.png
│ │ │ ├── Icon-76@2x.png
│ │ │ ├── Icon-Small.png
│ │ │ ├── Icon-Small@2x-1.png
│ │ │ ├── Icon-Small@2x.png
│ │ │ └── Icon-Small@3x.png
│ │ ├── rwdevcon-bg.imageset
│ │ │ ├── Contents.json
│ │ │ └── rwdevcon-bg.png
│ │ └── rwdevcon-logo.imageset
│ │ │ ├── Contents.json
│ │ │ └── rwdevcon-logo.png
│ ├── Info.plist
│ ├── LabelNode.swift
│ ├── LaunchScreen.xib
│ ├── SKTUtils
│ │ ├── CGFloat+Extensions.swift
│ │ ├── CGPoint+Extensions.swift
│ │ ├── CGVector+Extensions.swift
│ │ ├── Int+Extensions.swift
│ │ ├── SKAction+Extensions.swift
│ │ ├── SKAction+SpecialEffects.swift
│ │ ├── SKColor+Extensions.swift
│ │ ├── SKNode+Extensions.swift
│ │ ├── SKTAudio.swift
│ │ ├── SKTEffects.swift
│ │ ├── SKTTimingFunctions.swift
│ │ └── Vector3.swift
│ └── assets.scnassets
│ │ ├── Models
│ │ ├── car.dae
│ │ └── frog.dae
│ │ ├── Sounds
│ │ └── jump.wav
│ │ └── Textures
│ │ ├── hand.png
│ │ ├── hand@2x.png
│ │ ├── hand_click.png
│ │ ├── hand_click@2x.png
│ │ └── model_texture.tga
│ └── SCNFroggerTests
│ ├── Info.plist
│ └── SCNFroggerTests.swift
├── 3-Lab
├── 3-LabImages
│ └── SCNSceneRendererDelegate.png
├── 3-LabInstructions.html
└── SCNFrogger-3
│ ├── SCNFrogger.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── SCNFrogger.xccheckout
│ └── xcuserdata
│ │ └── kim.xcuserdatad
│ │ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ ├── SCNFrogger.xcscheme
│ │ └── xcschememanagement.plist
│ ├── SCNFrogger
│ ├── AppDelegate.swift
│ ├── Array2D.swift
│ ├── Base.lproj
│ │ └── Main.storyboard
│ ├── Constants.swift
│ ├── EarlyGameBoy.ttf
│ ├── GameLevel.swift
│ ├── GameScene.swift
│ ├── GameViewController.swift
│ ├── HandNode.swift
│ ├── Images.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ ├── Contents.json
│ │ │ ├── Icon-40.png
│ │ │ ├── Icon-40@2x-1.png
│ │ │ ├── Icon-40@2x.png
│ │ │ ├── Icon-40@3x.png
│ │ │ ├── Icon-60@2x.png
│ │ │ ├── Icon-60@3x.png
│ │ │ ├── Icon-76.png
│ │ │ ├── Icon-76@2x.png
│ │ │ ├── Icon-Small.png
│ │ │ ├── Icon-Small@2x-1.png
│ │ │ ├── Icon-Small@2x.png
│ │ │ └── Icon-Small@3x.png
│ │ ├── rwdevcon-bg.imageset
│ │ │ ├── Contents.json
│ │ │ └── rwdevcon-bg.png
│ │ └── rwdevcon-logo.imageset
│ │ │ ├── Contents.json
│ │ │ └── rwdevcon-logo.png
│ ├── Info.plist
│ ├── LabelNode.swift
│ ├── LaunchScreen.xib
│ ├── SKTUtils
│ │ ├── CGFloat+Extensions.swift
│ │ ├── CGPoint+Extensions.swift
│ │ ├── CGVector+Extensions.swift
│ │ ├── Int+Extensions.swift
│ │ ├── SKAction+Extensions.swift
│ │ ├── SKAction+SpecialEffects.swift
│ │ ├── SKColor+Extensions.swift
│ │ ├── SKNode+Extensions.swift
│ │ ├── SKTAudio.swift
│ │ ├── SKTEffects.swift
│ │ ├── SKTTimingFunctions.swift
│ │ └── Vector3.swift
│ └── assets.scnassets
│ │ ├── Models
│ │ ├── car.dae
│ │ └── frog.dae
│ │ ├── Sounds
│ │ └── jump.wav
│ │ └── Textures
│ │ ├── hand.png
│ │ ├── hand@2x.png
│ │ ├── hand_click.png
│ │ ├── hand_click@2x.png
│ │ └── model_texture.tga
│ └── SCNFroggerTests
│ ├── Info.plist
│ └── SCNFroggerTests.swift
├── 4-Challenge
├── 4-ChallengeInstructions.html
└── SCNFrogger-4
│ ├── SCNFrogger.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── SCNFrogger.xccheckout
│ └── xcuserdata
│ │ └── kim.xcuserdatad
│ │ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ ├── SCNFrogger.xcscheme
│ │ └── xcschememanagement.plist
│ ├── SCNFrogger
│ ├── AppDelegate.swift
│ ├── Array2D.swift
│ ├── Base.lproj
│ │ └── Main.storyboard
│ ├── Constants.swift
│ ├── EarlyGameBoy.ttf
│ ├── GameLevel.swift
│ ├── GameScene.swift
│ ├── GameViewController.swift
│ ├── HandNode.swift
│ ├── Images.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ ├── Contents.json
│ │ │ ├── Icon-40.png
│ │ │ ├── Icon-40@2x-1.png
│ │ │ ├── Icon-40@2x.png
│ │ │ ├── Icon-40@3x.png
│ │ │ ├── Icon-60@2x.png
│ │ │ ├── Icon-60@3x.png
│ │ │ ├── Icon-76.png
│ │ │ ├── Icon-76@2x.png
│ │ │ ├── Icon-Small.png
│ │ │ ├── Icon-Small@2x-1.png
│ │ │ ├── Icon-Small@2x.png
│ │ │ └── Icon-Small@3x.png
│ │ ├── rwdevcon-bg.imageset
│ │ │ ├── Contents.json
│ │ │ └── rwdevcon-bg.png
│ │ └── rwdevcon-logo.imageset
│ │ │ ├── Contents.json
│ │ │ └── rwdevcon-logo.png
│ ├── Info.plist
│ ├── LabelNode.swift
│ ├── LaunchScreen.xib
│ ├── SKTUtils
│ │ ├── CGFloat+Extensions.swift
│ │ ├── CGPoint+Extensions.swift
│ │ ├── CGVector+Extensions.swift
│ │ ├── Int+Extensions.swift
│ │ ├── SKAction+Extensions.swift
│ │ ├── SKAction+SpecialEffects.swift
│ │ ├── SKColor+Extensions.swift
│ │ ├── SKNode+Extensions.swift
│ │ ├── SKTAudio.swift
│ │ ├── SKTEffects.swift
│ │ ├── SKTTimingFunctions.swift
│ │ └── Vector3.swift
│ └── assets.scnassets
│ │ ├── Models
│ │ ├── car.dae
│ │ └── frog.dae
│ │ ├── Sounds
│ │ └── jump.wav
│ │ └── Textures
│ │ ├── hand.png
│ │ ├── hand@2x.png
│ │ ├── hand_click.png
│ │ ├── hand_click@2x.png
│ │ └── model_texture.tga
│ └── SCNFroggerTests
│ ├── Info.plist
│ └── SCNFroggerTests.swift
├── 5-Conclusion
└── 5-Conclusion.pdf
├── LICENSE
├── README.md
└── screenshot.png
/0-For-Instructor/1-Overview.key:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/0-For-Instructor/1-Overview.key
--------------------------------------------------------------------------------
/0-For-Instructor/3-LabImages/SCNSceneRendererDelegate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/0-For-Instructor/3-LabImages/SCNSceneRendererDelegate.png
--------------------------------------------------------------------------------
/0-For-Instructor/5-Conclusion.key:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/0-For-Instructor/5-Conclusion.key
--------------------------------------------------------------------------------
/1-Starter/1-Overview.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/1-Starter/1-Overview.pdf
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger.xcodeproj/project.xcworkspace/xcshareddata/SCNFrogger.xccheckout:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDESourceControlProjectFavoriteDictionaryKey
6 |
7 | IDESourceControlProjectIdentifier
8 | 6DE4669D-839D-4A6C-935D-D50EE5C00229
9 | IDESourceControlProjectName
10 | SCNFrogger
11 | IDESourceControlProjectOriginsDictionary
12 |
13 | C45253657BF1B0A67E13F808D5E653AC34B147B3
14 | https://github.com/devindazzle/SceneKitFrogger.git
15 |
16 | IDESourceControlProjectPath
17 | 1-Starter/SCNFrogger-1/SCNFrogger.xcodeproj
18 | IDESourceControlProjectRelativeInstallPathDictionary
19 |
20 | C45253657BF1B0A67E13F808D5E653AC34B147B3
21 | ../../../..
22 |
23 | IDESourceControlProjectURL
24 | https://github.com/devindazzle/SceneKitFrogger.git
25 | IDESourceControlProjectVersion
26 | 111
27 | IDESourceControlProjectWCCIdentifier
28 | C45253657BF1B0A67E13F808D5E653AC34B147B3
29 | IDESourceControlProjectWCConfigurations
30 |
31 |
32 | IDESourceControlRepositoryExtensionIdentifierKey
33 | public.vcs.git
34 | IDESourceControlWCCIdentifierKey
35 | C45253657BF1B0A67E13F808D5E653AC34B147B3
36 | IDESourceControlWCCName
37 | SceneKitFrogger
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger.xcodeproj/xcuserdata/kim.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger.xcodeproj/xcuserdata/kim.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | SCNFrogger.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 3BE6195A1A2DCDBA00ED80D7
16 |
17 | primary
18 |
19 |
20 | 3BE619711A2DCDBA00ED80D7
21 |
22 | primary
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // RWDevConSceneKitFinal
4 | //
5 | // Created by Kim Pedersen on 24/11/14.
6 | // Copyright (c) 2014 RWDevCon. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
17 | // Override point for customization after application launch.
18 | return true
19 | }
20 |
21 | func applicationWillResignActive(application: UIApplication) {
22 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
23 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
24 | }
25 |
26 | func applicationDidEnterBackground(application: UIApplication) {
27 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
28 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
29 | }
30 |
31 | func applicationWillEnterForeground(application: UIApplication) {
32 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
33 | }
34 |
35 | func applicationDidBecomeActive(application: UIApplication) {
36 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
37 | }
38 |
39 | func applicationWillTerminate(application: UIApplication) {
40 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
41 | }
42 |
43 |
44 | }
45 |
46 |
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger/Array2D.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Array2D.swift
3 | // RWDevConSceneKitFinal
4 | //
5 | // Created by Kim Pedersen on 24/11/14.
6 | // Copyright (c) 2014 RWDevCon. All rights reserved.
7 | //
8 |
9 | class Array2D {
10 |
11 | var cols: Int, rows: Int
12 | var data: [Int]
13 |
14 | init(cols columnCount: Int, rows rowCount: Int, value defaultValue: Int) {
15 | self.cols = columnCount
16 | self.rows = rowCount
17 | data = Array(count: cols * rows, repeatedValue: defaultValue)
18 | }
19 |
20 | subscript(column: Int, row: Int) -> Int {
21 | get {
22 | return data[cols * row + column]
23 | }
24 | set {
25 | data[cols * row + column] = newValue
26 | }
27 | }
28 |
29 | func columnCount() -> Int {
30 | return self.cols
31 | }
32 |
33 | func rowCount() -> Int {
34 | return self.rows
35 | }
36 |
37 | }
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger/Constants.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Constants.swift
3 | // SCNFrogger
4 | //
5 | // Created by Kim Pedersen on 11/12/14.
6 | // Copyright (c) 2014 RWDevCon. All rights reserved.
7 | //
8 |
9 | enum GameState {
10 | case WaitingForFirstTap
11 | case Playing
12 | case GameOver
13 | case RestartLevel
14 | }
15 |
16 |
17 | enum MoveDirection {
18 | case Forward
19 | case Backward
20 | case Left
21 | case Right
22 | }
23 |
24 |
25 | struct PhysicsCategory {
26 | static let None: Int = 0
27 | static let Player: Int = 0b1 // 1
28 | static let Car: Int = 0b10 // 2
29 | static let Obstacle: Int = 0b100 // 4
30 | }
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger/EarlyGameBoy.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/1-Starter/SCNFrogger-1/SCNFrogger/EarlyGameBoy.ttf
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger/GameViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GameViewController.swift
3 | // RWDevConSceneKitFinal
4 | //
5 | // Created by Kim Pedersen on 24/11/14.
6 | // Copyright (c) 2014 RWDevCon. All rights reserved.
7 | //
8 |
9 | import SceneKit
10 | import SpriteKit
11 |
12 | class GameViewController: UIViewController {
13 |
14 | var scnView: SCNView {
15 | get {
16 | return self.view as SCNView
17 | }
18 | }
19 |
20 | override func viewDidAppear(animated: Bool) {
21 |
22 | super.viewDidAppear(animated)
23 |
24 | // Set up the SCNView
25 | scnView.backgroundColor = UIColor(red: 100.0/255.0, green: 149.0/255.0, blue: 237.0/255.0, alpha: 1.0)
26 | scnView.showsStatistics = true
27 | scnView.allowsCameraControl = true
28 | scnView.antialiasingMode = SCNAntialiasingMode.Multisampling2X
29 | scnView.overlaySKScene = SKScene(size: view.bounds.size)
30 | scnView.playing = true
31 |
32 | // Set up the scene
33 | let scene = GameScene(view: scnView)
34 | scene.rootNode.hidden = true
35 | scene.physicsWorld.contactDelegate = scene
36 |
37 | // Start playing the scene
38 | scnView.scene = scene
39 | scnView.delegate = scene
40 | scnView.scene!.rootNode.hidden = false
41 | scnView.play(self)
42 | }
43 |
44 |
45 | override func shouldAutorotate() -> Bool {
46 | return true
47 | }
48 |
49 |
50 | override func prefersStatusBarHidden() -> Bool {
51 | return true
52 | }
53 |
54 |
55 | override func supportedInterfaceOrientations() -> Int {
56 | return Int(UIInterfaceOrientationMask.Portrait.rawValue)
57 | }
58 |
59 |
60 | override func didReceiveMemoryWarning() {
61 | super.didReceiveMemoryWarning()
62 | }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger/HandNode.swift:
--------------------------------------------------------------------------------
1 | //
2 | // HandNode.swift
3 | // SCNFrogger
4 | //
5 | // Created by Kim Pedersen on 11/12/14.
6 | // Copyright (c) 2014 RWDevCon. All rights reserved.
7 | //
8 |
9 | import SpriteKit
10 |
11 | class HandNode : SKNode {
12 |
13 | override init() {
14 |
15 | super.init()
16 |
17 | name = "Tutorial"
18 |
19 | // Load textures
20 | let handTexture = SKTexture(imageNamed:"assets.scnassets/Textures/hand.png")
21 | handTexture.filteringMode = SKTextureFilteringMode.Nearest
22 | let handTextureClick = SKTexture(imageNamed:"assets.scnassets/Textures/hand_click.png")
23 | handTextureClick.filteringMode = SKTextureFilteringMode.Nearest
24 |
25 | // Create animation
26 | let handAnimation = SKAction.animateWithTextures([handTexture, handTextureClick], timePerFrame:0.5)
27 |
28 | // Create a sprite node abd animate it
29 | let handSprite = SKSpriteNode(texture: handTexture)
30 | handSprite.xScale = 2.0
31 | handSprite.yScale = 2.0
32 | handSprite.runAction(SKAction.repeatActionForever(handAnimation))
33 |
34 | addChild(handSprite)
35 | }
36 |
37 |
38 | required init?(coder aDecoder: NSCoder) {
39 | fatalError("init(coder:) has not been implemented")
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "29x29",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-Small@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "29x29",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-Small@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "40x40",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-40@2x.png",
19 | "scale" : "2x"
20 | },
21 | {
22 | "size" : "40x40",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-40@3x.png",
25 | "scale" : "3x"
26 | },
27 | {
28 | "size" : "60x60",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-60@2x.png",
31 | "scale" : "2x"
32 | },
33 | {
34 | "size" : "60x60",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-60@3x.png",
37 | "scale" : "3x"
38 | },
39 | {
40 | "size" : "29x29",
41 | "idiom" : "ipad",
42 | "filename" : "Icon-Small.png",
43 | "scale" : "1x"
44 | },
45 | {
46 | "size" : "29x29",
47 | "idiom" : "ipad",
48 | "filename" : "Icon-Small@2x-1.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "40x40",
53 | "idiom" : "ipad",
54 | "filename" : "Icon-40.png",
55 | "scale" : "1x"
56 | },
57 | {
58 | "size" : "40x40",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-40@2x-1.png",
61 | "scale" : "2x"
62 | },
63 | {
64 | "size" : "76x76",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-76.png",
67 | "scale" : "1x"
68 | },
69 | {
70 | "size" : "76x76",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-76@2x.png",
73 | "scale" : "2x"
74 | }
75 | ],
76 | "info" : {
77 | "version" : 1,
78 | "author" : "xcode"
79 | }
80 | }
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/1-Starter/SCNFrogger-1/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-40.png
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-40@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/1-Starter/SCNFrogger-1/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-40@2x-1.png
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/1-Starter/SCNFrogger-1/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-40@2x.png
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/1-Starter/SCNFrogger-1/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-40@3x.png
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/1-Starter/SCNFrogger-1/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-60@2x.png
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/1-Starter/SCNFrogger-1/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-60@3x.png
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/1-Starter/SCNFrogger-1/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-76.png
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/1-Starter/SCNFrogger-1/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-76@2x.png
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-Small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/1-Starter/SCNFrogger-1/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-Small.png
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-Small@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/1-Starter/SCNFrogger-1/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-Small@2x-1.png
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-Small@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/1-Starter/SCNFrogger-1/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-Small@2x.png
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-Small@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/1-Starter/SCNFrogger-1/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-Small@3x.png
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger/Images.xcassets/rwdevcon-bg.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x",
10 | "filename" : "rwdevcon-bg.png"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger/Images.xcassets/rwdevcon-bg.imageset/rwdevcon-bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/1-Starter/SCNFrogger-1/SCNFrogger/Images.xcassets/rwdevcon-bg.imageset/rwdevcon-bg.png
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger/Images.xcassets/rwdevcon-logo.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x",
10 | "filename" : "rwdevcon-logo.png"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger/Images.xcassets/rwdevcon-logo.imageset/rwdevcon-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/1-Starter/SCNFrogger-1/SCNFrogger/Images.xcassets/rwdevcon-logo.imageset/rwdevcon-logo.png
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | com.raywenderlich.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UIAppFonts
26 |
27 | EarlyGameBoy.ttf
28 |
29 | UILaunchStoryboardName
30 | LaunchScreen
31 | UIMainStoryboardFile
32 | Main
33 | UIRequiredDeviceCapabilities
34 |
35 | armv7
36 |
37 | UIStatusBarHidden
38 |
39 | UISupportedInterfaceOrientations
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 |
44 | UISupportedInterfaceOrientations~ipad
45 |
46 | UIInterfaceOrientationPortrait
47 | UIInterfaceOrientationPortraitUpsideDown
48 | UIInterfaceOrientationLandscapeLeft
49 | UIInterfaceOrientationLandscapeRight
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger/LabelNode.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LabelNode.swift
3 | // SCNFrogger
4 | //
5 | // Created by Kim Pedersen on 11/12/14.
6 | // Copyright (c) 2014 RWDevCon. All rights reserved.
7 | //
8 |
9 | import SpriteKit
10 |
11 | class LabelNode : SKLabelNode {
12 |
13 | init(position: CGPoint, size: CGFloat, color: SKColor, text: String, name: String) {
14 | super.init()
15 |
16 | self.name = name
17 | self.text = text
18 | self.position = position
19 |
20 | fontName = "Early-Gameboy"
21 | fontSize = size
22 | fontColor = color
23 | }
24 |
25 | required init?(coder aDecoder: NSCoder) {
26 | fatalError("init(coder:) has not been implemented")
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger/LaunchScreen.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger/SKTUtils/CGFloat+Extensions.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013-2014 Razeware LLC
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import CoreGraphics
24 |
25 | /** The value of π as a CGFloat */
26 | let π = CGFloat(M_PI)
27 |
28 | public extension CGFloat {
29 | /**
30 | * Converts an angle in degrees to radians.
31 | */
32 | public func degreesToRadians() -> CGFloat {
33 | return π * self / 180.0
34 | }
35 |
36 | /**
37 | * Converts an angle in radians to degrees.
38 | */
39 | public func radiansToDegrees() -> CGFloat {
40 | return self * 180.0 / π
41 | }
42 |
43 | /**
44 | * Ensures that the float value stays between the given values, inclusive.
45 | */
46 | public func clamped(v1: CGFloat, _ v2: CGFloat) -> CGFloat {
47 | let min = v1 < v2 ? v1 : v2
48 | let max = v1 > v2 ? v1 : v2
49 | return self < min ? min : (self > max ? max : self)
50 | }
51 |
52 | /**
53 | * Ensures that the float value stays between the given values, inclusive.
54 | */
55 | public mutating func clamp(v1: CGFloat, _ v2: CGFloat) -> CGFloat {
56 | self = clamped(v1, v2)
57 | return self
58 | }
59 |
60 | /**
61 | * Returns 1.0 if a floating point value is positive; -1.0 if it is negative.
62 | */
63 | public func sign() -> CGFloat {
64 | return (self >= 0.0) ? 1.0 : -1.0
65 | }
66 |
67 | /**
68 | * Returns a random floating point number between 0.0 and 1.0, inclusive.
69 | */
70 | public static func random() -> CGFloat {
71 | return CGFloat(Float(arc4random()) / 0xFFFFFFFF)
72 | }
73 |
74 | /**
75 | * Returns a random floating point number in the range min...max, inclusive.
76 | */
77 | public static func random(#min: CGFloat, max: CGFloat) -> CGFloat {
78 | assert(min < max)
79 | return CGFloat.random() * (max - min) + min
80 | }
81 |
82 | /**
83 | * Randomly returns either 1.0 or -1.0.
84 | */
85 | public static func randomSign() -> CGFloat {
86 | return (arc4random_uniform(2) == 0) ? 1.0 : -1.0
87 | }
88 | }
89 |
90 | /**
91 | * Returns the shortest angle between two angles. The result is always between
92 | * -π and π.
93 | */
94 | public func shortestAngleBetween(angle1: CGFloat, angle2: CGFloat) -> CGFloat {
95 | let twoπ = π * 2.0
96 | var angle = (angle2 - angle1) % twoπ
97 | if (angle >= π) {
98 | angle = angle - twoπ
99 | }
100 | if (angle <= -π) {
101 | angle = angle + twoπ
102 | }
103 | return angle
104 | }
105 |
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger/SKTUtils/Int+Extensions.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013-2014 Razeware LLC
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import CoreGraphics
24 |
25 | public extension Int {
26 | /**
27 | * Ensures that the integer value stays with the specified range.
28 | */
29 | public func clamped(range: Range) -> Int {
30 | return (self < range.startIndex) ? range.startIndex : ((self >= range.endIndex) ? range.endIndex - 1: self)
31 | }
32 |
33 | /**
34 | * Ensures that the integer value stays with the specified range.
35 | */
36 | public mutating func clamp(range: Range) -> Int {
37 | self = clamped(range)
38 | return self
39 | }
40 |
41 | /**
42 | * Ensures that the integer value stays between the given values, inclusive.
43 | */
44 | public func clamped(v1: Int, _ v2: Int) -> Int {
45 | let min = v1 < v2 ? v1 : v2
46 | let max = v1 > v2 ? v1 : v2
47 | return self < min ? min : (self > max ? max : self)
48 | }
49 |
50 | /**
51 | * Ensures that the integer value stays between the given values, inclusive.
52 | */
53 | public mutating func clamp(v1: Int, _ v2: Int) -> Int {
54 | self = clamped(v1, v2)
55 | return self
56 | }
57 |
58 | /**
59 | * Returns a random integer in the specified range.
60 | */
61 | public static func random(range: Range) -> Int {
62 | return Int(arc4random_uniform(UInt32(range.endIndex - range.startIndex))) + range.startIndex
63 | }
64 |
65 | /**
66 | * Returns a random integer between 0 and n-1.
67 | */
68 | public static func random(n: Int) -> Int {
69 | return Int(arc4random_uniform(UInt32(n)))
70 | }
71 |
72 | /**
73 | * Returns a random integer in the range min...max, inclusive.
74 | */
75 | public static func random(#min: Int, max: Int) -> Int {
76 | assert(min < max)
77 | return Int(arc4random_uniform(UInt32(max - min + 1))) + min
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger/SKTUtils/SKAction+Extensions.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013-2014 Razeware LLC
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import SpriteKit
24 |
25 | public extension SKAction {
26 | /**
27 | * Performs an action after the specified delay.
28 | */
29 | public class func afterDelay(delay: NSTimeInterval, performAction action: SKAction) -> SKAction {
30 | return SKAction.sequence([SKAction.waitForDuration(delay), action])
31 | }
32 |
33 | /**
34 | * Performs a block after the specified delay.
35 | */
36 | public class func afterDelay(delay: NSTimeInterval, runBlock block: dispatch_block_t) -> SKAction {
37 | return SKAction.afterDelay(delay, performAction: SKAction.runBlock(block))
38 | }
39 |
40 | /**
41 | * Removes the node from its parent after the specified delay.
42 | */
43 | public class func removeFromParentAfterDelay(delay: NSTimeInterval) -> SKAction {
44 | return SKAction.afterDelay(delay, performAction: SKAction.removeFromParent())
45 | }
46 |
47 | /**
48 | * Creates an action to perform a parabolic jump.
49 | */
50 | public class func jumpToHeight(height: CGFloat, duration: NSTimeInterval, originalPosition: CGPoint) -> SKAction {
51 | return SKAction.customActionWithDuration(duration) {(node, elapsedTime) in
52 | let fraction = elapsedTime / CGFloat(duration)
53 | let yOffset = height * 4 * fraction * (1 - fraction)
54 | node.position = CGPoint(x: originalPosition.x, y: originalPosition.y + yOffset)
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger/SKTUtils/SKAction+SpecialEffects.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013-2014 Razeware LLC
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import SpriteKit
24 |
25 | public extension SKAction {
26 | /**
27 | * Creates a screen shake animation.
28 | *
29 | * @param node The node to shake. You cannot apply this effect to an SKScene.
30 | * @param amount The vector by which the node is displaced.
31 | * @param oscillations The number of oscillations; 10 is a good value.
32 | * @param duration How long the effect lasts. Shorter is better.
33 | */
34 | public class func screenShakeWithNode(node: SKNode, amount: CGPoint, oscillations: Int, duration: NSTimeInterval) -> SKAction {
35 | let oldPosition = node.position
36 | let newPosition = oldPosition + amount
37 |
38 | let effect = SKTMoveEffect(node: node, duration: duration, startPosition: newPosition, endPosition: oldPosition)
39 | effect.timingFunction = SKTCreateShakeFunction(oscillations)
40 |
41 | return SKAction.actionWithEffect(effect)
42 | }
43 |
44 | /**
45 | * Creates a screen rotation animation.
46 | *
47 | * @param node You usually want to apply this effect to a pivot node that is
48 | * centered in the scene. You cannot apply the effect to an SKScene.
49 | * @param angle The angle in radians.
50 | * @param oscillations The number of oscillations; 10 is a good value.
51 | * @param duration How long the effect lasts. Shorter is better.
52 | */
53 | public class func screenRotateWithNode(node: SKNode, angle: CGFloat, oscillations: Int, duration: NSTimeInterval) -> SKAction {
54 | let oldAngle = node.zRotation
55 | let newAngle = oldAngle + angle
56 |
57 | let effect = SKTRotateEffect(node: node, duration: duration, startAngle: newAngle, endAngle: oldAngle)
58 | effect.timingFunction = SKTCreateShakeFunction(oscillations)
59 |
60 | return SKAction.actionWithEffect(effect)
61 | }
62 |
63 | /**
64 | * Creates a screen zoom animation.
65 | *
66 | * @param node You usually want to apply this effect to a pivot node that is
67 | * centered in the scene. You cannot apply the effect to an SKScene.
68 | * @param amount How much to scale the node in the X and Y directions.
69 | * @param oscillations The number of oscillations; 10 is a good value.
70 | * @param duration How long the effect lasts. Shorter is better.
71 | */
72 | public class func screenZoomWithNode(node: SKNode, amount: CGPoint, oscillations: Int, duration: NSTimeInterval) -> SKAction {
73 | let oldScale = CGPoint(x: node.xScale, y: node.yScale)
74 | let newScale = oldScale * amount
75 |
76 | let effect = SKTScaleEffect(node: node, duration: duration, startScale: newScale, endScale: oldScale)
77 | effect.timingFunction = SKTCreateShakeFunction(oscillations)
78 |
79 | return SKAction.actionWithEffect(effect)
80 | }
81 |
82 | /**
83 | * Causes the scene background to flash for duration seconds.
84 | */
85 | public class func colorGlitchWithScene(scene: SKScene, originalColor: SKColor, duration: NSTimeInterval) -> SKAction {
86 | return SKAction.customActionWithDuration(duration) {(node, elapsedTime) in
87 | if elapsedTime < CGFloat(duration) {
88 | scene.backgroundColor = SKColorWithRGB(Int.random(0...255), Int.random(0...255), Int.random(0...255))
89 | } else {
90 | scene.backgroundColor = originalColor
91 | }
92 | }
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger/SKTUtils/SKColor+Extensions.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013-2014 Razeware LLC
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import SpriteKit
24 |
25 | public func SKColorWithRGB(r: Int, g: Int, b: Int) -> SKColor {
26 | return SKColor(red: CGFloat(r)/255.0, green: CGFloat(g)/255.0, blue: CGFloat(b)/255.0, alpha: 1.0)
27 | }
28 |
29 | public func SKColorWithRGBA(r: Int, g: Int, b: Int, a: Int) -> SKColor {
30 | return SKColor(red: CGFloat(r)/255.0, green: CGFloat(g)/255.0, blue: CGFloat(b)/255.0, alpha: CGFloat(a)/255.0)
31 | }
32 |
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger/SKTUtils/SKNode+Extensions.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013-2014 Razeware LLC
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import SpriteKit
24 |
25 | public extension SKNode {
26 |
27 | /** Lets you treat the node's scale as a CGPoint value. */
28 | public var scaleAsPoint: CGPoint {
29 | get {
30 | return CGPoint(x: xScale, y: yScale)
31 | }
32 | set {
33 | xScale = newValue.x
34 | yScale = newValue.y
35 | }
36 | }
37 |
38 | /**
39 | * Runs an action on the node that performs a closure or function after
40 | * a given time.
41 | */
42 | public func afterDelay(delay: NSTimeInterval, runBlock block: dispatch_block_t) {
43 | runAction(SKAction.sequence([SKAction.waitForDuration(delay), SKAction.runBlock(block)]))
44 | }
45 |
46 | /**
47 | * Makes this node the frontmost node in its parent.
48 | */
49 | public func bringToFront() {
50 | if let parent = self.parent{
51 | removeFromParent()
52 | parent.addChild(self)
53 | }
54 | }
55 |
56 | /**
57 | * Orients the node in the direction that it is moving by tweening its
58 | * rotation angle. This assumes that at 0 degrees the node is facing up.
59 | *
60 | * @param velocity The current speed and direction of the node. You can get
61 | * this from node.physicsBody.velocity.
62 | * @param rate How fast the node rotates. Must have a value between 0.0 and
63 | * 1.0, where smaller means slower; 1.0 is instantaneous.
64 | */
65 | public func rotateToVelocity(velocity: CGVector, rate: CGFloat) {
66 | // Determine what the rotation angle of the node ought to be based on the
67 | // current velocity of its physics body. This assumes that at 0 degrees the
68 | // node is pointed up, not to the right, so to compensate we subtract π/4
69 | // (90 degrees) from the calculated angle.
70 | let newAngle = atan2(velocity.dy, velocity.dx) - π/2
71 |
72 | // This always makes the node rotate over the shortest possible distance.
73 | // Because the range of atan2() is -180 to 180 degrees, a rotation from,
74 | // -170 to -190 would otherwise be from -170 to 170, which makes the node
75 | // rotate the wrong way (and the long way) around. We adjust the angle to
76 | // go from 190 to 170 instead, which is equivalent to -170 to -190.
77 | if newAngle - zRotation > π {
78 | zRotation += π * 2.0
79 | } else if zRotation - newAngle > π {
80 | zRotation -= π * 2.0
81 | }
82 |
83 | // Use the "standard exponential slide" to slowly tween zRotation to the
84 | // new angle. The greater the value of rate, the faster this goes.
85 | zRotation += (newAngle - zRotation) * rate
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger/SKTUtils/SKTAudio.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013-2014 Razeware LLC
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import AVFoundation
24 |
25 | /**
26 | * Audio player that uses AVFoundation to play looping background music and
27 | * short sound effects. For when using SKActions just isn't good enough.
28 | */
29 | public class SKTAudio {
30 | public var backgroundMusicPlayer: AVAudioPlayer?
31 | public var soundEffectPlayer: AVAudioPlayer?
32 |
33 | public class func sharedInstance() -> SKTAudio {
34 | return SKTAudioInstance
35 | }
36 |
37 | public func playBackgroundMusic(filename: String) {
38 | let url = NSBundle.mainBundle().URLForResource(filename, withExtension: nil)
39 | if (url == nil) {
40 | println("Could not find file: \(filename)")
41 | return
42 | }
43 |
44 | var error: NSError? = nil
45 | backgroundMusicPlayer = AVAudioPlayer(contentsOfURL: url, error: &error)
46 | if let player = backgroundMusicPlayer {
47 | player.numberOfLoops = -1
48 | player.prepareToPlay()
49 | player.play()
50 | } else {
51 | println("Could not create audio player: \(error!)")
52 | }
53 | }
54 |
55 | public func pauseBackgroundMusic() {
56 | if let player = backgroundMusicPlayer {
57 | if player.playing {
58 | player.pause()
59 | }
60 | }
61 | }
62 |
63 | public func resumeBackgroundMusic() {
64 | if let player = backgroundMusicPlayer {
65 | if !player.playing {
66 | player.play()
67 | }
68 | }
69 | }
70 |
71 | public func playSoundEffect(filename: String) {
72 | let url = NSBundle.mainBundle().URLForResource(filename, withExtension: nil)
73 | if (url == nil) {
74 | println("Could not find file: \(filename)")
75 | return
76 | }
77 |
78 | var error: NSError? = nil
79 | soundEffectPlayer = AVAudioPlayer(contentsOfURL: url, error: &error)
80 | if let player = soundEffectPlayer {
81 | player.numberOfLoops = 0
82 | player.prepareToPlay()
83 | player.play()
84 | } else {
85 | println("Could not create audio player: \(error!)")
86 | }
87 | }
88 | }
89 |
90 | private let SKTAudioInstance = SKTAudio()
91 |
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger/assets.scnassets/Sounds/jump.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/1-Starter/SCNFrogger-1/SCNFrogger/assets.scnassets/Sounds/jump.wav
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger/assets.scnassets/Textures/hand.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/1-Starter/SCNFrogger-1/SCNFrogger/assets.scnassets/Textures/hand.png
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger/assets.scnassets/Textures/hand@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/1-Starter/SCNFrogger-1/SCNFrogger/assets.scnassets/Textures/hand@2x.png
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger/assets.scnassets/Textures/hand_click.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/1-Starter/SCNFrogger-1/SCNFrogger/assets.scnassets/Textures/hand_click.png
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger/assets.scnassets/Textures/hand_click@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/1-Starter/SCNFrogger-1/SCNFrogger/assets.scnassets/Textures/hand_click@2x.png
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFrogger/assets.scnassets/Textures/model_texture.tga:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/1-Starter/SCNFrogger-1/SCNFrogger/assets.scnassets/Textures/model_texture.tga
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFroggerTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | com.raywenderlich.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/1-Starter/SCNFrogger-1/SCNFroggerTests/SCNFroggerTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SCNFroggerTests.swift
3 | // SCNFroggerTests
4 | //
5 | // Created by Kim Pedersen on 02/12/14.
6 | // Copyright (c) 2014 RWDevCon. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import XCTest
11 |
12 | class SCNFroggerTests: XCTestCase {
13 |
14 | override func setUp() {
15 | super.setUp()
16 | // Put setup code here. This method is called before the invocation of each test method in the class.
17 | }
18 |
19 | override func tearDown() {
20 | // Put teardown code here. This method is called after the invocation of each test method in the class.
21 | super.tearDown()
22 | }
23 |
24 | func testExample() {
25 | // This is an example of a functional test case.
26 | XCTAssert(true, "Pass")
27 | }
28 |
29 | func testPerformanceExample() {
30 | // This is an example of a performance test case.
31 | self.measureBlock() {
32 | // Put the code you want to measure the time of here.
33 | }
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger.xcodeproj/project.xcworkspace/xcshareddata/SCNFrogger.xccheckout:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDESourceControlProjectFavoriteDictionaryKey
6 |
7 | IDESourceControlProjectIdentifier
8 | 6DE4669D-839D-4A6C-935D-D50EE5C00229
9 | IDESourceControlProjectName
10 | SCNFrogger
11 | IDESourceControlProjectOriginsDictionary
12 |
13 | C45253657BF1B0A67E13F808D5E653AC34B147B3
14 | https://github.com/devindazzle/SceneKitFrogger.git
15 |
16 | IDESourceControlProjectPath
17 | 2-Demo/SCNFrogger-2/SCNFrogger.xcodeproj
18 | IDESourceControlProjectRelativeInstallPathDictionary
19 |
20 | C45253657BF1B0A67E13F808D5E653AC34B147B3
21 | ../../../..
22 |
23 | IDESourceControlProjectURL
24 | https://github.com/devindazzle/SceneKitFrogger.git
25 | IDESourceControlProjectVersion
26 | 111
27 | IDESourceControlProjectWCCIdentifier
28 | C45253657BF1B0A67E13F808D5E653AC34B147B3
29 | IDESourceControlProjectWCConfigurations
30 |
31 |
32 | IDESourceControlRepositoryExtensionIdentifierKey
33 | public.vcs.git
34 | IDESourceControlWCCIdentifierKey
35 | C45253657BF1B0A67E13F808D5E653AC34B147B3
36 | IDESourceControlWCCName
37 | SceneKitFrogger
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger.xcodeproj/xcuserdata/kim.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger.xcodeproj/xcuserdata/kim.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | SCNFrogger.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 3BE6195A1A2DCDBA00ED80D7
16 |
17 | primary
18 |
19 |
20 | 3BE619711A2DCDBA00ED80D7
21 |
22 | primary
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // RWDevConSceneKitFinal
4 | //
5 | // Created by Kim Pedersen on 24/11/14.
6 | // Copyright (c) 2014 RWDevCon. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
17 | // Override point for customization after application launch.
18 | return true
19 | }
20 |
21 | func applicationWillResignActive(application: UIApplication) {
22 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
23 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
24 | }
25 |
26 | func applicationDidEnterBackground(application: UIApplication) {
27 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
28 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
29 | }
30 |
31 | func applicationWillEnterForeground(application: UIApplication) {
32 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
33 | }
34 |
35 | func applicationDidBecomeActive(application: UIApplication) {
36 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
37 | }
38 |
39 | func applicationWillTerminate(application: UIApplication) {
40 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
41 | }
42 |
43 |
44 | }
45 |
46 |
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger/Array2D.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Array2D.swift
3 | // RWDevConSceneKitFinal
4 | //
5 | // Created by Kim Pedersen on 24/11/14.
6 | // Copyright (c) 2014 RWDevCon. All rights reserved.
7 | //
8 |
9 | class Array2D {
10 |
11 | var cols: Int, rows: Int
12 | var data: [Int]
13 |
14 | init(cols columnCount: Int, rows rowCount: Int, value defaultValue: Int) {
15 | self.cols = columnCount
16 | self.rows = rowCount
17 | data = Array(count: cols * rows, repeatedValue: defaultValue)
18 | }
19 |
20 | subscript(column: Int, row: Int) -> Int {
21 | get {
22 | return data[cols * row + column]
23 | }
24 | set {
25 | data[cols * row + column] = newValue
26 | }
27 | }
28 |
29 | func columnCount() -> Int {
30 | return self.cols
31 | }
32 |
33 | func rowCount() -> Int {
34 | return self.rows
35 | }
36 |
37 | }
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger/Constants.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Constants.swift
3 | // SCNFrogger
4 | //
5 | // Created by Kim Pedersen on 11/12/14.
6 | // Copyright (c) 2014 RWDevCon. All rights reserved.
7 | //
8 |
9 | enum GameState {
10 | case WaitingForFirstTap
11 | case Playing
12 | case GameOver
13 | case RestartLevel
14 | }
15 |
16 |
17 | enum MoveDirection {
18 | case Forward
19 | case Backward
20 | case Left
21 | case Right
22 | }
23 |
24 |
25 | struct PhysicsCategory {
26 | static let None: Int = 0
27 | static let Player: Int = 0b1 // 1
28 | static let Car: Int = 0b10 // 2
29 | static let Obstacle: Int = 0b100 // 4
30 | }
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger/EarlyGameBoy.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/2-Demo/SCNFrogger-2/SCNFrogger/EarlyGameBoy.ttf
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger/GameViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GameViewController.swift
3 | // RWDevConSceneKitFinal
4 | //
5 | // Created by Kim Pedersen on 24/11/14.
6 | // Copyright (c) 2014 RWDevCon. All rights reserved.
7 | //
8 |
9 | import SceneKit
10 | import SpriteKit
11 |
12 | class GameViewController: UIViewController {
13 |
14 | var scnView: SCNView {
15 | get {
16 | return self.view as SCNView
17 | }
18 | }
19 |
20 | override func viewDidAppear(animated: Bool) {
21 |
22 | super.viewDidAppear(animated)
23 |
24 | // Set up the SCNView
25 | scnView.backgroundColor = UIColor(red: 100.0/255.0, green: 149.0/255.0, blue: 237.0/255.0, alpha: 1.0)
26 | scnView.showsStatistics = true
27 | scnView.antialiasingMode = SCNAntialiasingMode.Multisampling2X
28 | scnView.overlaySKScene = SKScene(size: view.bounds.size)
29 | scnView.playing = true
30 |
31 | // Set up the scene
32 | let scene = GameScene(view: scnView)
33 | scene.rootNode.hidden = true
34 | scene.physicsWorld.contactDelegate = scene
35 |
36 | // Start playing the scene
37 | scnView.scene = scene
38 | scnView.delegate = scene
39 | scnView.scene!.rootNode.hidden = false
40 | scnView.play(self)
41 | }
42 |
43 |
44 | override func shouldAutorotate() -> Bool {
45 | return true
46 | }
47 |
48 |
49 | override func prefersStatusBarHidden() -> Bool {
50 | return true
51 | }
52 |
53 |
54 | override func supportedInterfaceOrientations() -> Int {
55 | return Int(UIInterfaceOrientationMask.Portrait.rawValue)
56 | }
57 |
58 |
59 | override func didReceiveMemoryWarning() {
60 | super.didReceiveMemoryWarning()
61 | }
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger/HandNode.swift:
--------------------------------------------------------------------------------
1 | //
2 | // HandNode.swift
3 | // SCNFrogger
4 | //
5 | // Created by Kim Pedersen on 11/12/14.
6 | // Copyright (c) 2014 RWDevCon. All rights reserved.
7 | //
8 |
9 | import SpriteKit
10 |
11 | class HandNode : SKNode {
12 |
13 | override init() {
14 |
15 | super.init()
16 |
17 | name = "Tutorial"
18 |
19 | // Load textures
20 | let handTexture = SKTexture(imageNamed:"assets.scnassets/Textures/hand.png")
21 | handTexture.filteringMode = SKTextureFilteringMode.Nearest
22 | let handTextureClick = SKTexture(imageNamed:"assets.scnassets/Textures/hand_click.png")
23 | handTextureClick.filteringMode = SKTextureFilteringMode.Nearest
24 |
25 | // Create animation
26 | let handAnimation = SKAction.animateWithTextures([handTexture, handTextureClick], timePerFrame:0.5)
27 |
28 | // Create a sprite node abd animate it
29 | let handSprite = SKSpriteNode(texture: handTexture)
30 | handSprite.xScale = 2.0
31 | handSprite.yScale = 2.0
32 | handSprite.runAction(SKAction.repeatActionForever(handAnimation))
33 |
34 | addChild(handSprite)
35 | }
36 |
37 |
38 | required init?(coder aDecoder: NSCoder) {
39 | fatalError("init(coder:) has not been implemented")
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "29x29",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-Small@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "29x29",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-Small@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "40x40",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-40@2x.png",
19 | "scale" : "2x"
20 | },
21 | {
22 | "size" : "40x40",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-40@3x.png",
25 | "scale" : "3x"
26 | },
27 | {
28 | "size" : "60x60",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-60@2x.png",
31 | "scale" : "2x"
32 | },
33 | {
34 | "size" : "60x60",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-60@3x.png",
37 | "scale" : "3x"
38 | },
39 | {
40 | "size" : "29x29",
41 | "idiom" : "ipad",
42 | "filename" : "Icon-Small.png",
43 | "scale" : "1x"
44 | },
45 | {
46 | "size" : "29x29",
47 | "idiom" : "ipad",
48 | "filename" : "Icon-Small@2x-1.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "40x40",
53 | "idiom" : "ipad",
54 | "filename" : "Icon-40.png",
55 | "scale" : "1x"
56 | },
57 | {
58 | "size" : "40x40",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-40@2x-1.png",
61 | "scale" : "2x"
62 | },
63 | {
64 | "size" : "76x76",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-76.png",
67 | "scale" : "1x"
68 | },
69 | {
70 | "size" : "76x76",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-76@2x.png",
73 | "scale" : "2x"
74 | }
75 | ],
76 | "info" : {
77 | "version" : 1,
78 | "author" : "xcode"
79 | }
80 | }
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/2-Demo/SCNFrogger-2/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-40.png
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-40@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/2-Demo/SCNFrogger-2/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-40@2x-1.png
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/2-Demo/SCNFrogger-2/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-40@2x.png
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/2-Demo/SCNFrogger-2/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-40@3x.png
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/2-Demo/SCNFrogger-2/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-60@2x.png
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/2-Demo/SCNFrogger-2/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-60@3x.png
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/2-Demo/SCNFrogger-2/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-76.png
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/2-Demo/SCNFrogger-2/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-76@2x.png
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-Small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/2-Demo/SCNFrogger-2/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-Small.png
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-Small@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/2-Demo/SCNFrogger-2/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-Small@2x-1.png
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-Small@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/2-Demo/SCNFrogger-2/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-Small@2x.png
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-Small@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/2-Demo/SCNFrogger-2/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-Small@3x.png
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger/Images.xcassets/rwdevcon-bg.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x",
10 | "filename" : "rwdevcon-bg.png"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger/Images.xcassets/rwdevcon-bg.imageset/rwdevcon-bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/2-Demo/SCNFrogger-2/SCNFrogger/Images.xcassets/rwdevcon-bg.imageset/rwdevcon-bg.png
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger/Images.xcassets/rwdevcon-logo.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x",
10 | "filename" : "rwdevcon-logo.png"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger/Images.xcassets/rwdevcon-logo.imageset/rwdevcon-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/2-Demo/SCNFrogger-2/SCNFrogger/Images.xcassets/rwdevcon-logo.imageset/rwdevcon-logo.png
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | com.raywenderlich.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UIAppFonts
26 |
27 | EarlyGameBoy.ttf
28 |
29 | UILaunchStoryboardName
30 | LaunchScreen
31 | UIMainStoryboardFile
32 | Main
33 | UIRequiredDeviceCapabilities
34 |
35 | armv7
36 |
37 | UIStatusBarHidden
38 |
39 | UISupportedInterfaceOrientations
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 |
44 | UISupportedInterfaceOrientations~ipad
45 |
46 | UIInterfaceOrientationPortrait
47 | UIInterfaceOrientationPortraitUpsideDown
48 | UIInterfaceOrientationLandscapeLeft
49 | UIInterfaceOrientationLandscapeRight
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger/LabelNode.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LabelNode.swift
3 | // SCNFrogger
4 | //
5 | // Created by Kim Pedersen on 11/12/14.
6 | // Copyright (c) 2014 RWDevCon. All rights reserved.
7 | //
8 |
9 | import SpriteKit
10 |
11 | class LabelNode : SKLabelNode {
12 |
13 | init(position: CGPoint, size: CGFloat, color: SKColor, text: String, name: String) {
14 | super.init()
15 |
16 | self.name = name
17 | self.text = text
18 | self.position = position
19 |
20 | fontName = "Early-Gameboy"
21 | fontSize = size
22 | fontColor = color
23 | }
24 |
25 | required init?(coder aDecoder: NSCoder) {
26 | fatalError("init(coder:) has not been implemented")
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger/LaunchScreen.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger/SKTUtils/CGFloat+Extensions.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013-2014 Razeware LLC
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import CoreGraphics
24 |
25 | /** The value of π as a CGFloat */
26 | let π = CGFloat(M_PI)
27 |
28 | public extension CGFloat {
29 | /**
30 | * Converts an angle in degrees to radians.
31 | */
32 | public func degreesToRadians() -> CGFloat {
33 | return π * self / 180.0
34 | }
35 |
36 | /**
37 | * Converts an angle in radians to degrees.
38 | */
39 | public func radiansToDegrees() -> CGFloat {
40 | return self * 180.0 / π
41 | }
42 |
43 | /**
44 | * Ensures that the float value stays between the given values, inclusive.
45 | */
46 | public func clamped(v1: CGFloat, _ v2: CGFloat) -> CGFloat {
47 | let min = v1 < v2 ? v1 : v2
48 | let max = v1 > v2 ? v1 : v2
49 | return self < min ? min : (self > max ? max : self)
50 | }
51 |
52 | /**
53 | * Ensures that the float value stays between the given values, inclusive.
54 | */
55 | public mutating func clamp(v1: CGFloat, _ v2: CGFloat) -> CGFloat {
56 | self = clamped(v1, v2)
57 | return self
58 | }
59 |
60 | /**
61 | * Returns 1.0 if a floating point value is positive; -1.0 if it is negative.
62 | */
63 | public func sign() -> CGFloat {
64 | return (self >= 0.0) ? 1.0 : -1.0
65 | }
66 |
67 | /**
68 | * Returns a random floating point number between 0.0 and 1.0, inclusive.
69 | */
70 | public static func random() -> CGFloat {
71 | return CGFloat(Float(arc4random()) / 0xFFFFFFFF)
72 | }
73 |
74 | /**
75 | * Returns a random floating point number in the range min...max, inclusive.
76 | */
77 | public static func random(#min: CGFloat, max: CGFloat) -> CGFloat {
78 | assert(min < max)
79 | return CGFloat.random() * (max - min) + min
80 | }
81 |
82 | /**
83 | * Randomly returns either 1.0 or -1.0.
84 | */
85 | public static func randomSign() -> CGFloat {
86 | return (arc4random_uniform(2) == 0) ? 1.0 : -1.0
87 | }
88 | }
89 |
90 | /**
91 | * Returns the shortest angle between two angles. The result is always between
92 | * -π and π.
93 | */
94 | public func shortestAngleBetween(angle1: CGFloat, angle2: CGFloat) -> CGFloat {
95 | let twoπ = π * 2.0
96 | var angle = (angle2 - angle1) % twoπ
97 | if (angle >= π) {
98 | angle = angle - twoπ
99 | }
100 | if (angle <= -π) {
101 | angle = angle + twoπ
102 | }
103 | return angle
104 | }
105 |
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger/SKTUtils/Int+Extensions.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013-2014 Razeware LLC
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import CoreGraphics
24 |
25 | public extension Int {
26 | /**
27 | * Ensures that the integer value stays with the specified range.
28 | */
29 | public func clamped(range: Range) -> Int {
30 | return (self < range.startIndex) ? range.startIndex : ((self >= range.endIndex) ? range.endIndex - 1: self)
31 | }
32 |
33 | /**
34 | * Ensures that the integer value stays with the specified range.
35 | */
36 | public mutating func clamp(range: Range) -> Int {
37 | self = clamped(range)
38 | return self
39 | }
40 |
41 | /**
42 | * Ensures that the integer value stays between the given values, inclusive.
43 | */
44 | public func clamped(v1: Int, _ v2: Int) -> Int {
45 | let min = v1 < v2 ? v1 : v2
46 | let max = v1 > v2 ? v1 : v2
47 | return self < min ? min : (self > max ? max : self)
48 | }
49 |
50 | /**
51 | * Ensures that the integer value stays between the given values, inclusive.
52 | */
53 | public mutating func clamp(v1: Int, _ v2: Int) -> Int {
54 | self = clamped(v1, v2)
55 | return self
56 | }
57 |
58 | /**
59 | * Returns a random integer in the specified range.
60 | */
61 | public static func random(range: Range) -> Int {
62 | return Int(arc4random_uniform(UInt32(range.endIndex - range.startIndex))) + range.startIndex
63 | }
64 |
65 | /**
66 | * Returns a random integer between 0 and n-1.
67 | */
68 | public static func random(n: Int) -> Int {
69 | return Int(arc4random_uniform(UInt32(n)))
70 | }
71 |
72 | /**
73 | * Returns a random integer in the range min...max, inclusive.
74 | */
75 | public static func random(#min: Int, max: Int) -> Int {
76 | assert(min < max)
77 | return Int(arc4random_uniform(UInt32(max - min + 1))) + min
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger/SKTUtils/SKAction+Extensions.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013-2014 Razeware LLC
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import SpriteKit
24 |
25 | public extension SKAction {
26 | /**
27 | * Performs an action after the specified delay.
28 | */
29 | public class func afterDelay(delay: NSTimeInterval, performAction action: SKAction) -> SKAction {
30 | return SKAction.sequence([SKAction.waitForDuration(delay), action])
31 | }
32 |
33 | /**
34 | * Performs a block after the specified delay.
35 | */
36 | public class func afterDelay(delay: NSTimeInterval, runBlock block: dispatch_block_t) -> SKAction {
37 | return SKAction.afterDelay(delay, performAction: SKAction.runBlock(block))
38 | }
39 |
40 | /**
41 | * Removes the node from its parent after the specified delay.
42 | */
43 | public class func removeFromParentAfterDelay(delay: NSTimeInterval) -> SKAction {
44 | return SKAction.afterDelay(delay, performAction: SKAction.removeFromParent())
45 | }
46 |
47 | /**
48 | * Creates an action to perform a parabolic jump.
49 | */
50 | public class func jumpToHeight(height: CGFloat, duration: NSTimeInterval, originalPosition: CGPoint) -> SKAction {
51 | return SKAction.customActionWithDuration(duration) {(node, elapsedTime) in
52 | let fraction = elapsedTime / CGFloat(duration)
53 | let yOffset = height * 4 * fraction * (1 - fraction)
54 | node.position = CGPoint(x: originalPosition.x, y: originalPosition.y + yOffset)
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger/SKTUtils/SKAction+SpecialEffects.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013-2014 Razeware LLC
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import SpriteKit
24 |
25 | public extension SKAction {
26 | /**
27 | * Creates a screen shake animation.
28 | *
29 | * @param node The node to shake. You cannot apply this effect to an SKScene.
30 | * @param amount The vector by which the node is displaced.
31 | * @param oscillations The number of oscillations; 10 is a good value.
32 | * @param duration How long the effect lasts. Shorter is better.
33 | */
34 | public class func screenShakeWithNode(node: SKNode, amount: CGPoint, oscillations: Int, duration: NSTimeInterval) -> SKAction {
35 | let oldPosition = node.position
36 | let newPosition = oldPosition + amount
37 |
38 | let effect = SKTMoveEffect(node: node, duration: duration, startPosition: newPosition, endPosition: oldPosition)
39 | effect.timingFunction = SKTCreateShakeFunction(oscillations)
40 |
41 | return SKAction.actionWithEffect(effect)
42 | }
43 |
44 | /**
45 | * Creates a screen rotation animation.
46 | *
47 | * @param node You usually want to apply this effect to a pivot node that is
48 | * centered in the scene. You cannot apply the effect to an SKScene.
49 | * @param angle The angle in radians.
50 | * @param oscillations The number of oscillations; 10 is a good value.
51 | * @param duration How long the effect lasts. Shorter is better.
52 | */
53 | public class func screenRotateWithNode(node: SKNode, angle: CGFloat, oscillations: Int, duration: NSTimeInterval) -> SKAction {
54 | let oldAngle = node.zRotation
55 | let newAngle = oldAngle + angle
56 |
57 | let effect = SKTRotateEffect(node: node, duration: duration, startAngle: newAngle, endAngle: oldAngle)
58 | effect.timingFunction = SKTCreateShakeFunction(oscillations)
59 |
60 | return SKAction.actionWithEffect(effect)
61 | }
62 |
63 | /**
64 | * Creates a screen zoom animation.
65 | *
66 | * @param node You usually want to apply this effect to a pivot node that is
67 | * centered in the scene. You cannot apply the effect to an SKScene.
68 | * @param amount How much to scale the node in the X and Y directions.
69 | * @param oscillations The number of oscillations; 10 is a good value.
70 | * @param duration How long the effect lasts. Shorter is better.
71 | */
72 | public class func screenZoomWithNode(node: SKNode, amount: CGPoint, oscillations: Int, duration: NSTimeInterval) -> SKAction {
73 | let oldScale = CGPoint(x: node.xScale, y: node.yScale)
74 | let newScale = oldScale * amount
75 |
76 | let effect = SKTScaleEffect(node: node, duration: duration, startScale: newScale, endScale: oldScale)
77 | effect.timingFunction = SKTCreateShakeFunction(oscillations)
78 |
79 | return SKAction.actionWithEffect(effect)
80 | }
81 |
82 | /**
83 | * Causes the scene background to flash for duration seconds.
84 | */
85 | public class func colorGlitchWithScene(scene: SKScene, originalColor: SKColor, duration: NSTimeInterval) -> SKAction {
86 | return SKAction.customActionWithDuration(duration) {(node, elapsedTime) in
87 | if elapsedTime < CGFloat(duration) {
88 | scene.backgroundColor = SKColorWithRGB(Int.random(0...255), Int.random(0...255), Int.random(0...255))
89 | } else {
90 | scene.backgroundColor = originalColor
91 | }
92 | }
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger/SKTUtils/SKColor+Extensions.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013-2014 Razeware LLC
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import SpriteKit
24 |
25 | public func SKColorWithRGB(r: Int, g: Int, b: Int) -> SKColor {
26 | return SKColor(red: CGFloat(r)/255.0, green: CGFloat(g)/255.0, blue: CGFloat(b)/255.0, alpha: 1.0)
27 | }
28 |
29 | public func SKColorWithRGBA(r: Int, g: Int, b: Int, a: Int) -> SKColor {
30 | return SKColor(red: CGFloat(r)/255.0, green: CGFloat(g)/255.0, blue: CGFloat(b)/255.0, alpha: CGFloat(a)/255.0)
31 | }
32 |
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger/SKTUtils/SKNode+Extensions.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013-2014 Razeware LLC
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import SpriteKit
24 |
25 | public extension SKNode {
26 |
27 | /** Lets you treat the node's scale as a CGPoint value. */
28 | public var scaleAsPoint: CGPoint {
29 | get {
30 | return CGPoint(x: xScale, y: yScale)
31 | }
32 | set {
33 | xScale = newValue.x
34 | yScale = newValue.y
35 | }
36 | }
37 |
38 | /**
39 | * Runs an action on the node that performs a closure or function after
40 | * a given time.
41 | */
42 | public func afterDelay(delay: NSTimeInterval, runBlock block: dispatch_block_t) {
43 | runAction(SKAction.sequence([SKAction.waitForDuration(delay), SKAction.runBlock(block)]))
44 | }
45 |
46 | /**
47 | * Makes this node the frontmost node in its parent.
48 | */
49 | public func bringToFront() {
50 | if let parent = self.parent{
51 | removeFromParent()
52 | parent.addChild(self)
53 | }
54 | }
55 |
56 | /**
57 | * Orients the node in the direction that it is moving by tweening its
58 | * rotation angle. This assumes that at 0 degrees the node is facing up.
59 | *
60 | * @param velocity The current speed and direction of the node. You can get
61 | * this from node.physicsBody.velocity.
62 | * @param rate How fast the node rotates. Must have a value between 0.0 and
63 | * 1.0, where smaller means slower; 1.0 is instantaneous.
64 | */
65 | public func rotateToVelocity(velocity: CGVector, rate: CGFloat) {
66 | // Determine what the rotation angle of the node ought to be based on the
67 | // current velocity of its physics body. This assumes that at 0 degrees the
68 | // node is pointed up, not to the right, so to compensate we subtract π/4
69 | // (90 degrees) from the calculated angle.
70 | let newAngle = atan2(velocity.dy, velocity.dx) - π/2
71 |
72 | // This always makes the node rotate over the shortest possible distance.
73 | // Because the range of atan2() is -180 to 180 degrees, a rotation from,
74 | // -170 to -190 would otherwise be from -170 to 170, which makes the node
75 | // rotate the wrong way (and the long way) around. We adjust the angle to
76 | // go from 190 to 170 instead, which is equivalent to -170 to -190.
77 | if newAngle - zRotation > π {
78 | zRotation += π * 2.0
79 | } else if zRotation - newAngle > π {
80 | zRotation -= π * 2.0
81 | }
82 |
83 | // Use the "standard exponential slide" to slowly tween zRotation to the
84 | // new angle. The greater the value of rate, the faster this goes.
85 | zRotation += (newAngle - zRotation) * rate
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger/SKTUtils/SKTAudio.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013-2014 Razeware LLC
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import AVFoundation
24 |
25 | /**
26 | * Audio player that uses AVFoundation to play looping background music and
27 | * short sound effects. For when using SKActions just isn't good enough.
28 | */
29 | public class SKTAudio {
30 | public var backgroundMusicPlayer: AVAudioPlayer?
31 | public var soundEffectPlayer: AVAudioPlayer?
32 |
33 | public class func sharedInstance() -> SKTAudio {
34 | return SKTAudioInstance
35 | }
36 |
37 | public func playBackgroundMusic(filename: String) {
38 | let url = NSBundle.mainBundle().URLForResource(filename, withExtension: nil)
39 | if (url == nil) {
40 | println("Could not find file: \(filename)")
41 | return
42 | }
43 |
44 | var error: NSError? = nil
45 | backgroundMusicPlayer = AVAudioPlayer(contentsOfURL: url, error: &error)
46 | if let player = backgroundMusicPlayer {
47 | player.numberOfLoops = -1
48 | player.prepareToPlay()
49 | player.play()
50 | } else {
51 | println("Could not create audio player: \(error!)")
52 | }
53 | }
54 |
55 | public func pauseBackgroundMusic() {
56 | if let player = backgroundMusicPlayer {
57 | if player.playing {
58 | player.pause()
59 | }
60 | }
61 | }
62 |
63 | public func resumeBackgroundMusic() {
64 | if let player = backgroundMusicPlayer {
65 | if !player.playing {
66 | player.play()
67 | }
68 | }
69 | }
70 |
71 | public func playSoundEffect(filename: String) {
72 | let url = NSBundle.mainBundle().URLForResource(filename, withExtension: nil)
73 | if (url == nil) {
74 | println("Could not find file: \(filename)")
75 | return
76 | }
77 |
78 | var error: NSError? = nil
79 | soundEffectPlayer = AVAudioPlayer(contentsOfURL: url, error: &error)
80 | if let player = soundEffectPlayer {
81 | player.numberOfLoops = 0
82 | player.prepareToPlay()
83 | player.play()
84 | } else {
85 | println("Could not create audio player: \(error!)")
86 | }
87 | }
88 | }
89 |
90 | private let SKTAudioInstance = SKTAudio()
91 |
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger/assets.scnassets/Sounds/jump.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/2-Demo/SCNFrogger-2/SCNFrogger/assets.scnassets/Sounds/jump.wav
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger/assets.scnassets/Textures/hand.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/2-Demo/SCNFrogger-2/SCNFrogger/assets.scnassets/Textures/hand.png
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger/assets.scnassets/Textures/hand@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/2-Demo/SCNFrogger-2/SCNFrogger/assets.scnassets/Textures/hand@2x.png
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger/assets.scnassets/Textures/hand_click.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/2-Demo/SCNFrogger-2/SCNFrogger/assets.scnassets/Textures/hand_click.png
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger/assets.scnassets/Textures/hand_click@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/2-Demo/SCNFrogger-2/SCNFrogger/assets.scnassets/Textures/hand_click@2x.png
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFrogger/assets.scnassets/Textures/model_texture.tga:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/2-Demo/SCNFrogger-2/SCNFrogger/assets.scnassets/Textures/model_texture.tga
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFroggerTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | com.raywenderlich.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/2-Demo/SCNFrogger-2/SCNFroggerTests/SCNFroggerTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SCNFroggerTests.swift
3 | // SCNFroggerTests
4 | //
5 | // Created by Kim Pedersen on 02/12/14.
6 | // Copyright (c) 2014 RWDevCon. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import XCTest
11 |
12 | class SCNFroggerTests: XCTestCase {
13 |
14 | override func setUp() {
15 | super.setUp()
16 | // Put setup code here. This method is called before the invocation of each test method in the class.
17 | }
18 |
19 | override func tearDown() {
20 | // Put teardown code here. This method is called after the invocation of each test method in the class.
21 | super.tearDown()
22 | }
23 |
24 | func testExample() {
25 | // This is an example of a functional test case.
26 | XCTAssert(true, "Pass")
27 | }
28 |
29 | func testPerformanceExample() {
30 | // This is an example of a performance test case.
31 | self.measureBlock() {
32 | // Put the code you want to measure the time of here.
33 | }
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/3-Lab/3-LabImages/SCNSceneRendererDelegate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/3-Lab/3-LabImages/SCNSceneRendererDelegate.png
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger.xcodeproj/project.xcworkspace/xcshareddata/SCNFrogger.xccheckout:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDESourceControlProjectFavoriteDictionaryKey
6 |
7 | IDESourceControlProjectIdentifier
8 | 6DE4669D-839D-4A6C-935D-D50EE5C00229
9 | IDESourceControlProjectName
10 | SCNFrogger
11 | IDESourceControlProjectOriginsDictionary
12 |
13 | C45253657BF1B0A67E13F808D5E653AC34B147B3
14 | https://github.com/devindazzle/SceneKitFrogger.git
15 |
16 | IDESourceControlProjectPath
17 | 3-Lab/SCNFrogger-3/SCNFrogger.xcodeproj
18 | IDESourceControlProjectRelativeInstallPathDictionary
19 |
20 | C45253657BF1B0A67E13F808D5E653AC34B147B3
21 | ../../../..
22 |
23 | IDESourceControlProjectURL
24 | https://github.com/devindazzle/SceneKitFrogger.git
25 | IDESourceControlProjectVersion
26 | 111
27 | IDESourceControlProjectWCCIdentifier
28 | C45253657BF1B0A67E13F808D5E653AC34B147B3
29 | IDESourceControlProjectWCConfigurations
30 |
31 |
32 | IDESourceControlRepositoryExtensionIdentifierKey
33 | public.vcs.git
34 | IDESourceControlWCCIdentifierKey
35 | C45253657BF1B0A67E13F808D5E653AC34B147B3
36 | IDESourceControlWCCName
37 | SceneKitFrogger
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger.xcodeproj/xcuserdata/kim.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger.xcodeproj/xcuserdata/kim.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | SCNFrogger.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 3BE6195A1A2DCDBA00ED80D7
16 |
17 | primary
18 |
19 |
20 | 3BE619711A2DCDBA00ED80D7
21 |
22 | primary
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // RWDevConSceneKitFinal
4 | //
5 | // Created by Kim Pedersen on 24/11/14.
6 | // Copyright (c) 2014 RWDevCon. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
17 | // Override point for customization after application launch.
18 | return true
19 | }
20 |
21 | func applicationWillResignActive(application: UIApplication) {
22 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
23 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
24 | }
25 |
26 | func applicationDidEnterBackground(application: UIApplication) {
27 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
28 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
29 | }
30 |
31 | func applicationWillEnterForeground(application: UIApplication) {
32 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
33 | }
34 |
35 | func applicationDidBecomeActive(application: UIApplication) {
36 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
37 | }
38 |
39 | func applicationWillTerminate(application: UIApplication) {
40 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
41 | }
42 |
43 |
44 | }
45 |
46 |
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger/Array2D.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Array2D.swift
3 | // RWDevConSceneKitFinal
4 | //
5 | // Created by Kim Pedersen on 24/11/14.
6 | // Copyright (c) 2014 RWDevCon. All rights reserved.
7 | //
8 |
9 | class Array2D {
10 |
11 | var cols: Int, rows: Int
12 | var data: [Int]
13 |
14 | init(cols columnCount: Int, rows rowCount: Int, value defaultValue: Int) {
15 | self.cols = columnCount
16 | self.rows = rowCount
17 | data = Array(count: cols * rows, repeatedValue: defaultValue)
18 | }
19 |
20 | subscript(column: Int, row: Int) -> Int {
21 | get {
22 | return data[cols * row + column]
23 | }
24 | set {
25 | data[cols * row + column] = newValue
26 | }
27 | }
28 |
29 | func columnCount() -> Int {
30 | return self.cols
31 | }
32 |
33 | func rowCount() -> Int {
34 | return self.rows
35 | }
36 |
37 | }
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger/Constants.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Constants.swift
3 | // SCNFrogger
4 | //
5 | // Created by Kim Pedersen on 11/12/14.
6 | // Copyright (c) 2014 RWDevCon. All rights reserved.
7 | //
8 |
9 | enum GameState {
10 | case WaitingForFirstTap
11 | case Playing
12 | case GameOver
13 | case RestartLevel
14 | }
15 |
16 |
17 | enum MoveDirection {
18 | case Forward
19 | case Backward
20 | case Left
21 | case Right
22 | }
23 |
24 |
25 | struct PhysicsCategory {
26 | static let None: Int = 0
27 | static let Player: Int = 0b1 // 1
28 | static let Car: Int = 0b10 // 2
29 | static let Obstacle: Int = 0b100 // 4
30 | }
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger/EarlyGameBoy.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/3-Lab/SCNFrogger-3/SCNFrogger/EarlyGameBoy.ttf
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger/GameViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GameViewController.swift
3 | // RWDevConSceneKitFinal
4 | //
5 | // Created by Kim Pedersen on 24/11/14.
6 | // Copyright (c) 2014 RWDevCon. All rights reserved.
7 | //
8 |
9 | import SceneKit
10 | import SpriteKit
11 |
12 | class GameViewController: UIViewController {
13 |
14 | var scnView: SCNView {
15 | get {
16 | return self.view as SCNView
17 | }
18 | }
19 |
20 | override func viewDidAppear(animated: Bool) {
21 |
22 | super.viewDidAppear(animated)
23 |
24 | // Set up the SCNView
25 | scnView.backgroundColor = UIColor(red: 100.0/255.0, green: 149.0/255.0, blue: 237.0/255.0, alpha: 1.0)
26 | scnView.showsStatistics = true
27 | scnView.antialiasingMode = SCNAntialiasingMode.Multisampling2X
28 | scnView.overlaySKScene = SKScene(size: view.bounds.size)
29 | scnView.playing = true
30 |
31 | // Set up the scene
32 | let scene = GameScene(view: scnView)
33 | scene.rootNode.hidden = true
34 | scene.physicsWorld.contactDelegate = scene
35 |
36 | // Start playing the scene
37 | scnView.scene = scene
38 | scnView.delegate = scene
39 | scnView.scene!.rootNode.hidden = false
40 | scnView.play(self)
41 | }
42 |
43 |
44 | override func shouldAutorotate() -> Bool {
45 | return true
46 | }
47 |
48 |
49 | override func prefersStatusBarHidden() -> Bool {
50 | return true
51 | }
52 |
53 |
54 | override func supportedInterfaceOrientations() -> Int {
55 | return Int(UIInterfaceOrientationMask.Portrait.rawValue)
56 | }
57 |
58 |
59 | override func didReceiveMemoryWarning() {
60 | super.didReceiveMemoryWarning()
61 | }
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger/HandNode.swift:
--------------------------------------------------------------------------------
1 | //
2 | // HandNode.swift
3 | // SCNFrogger
4 | //
5 | // Created by Kim Pedersen on 11/12/14.
6 | // Copyright (c) 2014 RWDevCon. All rights reserved.
7 | //
8 |
9 | import SpriteKit
10 |
11 | class HandNode : SKNode {
12 |
13 | override init() {
14 |
15 | super.init()
16 |
17 | name = "Tutorial"
18 |
19 | // Load textures
20 | let handTexture = SKTexture(imageNamed:"assets.scnassets/Textures/hand.png")
21 | handTexture.filteringMode = SKTextureFilteringMode.Nearest
22 | let handTextureClick = SKTexture(imageNamed:"assets.scnassets/Textures/hand_click.png")
23 | handTextureClick.filteringMode = SKTextureFilteringMode.Nearest
24 |
25 | // Create animation
26 | let handAnimation = SKAction.animateWithTextures([handTexture, handTextureClick], timePerFrame:0.5)
27 |
28 | // Create a sprite node abd animate it
29 | let handSprite = SKSpriteNode(texture: handTexture)
30 | handSprite.xScale = 2.0
31 | handSprite.yScale = 2.0
32 | handSprite.runAction(SKAction.repeatActionForever(handAnimation))
33 |
34 | addChild(handSprite)
35 | }
36 |
37 |
38 | required init?(coder aDecoder: NSCoder) {
39 | fatalError("init(coder:) has not been implemented")
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "29x29",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-Small@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "29x29",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-Small@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "40x40",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-40@2x.png",
19 | "scale" : "2x"
20 | },
21 | {
22 | "size" : "40x40",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-40@3x.png",
25 | "scale" : "3x"
26 | },
27 | {
28 | "size" : "60x60",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-60@2x.png",
31 | "scale" : "2x"
32 | },
33 | {
34 | "size" : "60x60",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-60@3x.png",
37 | "scale" : "3x"
38 | },
39 | {
40 | "size" : "29x29",
41 | "idiom" : "ipad",
42 | "filename" : "Icon-Small.png",
43 | "scale" : "1x"
44 | },
45 | {
46 | "size" : "29x29",
47 | "idiom" : "ipad",
48 | "filename" : "Icon-Small@2x-1.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "40x40",
53 | "idiom" : "ipad",
54 | "filename" : "Icon-40.png",
55 | "scale" : "1x"
56 | },
57 | {
58 | "size" : "40x40",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-40@2x-1.png",
61 | "scale" : "2x"
62 | },
63 | {
64 | "size" : "76x76",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-76.png",
67 | "scale" : "1x"
68 | },
69 | {
70 | "size" : "76x76",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-76@2x.png",
73 | "scale" : "2x"
74 | }
75 | ],
76 | "info" : {
77 | "version" : 1,
78 | "author" : "xcode"
79 | }
80 | }
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/3-Lab/SCNFrogger-3/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-40.png
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-40@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/3-Lab/SCNFrogger-3/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-40@2x-1.png
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/3-Lab/SCNFrogger-3/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-40@2x.png
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/3-Lab/SCNFrogger-3/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-40@3x.png
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/3-Lab/SCNFrogger-3/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-60@2x.png
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/3-Lab/SCNFrogger-3/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-60@3x.png
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/3-Lab/SCNFrogger-3/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-76.png
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/3-Lab/SCNFrogger-3/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-76@2x.png
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-Small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/3-Lab/SCNFrogger-3/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-Small.png
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-Small@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/3-Lab/SCNFrogger-3/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-Small@2x-1.png
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-Small@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/3-Lab/SCNFrogger-3/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-Small@2x.png
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-Small@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/3-Lab/SCNFrogger-3/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-Small@3x.png
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger/Images.xcassets/rwdevcon-bg.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x",
10 | "filename" : "rwdevcon-bg.png"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger/Images.xcassets/rwdevcon-bg.imageset/rwdevcon-bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/3-Lab/SCNFrogger-3/SCNFrogger/Images.xcassets/rwdevcon-bg.imageset/rwdevcon-bg.png
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger/Images.xcassets/rwdevcon-logo.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x",
10 | "filename" : "rwdevcon-logo.png"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger/Images.xcassets/rwdevcon-logo.imageset/rwdevcon-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/3-Lab/SCNFrogger-3/SCNFrogger/Images.xcassets/rwdevcon-logo.imageset/rwdevcon-logo.png
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | com.raywenderlich.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UIAppFonts
26 |
27 | EarlyGameBoy.ttf
28 |
29 | UILaunchStoryboardName
30 | LaunchScreen
31 | UIMainStoryboardFile
32 | Main
33 | UIRequiredDeviceCapabilities
34 |
35 | armv7
36 |
37 | UIStatusBarHidden
38 |
39 | UISupportedInterfaceOrientations
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 |
44 | UISupportedInterfaceOrientations~ipad
45 |
46 | UIInterfaceOrientationPortrait
47 | UIInterfaceOrientationPortraitUpsideDown
48 | UIInterfaceOrientationLandscapeLeft
49 | UIInterfaceOrientationLandscapeRight
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger/LabelNode.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LabelNode.swift
3 | // SCNFrogger
4 | //
5 | // Created by Kim Pedersen on 11/12/14.
6 | // Copyright (c) 2014 RWDevCon. All rights reserved.
7 | //
8 |
9 | import SpriteKit
10 |
11 | class LabelNode : SKLabelNode {
12 |
13 | init(position: CGPoint, size: CGFloat, color: SKColor, text: String, name: String) {
14 | super.init()
15 |
16 | self.name = name
17 | self.text = text
18 | self.position = position
19 |
20 | fontName = "Early-Gameboy"
21 | fontSize = size
22 | fontColor = color
23 | }
24 |
25 | required init?(coder aDecoder: NSCoder) {
26 | fatalError("init(coder:) has not been implemented")
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger/LaunchScreen.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger/SKTUtils/CGFloat+Extensions.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013-2014 Razeware LLC
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import CoreGraphics
24 |
25 | /** The value of π as a CGFloat */
26 | let π = CGFloat(M_PI)
27 |
28 | public extension CGFloat {
29 | /**
30 | * Converts an angle in degrees to radians.
31 | */
32 | public func degreesToRadians() -> CGFloat {
33 | return π * self / 180.0
34 | }
35 |
36 | /**
37 | * Converts an angle in radians to degrees.
38 | */
39 | public func radiansToDegrees() -> CGFloat {
40 | return self * 180.0 / π
41 | }
42 |
43 | /**
44 | * Ensures that the float value stays between the given values, inclusive.
45 | */
46 | public func clamped(v1: CGFloat, _ v2: CGFloat) -> CGFloat {
47 | let min = v1 < v2 ? v1 : v2
48 | let max = v1 > v2 ? v1 : v2
49 | return self < min ? min : (self > max ? max : self)
50 | }
51 |
52 | /**
53 | * Ensures that the float value stays between the given values, inclusive.
54 | */
55 | public mutating func clamp(v1: CGFloat, _ v2: CGFloat) -> CGFloat {
56 | self = clamped(v1, v2)
57 | return self
58 | }
59 |
60 | /**
61 | * Returns 1.0 if a floating point value is positive; -1.0 if it is negative.
62 | */
63 | public func sign() -> CGFloat {
64 | return (self >= 0.0) ? 1.0 : -1.0
65 | }
66 |
67 | /**
68 | * Returns a random floating point number between 0.0 and 1.0, inclusive.
69 | */
70 | public static func random() -> CGFloat {
71 | return CGFloat(Float(arc4random()) / 0xFFFFFFFF)
72 | }
73 |
74 | /**
75 | * Returns a random floating point number in the range min...max, inclusive.
76 | */
77 | public static func random(#min: CGFloat, max: CGFloat) -> CGFloat {
78 | assert(min < max)
79 | return CGFloat.random() * (max - min) + min
80 | }
81 |
82 | /**
83 | * Randomly returns either 1.0 or -1.0.
84 | */
85 | public static func randomSign() -> CGFloat {
86 | return (arc4random_uniform(2) == 0) ? 1.0 : -1.0
87 | }
88 | }
89 |
90 | /**
91 | * Returns the shortest angle between two angles. The result is always between
92 | * -π and π.
93 | */
94 | public func shortestAngleBetween(angle1: CGFloat, angle2: CGFloat) -> CGFloat {
95 | let twoπ = π * 2.0
96 | var angle = (angle2 - angle1) % twoπ
97 | if (angle >= π) {
98 | angle = angle - twoπ
99 | }
100 | if (angle <= -π) {
101 | angle = angle + twoπ
102 | }
103 | return angle
104 | }
105 |
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger/SKTUtils/Int+Extensions.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013-2014 Razeware LLC
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import CoreGraphics
24 |
25 | public extension Int {
26 | /**
27 | * Ensures that the integer value stays with the specified range.
28 | */
29 | public func clamped(range: Range) -> Int {
30 | return (self < range.startIndex) ? range.startIndex : ((self >= range.endIndex) ? range.endIndex - 1: self)
31 | }
32 |
33 | /**
34 | * Ensures that the integer value stays with the specified range.
35 | */
36 | public mutating func clamp(range: Range) -> Int {
37 | self = clamped(range)
38 | return self
39 | }
40 |
41 | /**
42 | * Ensures that the integer value stays between the given values, inclusive.
43 | */
44 | public func clamped(v1: Int, _ v2: Int) -> Int {
45 | let min = v1 < v2 ? v1 : v2
46 | let max = v1 > v2 ? v1 : v2
47 | return self < min ? min : (self > max ? max : self)
48 | }
49 |
50 | /**
51 | * Ensures that the integer value stays between the given values, inclusive.
52 | */
53 | public mutating func clamp(v1: Int, _ v2: Int) -> Int {
54 | self = clamped(v1, v2)
55 | return self
56 | }
57 |
58 | /**
59 | * Returns a random integer in the specified range.
60 | */
61 | public static func random(range: Range) -> Int {
62 | return Int(arc4random_uniform(UInt32(range.endIndex - range.startIndex))) + range.startIndex
63 | }
64 |
65 | /**
66 | * Returns a random integer between 0 and n-1.
67 | */
68 | public static func random(n: Int) -> Int {
69 | return Int(arc4random_uniform(UInt32(n)))
70 | }
71 |
72 | /**
73 | * Returns a random integer in the range min...max, inclusive.
74 | */
75 | public static func random(#min: Int, max: Int) -> Int {
76 | assert(min < max)
77 | return Int(arc4random_uniform(UInt32(max - min + 1))) + min
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger/SKTUtils/SKAction+Extensions.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013-2014 Razeware LLC
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import SpriteKit
24 |
25 | public extension SKAction {
26 | /**
27 | * Performs an action after the specified delay.
28 | */
29 | public class func afterDelay(delay: NSTimeInterval, performAction action: SKAction) -> SKAction {
30 | return SKAction.sequence([SKAction.waitForDuration(delay), action])
31 | }
32 |
33 | /**
34 | * Performs a block after the specified delay.
35 | */
36 | public class func afterDelay(delay: NSTimeInterval, runBlock block: dispatch_block_t) -> SKAction {
37 | return SKAction.afterDelay(delay, performAction: SKAction.runBlock(block))
38 | }
39 |
40 | /**
41 | * Removes the node from its parent after the specified delay.
42 | */
43 | public class func removeFromParentAfterDelay(delay: NSTimeInterval) -> SKAction {
44 | return SKAction.afterDelay(delay, performAction: SKAction.removeFromParent())
45 | }
46 |
47 | /**
48 | * Creates an action to perform a parabolic jump.
49 | */
50 | public class func jumpToHeight(height: CGFloat, duration: NSTimeInterval, originalPosition: CGPoint) -> SKAction {
51 | return SKAction.customActionWithDuration(duration) {(node, elapsedTime) in
52 | let fraction = elapsedTime / CGFloat(duration)
53 | let yOffset = height * 4 * fraction * (1 - fraction)
54 | node.position = CGPoint(x: originalPosition.x, y: originalPosition.y + yOffset)
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger/SKTUtils/SKAction+SpecialEffects.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013-2014 Razeware LLC
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import SpriteKit
24 |
25 | public extension SKAction {
26 | /**
27 | * Creates a screen shake animation.
28 | *
29 | * @param node The node to shake. You cannot apply this effect to an SKScene.
30 | * @param amount The vector by which the node is displaced.
31 | * @param oscillations The number of oscillations; 10 is a good value.
32 | * @param duration How long the effect lasts. Shorter is better.
33 | */
34 | public class func screenShakeWithNode(node: SKNode, amount: CGPoint, oscillations: Int, duration: NSTimeInterval) -> SKAction {
35 | let oldPosition = node.position
36 | let newPosition = oldPosition + amount
37 |
38 | let effect = SKTMoveEffect(node: node, duration: duration, startPosition: newPosition, endPosition: oldPosition)
39 | effect.timingFunction = SKTCreateShakeFunction(oscillations)
40 |
41 | return SKAction.actionWithEffect(effect)
42 | }
43 |
44 | /**
45 | * Creates a screen rotation animation.
46 | *
47 | * @param node You usually want to apply this effect to a pivot node that is
48 | * centered in the scene. You cannot apply the effect to an SKScene.
49 | * @param angle The angle in radians.
50 | * @param oscillations The number of oscillations; 10 is a good value.
51 | * @param duration How long the effect lasts. Shorter is better.
52 | */
53 | public class func screenRotateWithNode(node: SKNode, angle: CGFloat, oscillations: Int, duration: NSTimeInterval) -> SKAction {
54 | let oldAngle = node.zRotation
55 | let newAngle = oldAngle + angle
56 |
57 | let effect = SKTRotateEffect(node: node, duration: duration, startAngle: newAngle, endAngle: oldAngle)
58 | effect.timingFunction = SKTCreateShakeFunction(oscillations)
59 |
60 | return SKAction.actionWithEffect(effect)
61 | }
62 |
63 | /**
64 | * Creates a screen zoom animation.
65 | *
66 | * @param node You usually want to apply this effect to a pivot node that is
67 | * centered in the scene. You cannot apply the effect to an SKScene.
68 | * @param amount How much to scale the node in the X and Y directions.
69 | * @param oscillations The number of oscillations; 10 is a good value.
70 | * @param duration How long the effect lasts. Shorter is better.
71 | */
72 | public class func screenZoomWithNode(node: SKNode, amount: CGPoint, oscillations: Int, duration: NSTimeInterval) -> SKAction {
73 | let oldScale = CGPoint(x: node.xScale, y: node.yScale)
74 | let newScale = oldScale * amount
75 |
76 | let effect = SKTScaleEffect(node: node, duration: duration, startScale: newScale, endScale: oldScale)
77 | effect.timingFunction = SKTCreateShakeFunction(oscillations)
78 |
79 | return SKAction.actionWithEffect(effect)
80 | }
81 |
82 | /**
83 | * Causes the scene background to flash for duration seconds.
84 | */
85 | public class func colorGlitchWithScene(scene: SKScene, originalColor: SKColor, duration: NSTimeInterval) -> SKAction {
86 | return SKAction.customActionWithDuration(duration) {(node, elapsedTime) in
87 | if elapsedTime < CGFloat(duration) {
88 | scene.backgroundColor = SKColorWithRGB(Int.random(0...255), Int.random(0...255), Int.random(0...255))
89 | } else {
90 | scene.backgroundColor = originalColor
91 | }
92 | }
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger/SKTUtils/SKColor+Extensions.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013-2014 Razeware LLC
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import SpriteKit
24 |
25 | public func SKColorWithRGB(r: Int, g: Int, b: Int) -> SKColor {
26 | return SKColor(red: CGFloat(r)/255.0, green: CGFloat(g)/255.0, blue: CGFloat(b)/255.0, alpha: 1.0)
27 | }
28 |
29 | public func SKColorWithRGBA(r: Int, g: Int, b: Int, a: Int) -> SKColor {
30 | return SKColor(red: CGFloat(r)/255.0, green: CGFloat(g)/255.0, blue: CGFloat(b)/255.0, alpha: CGFloat(a)/255.0)
31 | }
32 |
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger/SKTUtils/SKNode+Extensions.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013-2014 Razeware LLC
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import SpriteKit
24 |
25 | public extension SKNode {
26 |
27 | /** Lets you treat the node's scale as a CGPoint value. */
28 | public var scaleAsPoint: CGPoint {
29 | get {
30 | return CGPoint(x: xScale, y: yScale)
31 | }
32 | set {
33 | xScale = newValue.x
34 | yScale = newValue.y
35 | }
36 | }
37 |
38 | /**
39 | * Runs an action on the node that performs a closure or function after
40 | * a given time.
41 | */
42 | public func afterDelay(delay: NSTimeInterval, runBlock block: dispatch_block_t) {
43 | runAction(SKAction.sequence([SKAction.waitForDuration(delay), SKAction.runBlock(block)]))
44 | }
45 |
46 | /**
47 | * Makes this node the frontmost node in its parent.
48 | */
49 | public func bringToFront() {
50 | if let parent = self.parent{
51 | removeFromParent()
52 | parent.addChild(self)
53 | }
54 | }
55 |
56 | /**
57 | * Orients the node in the direction that it is moving by tweening its
58 | * rotation angle. This assumes that at 0 degrees the node is facing up.
59 | *
60 | * @param velocity The current speed and direction of the node. You can get
61 | * this from node.physicsBody.velocity.
62 | * @param rate How fast the node rotates. Must have a value between 0.0 and
63 | * 1.0, where smaller means slower; 1.0 is instantaneous.
64 | */
65 | public func rotateToVelocity(velocity: CGVector, rate: CGFloat) {
66 | // Determine what the rotation angle of the node ought to be based on the
67 | // current velocity of its physics body. This assumes that at 0 degrees the
68 | // node is pointed up, not to the right, so to compensate we subtract π/4
69 | // (90 degrees) from the calculated angle.
70 | let newAngle = atan2(velocity.dy, velocity.dx) - π/2
71 |
72 | // This always makes the node rotate over the shortest possible distance.
73 | // Because the range of atan2() is -180 to 180 degrees, a rotation from,
74 | // -170 to -190 would otherwise be from -170 to 170, which makes the node
75 | // rotate the wrong way (and the long way) around. We adjust the angle to
76 | // go from 190 to 170 instead, which is equivalent to -170 to -190.
77 | if newAngle - zRotation > π {
78 | zRotation += π * 2.0
79 | } else if zRotation - newAngle > π {
80 | zRotation -= π * 2.0
81 | }
82 |
83 | // Use the "standard exponential slide" to slowly tween zRotation to the
84 | // new angle. The greater the value of rate, the faster this goes.
85 | zRotation += (newAngle - zRotation) * rate
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger/SKTUtils/SKTAudio.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013-2014 Razeware LLC
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import AVFoundation
24 |
25 | /**
26 | * Audio player that uses AVFoundation to play looping background music and
27 | * short sound effects. For when using SKActions just isn't good enough.
28 | */
29 | public class SKTAudio {
30 | public var backgroundMusicPlayer: AVAudioPlayer?
31 | public var soundEffectPlayer: AVAudioPlayer?
32 |
33 | public class func sharedInstance() -> SKTAudio {
34 | return SKTAudioInstance
35 | }
36 |
37 | public func playBackgroundMusic(filename: String) {
38 | let url = NSBundle.mainBundle().URLForResource(filename, withExtension: nil)
39 | if (url == nil) {
40 | println("Could not find file: \(filename)")
41 | return
42 | }
43 |
44 | var error: NSError? = nil
45 | backgroundMusicPlayer = AVAudioPlayer(contentsOfURL: url, error: &error)
46 | if let player = backgroundMusicPlayer {
47 | player.numberOfLoops = -1
48 | player.prepareToPlay()
49 | player.play()
50 | } else {
51 | println("Could not create audio player: \(error!)")
52 | }
53 | }
54 |
55 | public func pauseBackgroundMusic() {
56 | if let player = backgroundMusicPlayer {
57 | if player.playing {
58 | player.pause()
59 | }
60 | }
61 | }
62 |
63 | public func resumeBackgroundMusic() {
64 | if let player = backgroundMusicPlayer {
65 | if !player.playing {
66 | player.play()
67 | }
68 | }
69 | }
70 |
71 | public func playSoundEffect(filename: String) {
72 | let url = NSBundle.mainBundle().URLForResource(filename, withExtension: nil)
73 | if (url == nil) {
74 | println("Could not find file: \(filename)")
75 | return
76 | }
77 |
78 | var error: NSError? = nil
79 | soundEffectPlayer = AVAudioPlayer(contentsOfURL: url, error: &error)
80 | if let player = soundEffectPlayer {
81 | player.numberOfLoops = 0
82 | player.prepareToPlay()
83 | player.play()
84 | } else {
85 | println("Could not create audio player: \(error!)")
86 | }
87 | }
88 | }
89 |
90 | private let SKTAudioInstance = SKTAudio()
91 |
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger/assets.scnassets/Sounds/jump.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/3-Lab/SCNFrogger-3/SCNFrogger/assets.scnassets/Sounds/jump.wav
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger/assets.scnassets/Textures/hand.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/3-Lab/SCNFrogger-3/SCNFrogger/assets.scnassets/Textures/hand.png
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger/assets.scnassets/Textures/hand@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/3-Lab/SCNFrogger-3/SCNFrogger/assets.scnassets/Textures/hand@2x.png
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger/assets.scnassets/Textures/hand_click.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/3-Lab/SCNFrogger-3/SCNFrogger/assets.scnassets/Textures/hand_click.png
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger/assets.scnassets/Textures/hand_click@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/3-Lab/SCNFrogger-3/SCNFrogger/assets.scnassets/Textures/hand_click@2x.png
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFrogger/assets.scnassets/Textures/model_texture.tga:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/3-Lab/SCNFrogger-3/SCNFrogger/assets.scnassets/Textures/model_texture.tga
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFroggerTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | com.raywenderlich.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/3-Lab/SCNFrogger-3/SCNFroggerTests/SCNFroggerTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SCNFroggerTests.swift
3 | // SCNFroggerTests
4 | //
5 | // Created by Kim Pedersen on 02/12/14.
6 | // Copyright (c) 2014 RWDevCon. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import XCTest
11 |
12 | class SCNFroggerTests: XCTestCase {
13 |
14 | override func setUp() {
15 | super.setUp()
16 | // Put setup code here. This method is called before the invocation of each test method in the class.
17 | }
18 |
19 | override func tearDown() {
20 | // Put teardown code here. This method is called after the invocation of each test method in the class.
21 | super.tearDown()
22 | }
23 |
24 | func testExample() {
25 | // This is an example of a functional test case.
26 | XCTAssert(true, "Pass")
27 | }
28 |
29 | func testPerformanceExample() {
30 | // This is an example of a performance test case.
31 | self.measureBlock() {
32 | // Put the code you want to measure the time of here.
33 | }
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger.xcodeproj/project.xcworkspace/xcshareddata/SCNFrogger.xccheckout:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDESourceControlProjectFavoriteDictionaryKey
6 |
7 | IDESourceControlProjectIdentifier
8 | 6DE4669D-839D-4A6C-935D-D50EE5C00229
9 | IDESourceControlProjectName
10 | SCNFrogger
11 | IDESourceControlProjectOriginsDictionary
12 |
13 | C45253657BF1B0A67E13F808D5E653AC34B147B3
14 | https://github.com/devindazzle/SceneKitFrogger.git
15 |
16 | IDESourceControlProjectPath
17 | 4-Challenge/SCNFrogger-4/SCNFrogger.xcodeproj
18 | IDESourceControlProjectRelativeInstallPathDictionary
19 |
20 | C45253657BF1B0A67E13F808D5E653AC34B147B3
21 | ../../../..
22 |
23 | IDESourceControlProjectURL
24 | https://github.com/devindazzle/SceneKitFrogger.git
25 | IDESourceControlProjectVersion
26 | 111
27 | IDESourceControlProjectWCCIdentifier
28 | C45253657BF1B0A67E13F808D5E653AC34B147B3
29 | IDESourceControlProjectWCConfigurations
30 |
31 |
32 | IDESourceControlRepositoryExtensionIdentifierKey
33 | public.vcs.git
34 | IDESourceControlWCCIdentifierKey
35 | C45253657BF1B0A67E13F808D5E653AC34B147B3
36 | IDESourceControlWCCName
37 | SceneKitFrogger
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger.xcodeproj/xcuserdata/kim.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger.xcodeproj/xcuserdata/kim.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | SCNFrogger.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 3BE6195A1A2DCDBA00ED80D7
16 |
17 | primary
18 |
19 |
20 | 3BE619711A2DCDBA00ED80D7
21 |
22 | primary
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // RWDevConSceneKitFinal
4 | //
5 | // Created by Kim Pedersen on 24/11/14.
6 | // Copyright (c) 2014 RWDevCon. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
17 | // Override point for customization after application launch.
18 | return true
19 | }
20 |
21 | func applicationWillResignActive(application: UIApplication) {
22 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
23 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
24 | }
25 |
26 | func applicationDidEnterBackground(application: UIApplication) {
27 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
28 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
29 | }
30 |
31 | func applicationWillEnterForeground(application: UIApplication) {
32 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
33 | }
34 |
35 | func applicationDidBecomeActive(application: UIApplication) {
36 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
37 | }
38 |
39 | func applicationWillTerminate(application: UIApplication) {
40 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
41 | }
42 |
43 |
44 | }
45 |
46 |
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger/Array2D.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Array2D.swift
3 | // RWDevConSceneKitFinal
4 | //
5 | // Created by Kim Pedersen on 24/11/14.
6 | // Copyright (c) 2014 RWDevCon. All rights reserved.
7 | //
8 |
9 | class Array2D {
10 |
11 | var cols: Int, rows: Int
12 | var data: [Int]
13 |
14 | init(cols columnCount: Int, rows rowCount: Int, value defaultValue: Int) {
15 | self.cols = columnCount
16 | self.rows = rowCount
17 | data = Array(count: cols * rows, repeatedValue: defaultValue)
18 | }
19 |
20 | subscript(column: Int, row: Int) -> Int {
21 | get {
22 | return data[cols * row + column]
23 | }
24 | set {
25 | data[cols * row + column] = newValue
26 | }
27 | }
28 |
29 | func columnCount() -> Int {
30 | return self.cols
31 | }
32 |
33 | func rowCount() -> Int {
34 | return self.rows
35 | }
36 |
37 | }
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger/Constants.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Constants.swift
3 | // SCNFrogger
4 | //
5 | // Created by Kim Pedersen on 11/12/14.
6 | // Copyright (c) 2014 RWDevCon. All rights reserved.
7 | //
8 |
9 | enum GameState {
10 | case WaitingForFirstTap
11 | case Playing
12 | case GameOver
13 | case RestartLevel
14 | }
15 |
16 |
17 | enum MoveDirection {
18 | case Forward
19 | case Backward
20 | case Left
21 | case Right
22 | }
23 |
24 |
25 | struct PhysicsCategory {
26 | static let None: Int = 0
27 | static let Player: Int = 0b1 // 1
28 | static let Car: Int = 0b10 // 2
29 | static let Obstacle: Int = 0b100 // 4
30 | }
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger/EarlyGameBoy.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/4-Challenge/SCNFrogger-4/SCNFrogger/EarlyGameBoy.ttf
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger/GameViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GameViewController.swift
3 | // RWDevConSceneKitFinal
4 | //
5 | // Created by Kim Pedersen on 24/11/14.
6 | // Copyright (c) 2014 RWDevCon. All rights reserved.
7 | //
8 |
9 | import SceneKit
10 | import SpriteKit
11 |
12 | class GameViewController: UIViewController {
13 |
14 | var scnView: SCNView {
15 | get {
16 | return self.view as SCNView
17 | }
18 | }
19 |
20 | override func viewDidAppear(animated: Bool) {
21 |
22 | super.viewDidAppear(animated)
23 |
24 | // Set up the SCNView
25 | scnView.backgroundColor = UIColor(red: 100.0/255.0, green: 149.0/255.0, blue: 237.0/255.0, alpha: 1.0)
26 | scnView.showsStatistics = true
27 | scnView.antialiasingMode = SCNAntialiasingMode.Multisampling2X
28 | scnView.overlaySKScene = SKScene(size: view.bounds.size)
29 | scnView.playing = true
30 |
31 | // Set up the scene
32 | let scene = GameScene(view: scnView)
33 | scene.rootNode.hidden = true
34 | scene.physicsWorld.contactDelegate = scene
35 |
36 | // Start playing the scene
37 | scnView.scene = scene
38 | scnView.delegate = scene
39 | scnView.scene!.rootNode.hidden = false
40 | scnView.play(self)
41 | }
42 |
43 |
44 | override func shouldAutorotate() -> Bool {
45 | return true
46 | }
47 |
48 |
49 | override func prefersStatusBarHidden() -> Bool {
50 | return true
51 | }
52 |
53 |
54 | override func supportedInterfaceOrientations() -> Int {
55 | return Int(UIInterfaceOrientationMask.Portrait.rawValue)
56 | }
57 |
58 |
59 | override func didReceiveMemoryWarning() {
60 | super.didReceiveMemoryWarning()
61 | }
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger/HandNode.swift:
--------------------------------------------------------------------------------
1 | //
2 | // HandNode.swift
3 | // SCNFrogger
4 | //
5 | // Created by Kim Pedersen on 11/12/14.
6 | // Copyright (c) 2014 RWDevCon. All rights reserved.
7 | //
8 |
9 | import SpriteKit
10 |
11 | class HandNode : SKNode {
12 |
13 | override init() {
14 |
15 | super.init()
16 |
17 | name = "Tutorial"
18 |
19 | // Load textures
20 | let handTexture = SKTexture(imageNamed:"assets.scnassets/Textures/hand.png")
21 | handTexture.filteringMode = SKTextureFilteringMode.Nearest
22 | let handTextureClick = SKTexture(imageNamed:"assets.scnassets/Textures/hand_click.png")
23 | handTextureClick.filteringMode = SKTextureFilteringMode.Nearest
24 |
25 | // Create animation
26 | let handAnimation = SKAction.animateWithTextures([handTexture, handTextureClick], timePerFrame:0.5)
27 |
28 | // Create a sprite node abd animate it
29 | let handSprite = SKSpriteNode(texture: handTexture)
30 | handSprite.xScale = 2.0
31 | handSprite.yScale = 2.0
32 | handSprite.runAction(SKAction.repeatActionForever(handAnimation))
33 |
34 | addChild(handSprite)
35 | }
36 |
37 |
38 | required init?(coder aDecoder: NSCoder) {
39 | fatalError("init(coder:) has not been implemented")
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "29x29",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-Small@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "29x29",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-Small@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "40x40",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-40@2x.png",
19 | "scale" : "2x"
20 | },
21 | {
22 | "size" : "40x40",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-40@3x.png",
25 | "scale" : "3x"
26 | },
27 | {
28 | "size" : "60x60",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-60@2x.png",
31 | "scale" : "2x"
32 | },
33 | {
34 | "size" : "60x60",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-60@3x.png",
37 | "scale" : "3x"
38 | },
39 | {
40 | "size" : "29x29",
41 | "idiom" : "ipad",
42 | "filename" : "Icon-Small.png",
43 | "scale" : "1x"
44 | },
45 | {
46 | "size" : "29x29",
47 | "idiom" : "ipad",
48 | "filename" : "Icon-Small@2x-1.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "40x40",
53 | "idiom" : "ipad",
54 | "filename" : "Icon-40.png",
55 | "scale" : "1x"
56 | },
57 | {
58 | "size" : "40x40",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-40@2x-1.png",
61 | "scale" : "2x"
62 | },
63 | {
64 | "size" : "76x76",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-76.png",
67 | "scale" : "1x"
68 | },
69 | {
70 | "size" : "76x76",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-76@2x.png",
73 | "scale" : "2x"
74 | }
75 | ],
76 | "info" : {
77 | "version" : 1,
78 | "author" : "xcode"
79 | }
80 | }
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/4-Challenge/SCNFrogger-4/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-40.png
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-40@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/4-Challenge/SCNFrogger-4/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-40@2x-1.png
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/4-Challenge/SCNFrogger-4/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-40@2x.png
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/4-Challenge/SCNFrogger-4/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-40@3x.png
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/4-Challenge/SCNFrogger-4/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-60@2x.png
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/4-Challenge/SCNFrogger-4/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-60@3x.png
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/4-Challenge/SCNFrogger-4/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-76.png
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/4-Challenge/SCNFrogger-4/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-76@2x.png
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-Small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/4-Challenge/SCNFrogger-4/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-Small.png
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-Small@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/4-Challenge/SCNFrogger-4/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-Small@2x-1.png
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-Small@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/4-Challenge/SCNFrogger-4/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-Small@2x.png
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-Small@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/4-Challenge/SCNFrogger-4/SCNFrogger/Images.xcassets/AppIcon.appiconset/Icon-Small@3x.png
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger/Images.xcassets/rwdevcon-bg.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x",
10 | "filename" : "rwdevcon-bg.png"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger/Images.xcassets/rwdevcon-bg.imageset/rwdevcon-bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/4-Challenge/SCNFrogger-4/SCNFrogger/Images.xcassets/rwdevcon-bg.imageset/rwdevcon-bg.png
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger/Images.xcassets/rwdevcon-logo.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x",
10 | "filename" : "rwdevcon-logo.png"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger/Images.xcassets/rwdevcon-logo.imageset/rwdevcon-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/4-Challenge/SCNFrogger-4/SCNFrogger/Images.xcassets/rwdevcon-logo.imageset/rwdevcon-logo.png
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | com.raywenderlich.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UIAppFonts
26 |
27 | EarlyGameBoy.ttf
28 |
29 | UILaunchStoryboardName
30 | LaunchScreen
31 | UIMainStoryboardFile
32 | Main
33 | UIRequiredDeviceCapabilities
34 |
35 | armv7
36 |
37 | UIStatusBarHidden
38 |
39 | UISupportedInterfaceOrientations
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 |
44 | UISupportedInterfaceOrientations~ipad
45 |
46 | UIInterfaceOrientationPortrait
47 | UIInterfaceOrientationPortraitUpsideDown
48 | UIInterfaceOrientationLandscapeLeft
49 | UIInterfaceOrientationLandscapeRight
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger/LabelNode.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LabelNode.swift
3 | // SCNFrogger
4 | //
5 | // Created by Kim Pedersen on 11/12/14.
6 | // Copyright (c) 2014 RWDevCon. All rights reserved.
7 | //
8 |
9 | import SpriteKit
10 |
11 | class LabelNode : SKLabelNode {
12 |
13 | init(position: CGPoint, size: CGFloat, color: SKColor, text: String, name: String) {
14 | super.init()
15 |
16 | self.name = name
17 | self.text = text
18 | self.position = position
19 |
20 | fontName = "Early-Gameboy"
21 | fontSize = size
22 | fontColor = color
23 | }
24 |
25 | required init?(coder aDecoder: NSCoder) {
26 | fatalError("init(coder:) has not been implemented")
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger/LaunchScreen.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger/SKTUtils/CGFloat+Extensions.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013-2014 Razeware LLC
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import CoreGraphics
24 |
25 | /** The value of π as a CGFloat */
26 | let π = CGFloat(M_PI)
27 |
28 | public extension CGFloat {
29 | /**
30 | * Converts an angle in degrees to radians.
31 | */
32 | public func degreesToRadians() -> CGFloat {
33 | return π * self / 180.0
34 | }
35 |
36 | /**
37 | * Converts an angle in radians to degrees.
38 | */
39 | public func radiansToDegrees() -> CGFloat {
40 | return self * 180.0 / π
41 | }
42 |
43 | /**
44 | * Ensures that the float value stays between the given values, inclusive.
45 | */
46 | public func clamped(v1: CGFloat, _ v2: CGFloat) -> CGFloat {
47 | let min = v1 < v2 ? v1 : v2
48 | let max = v1 > v2 ? v1 : v2
49 | return self < min ? min : (self > max ? max : self)
50 | }
51 |
52 | /**
53 | * Ensures that the float value stays between the given values, inclusive.
54 | */
55 | public mutating func clamp(v1: CGFloat, _ v2: CGFloat) -> CGFloat {
56 | self = clamped(v1, v2)
57 | return self
58 | }
59 |
60 | /**
61 | * Returns 1.0 if a floating point value is positive; -1.0 if it is negative.
62 | */
63 | public func sign() -> CGFloat {
64 | return (self >= 0.0) ? 1.0 : -1.0
65 | }
66 |
67 | /**
68 | * Returns a random floating point number between 0.0 and 1.0, inclusive.
69 | */
70 | public static func random() -> CGFloat {
71 | return CGFloat(Float(arc4random()) / 0xFFFFFFFF)
72 | }
73 |
74 | /**
75 | * Returns a random floating point number in the range min...max, inclusive.
76 | */
77 | public static func random(#min: CGFloat, max: CGFloat) -> CGFloat {
78 | assert(min < max)
79 | return CGFloat.random() * (max - min) + min
80 | }
81 |
82 | /**
83 | * Randomly returns either 1.0 or -1.0.
84 | */
85 | public static func randomSign() -> CGFloat {
86 | return (arc4random_uniform(2) == 0) ? 1.0 : -1.0
87 | }
88 | }
89 |
90 | /**
91 | * Returns the shortest angle between two angles. The result is always between
92 | * -π and π.
93 | */
94 | public func shortestAngleBetween(angle1: CGFloat, angle2: CGFloat) -> CGFloat {
95 | let twoπ = π * 2.0
96 | var angle = (angle2 - angle1) % twoπ
97 | if (angle >= π) {
98 | angle = angle - twoπ
99 | }
100 | if (angle <= -π) {
101 | angle = angle + twoπ
102 | }
103 | return angle
104 | }
105 |
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger/SKTUtils/Int+Extensions.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013-2014 Razeware LLC
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import CoreGraphics
24 |
25 | public extension Int {
26 | /**
27 | * Ensures that the integer value stays with the specified range.
28 | */
29 | public func clamped(range: Range) -> Int {
30 | return (self < range.startIndex) ? range.startIndex : ((self >= range.endIndex) ? range.endIndex - 1: self)
31 | }
32 |
33 | /**
34 | * Ensures that the integer value stays with the specified range.
35 | */
36 | public mutating func clamp(range: Range) -> Int {
37 | self = clamped(range)
38 | return self
39 | }
40 |
41 | /**
42 | * Ensures that the integer value stays between the given values, inclusive.
43 | */
44 | public func clamped(v1: Int, _ v2: Int) -> Int {
45 | let min = v1 < v2 ? v1 : v2
46 | let max = v1 > v2 ? v1 : v2
47 | return self < min ? min : (self > max ? max : self)
48 | }
49 |
50 | /**
51 | * Ensures that the integer value stays between the given values, inclusive.
52 | */
53 | public mutating func clamp(v1: Int, _ v2: Int) -> Int {
54 | self = clamped(v1, v2)
55 | return self
56 | }
57 |
58 | /**
59 | * Returns a random integer in the specified range.
60 | */
61 | public static func random(range: Range) -> Int {
62 | return Int(arc4random_uniform(UInt32(range.endIndex - range.startIndex))) + range.startIndex
63 | }
64 |
65 | /**
66 | * Returns a random integer between 0 and n-1.
67 | */
68 | public static func random(n: Int) -> Int {
69 | return Int(arc4random_uniform(UInt32(n)))
70 | }
71 |
72 | /**
73 | * Returns a random integer in the range min...max, inclusive.
74 | */
75 | public static func random(#min: Int, max: Int) -> Int {
76 | assert(min < max)
77 | return Int(arc4random_uniform(UInt32(max - min + 1))) + min
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger/SKTUtils/SKAction+Extensions.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013-2014 Razeware LLC
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import SpriteKit
24 |
25 | public extension SKAction {
26 | /**
27 | * Performs an action after the specified delay.
28 | */
29 | public class func afterDelay(delay: NSTimeInterval, performAction action: SKAction) -> SKAction {
30 | return SKAction.sequence([SKAction.waitForDuration(delay), action])
31 | }
32 |
33 | /**
34 | * Performs a block after the specified delay.
35 | */
36 | public class func afterDelay(delay: NSTimeInterval, runBlock block: dispatch_block_t) -> SKAction {
37 | return SKAction.afterDelay(delay, performAction: SKAction.runBlock(block))
38 | }
39 |
40 | /**
41 | * Removes the node from its parent after the specified delay.
42 | */
43 | public class func removeFromParentAfterDelay(delay: NSTimeInterval) -> SKAction {
44 | return SKAction.afterDelay(delay, performAction: SKAction.removeFromParent())
45 | }
46 |
47 | /**
48 | * Creates an action to perform a parabolic jump.
49 | */
50 | public class func jumpToHeight(height: CGFloat, duration: NSTimeInterval, originalPosition: CGPoint) -> SKAction {
51 | return SKAction.customActionWithDuration(duration) {(node, elapsedTime) in
52 | let fraction = elapsedTime / CGFloat(duration)
53 | let yOffset = height * 4 * fraction * (1 - fraction)
54 | node.position = CGPoint(x: originalPosition.x, y: originalPosition.y + yOffset)
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger/SKTUtils/SKAction+SpecialEffects.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013-2014 Razeware LLC
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import SpriteKit
24 |
25 | public extension SKAction {
26 | /**
27 | * Creates a screen shake animation.
28 | *
29 | * @param node The node to shake. You cannot apply this effect to an SKScene.
30 | * @param amount The vector by which the node is displaced.
31 | * @param oscillations The number of oscillations; 10 is a good value.
32 | * @param duration How long the effect lasts. Shorter is better.
33 | */
34 | public class func screenShakeWithNode(node: SKNode, amount: CGPoint, oscillations: Int, duration: NSTimeInterval) -> SKAction {
35 | let oldPosition = node.position
36 | let newPosition = oldPosition + amount
37 |
38 | let effect = SKTMoveEffect(node: node, duration: duration, startPosition: newPosition, endPosition: oldPosition)
39 | effect.timingFunction = SKTCreateShakeFunction(oscillations)
40 |
41 | return SKAction.actionWithEffect(effect)
42 | }
43 |
44 | /**
45 | * Creates a screen rotation animation.
46 | *
47 | * @param node You usually want to apply this effect to a pivot node that is
48 | * centered in the scene. You cannot apply the effect to an SKScene.
49 | * @param angle The angle in radians.
50 | * @param oscillations The number of oscillations; 10 is a good value.
51 | * @param duration How long the effect lasts. Shorter is better.
52 | */
53 | public class func screenRotateWithNode(node: SKNode, angle: CGFloat, oscillations: Int, duration: NSTimeInterval) -> SKAction {
54 | let oldAngle = node.zRotation
55 | let newAngle = oldAngle + angle
56 |
57 | let effect = SKTRotateEffect(node: node, duration: duration, startAngle: newAngle, endAngle: oldAngle)
58 | effect.timingFunction = SKTCreateShakeFunction(oscillations)
59 |
60 | return SKAction.actionWithEffect(effect)
61 | }
62 |
63 | /**
64 | * Creates a screen zoom animation.
65 | *
66 | * @param node You usually want to apply this effect to a pivot node that is
67 | * centered in the scene. You cannot apply the effect to an SKScene.
68 | * @param amount How much to scale the node in the X and Y directions.
69 | * @param oscillations The number of oscillations; 10 is a good value.
70 | * @param duration How long the effect lasts. Shorter is better.
71 | */
72 | public class func screenZoomWithNode(node: SKNode, amount: CGPoint, oscillations: Int, duration: NSTimeInterval) -> SKAction {
73 | let oldScale = CGPoint(x: node.xScale, y: node.yScale)
74 | let newScale = oldScale * amount
75 |
76 | let effect = SKTScaleEffect(node: node, duration: duration, startScale: newScale, endScale: oldScale)
77 | effect.timingFunction = SKTCreateShakeFunction(oscillations)
78 |
79 | return SKAction.actionWithEffect(effect)
80 | }
81 |
82 | /**
83 | * Causes the scene background to flash for duration seconds.
84 | */
85 | public class func colorGlitchWithScene(scene: SKScene, originalColor: SKColor, duration: NSTimeInterval) -> SKAction {
86 | return SKAction.customActionWithDuration(duration) {(node, elapsedTime) in
87 | if elapsedTime < CGFloat(duration) {
88 | scene.backgroundColor = SKColorWithRGB(Int.random(0...255), Int.random(0...255), Int.random(0...255))
89 | } else {
90 | scene.backgroundColor = originalColor
91 | }
92 | }
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger/SKTUtils/SKColor+Extensions.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013-2014 Razeware LLC
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import SpriteKit
24 |
25 | public func SKColorWithRGB(r: Int, g: Int, b: Int) -> SKColor {
26 | return SKColor(red: CGFloat(r)/255.0, green: CGFloat(g)/255.0, blue: CGFloat(b)/255.0, alpha: 1.0)
27 | }
28 |
29 | public func SKColorWithRGBA(r: Int, g: Int, b: Int, a: Int) -> SKColor {
30 | return SKColor(red: CGFloat(r)/255.0, green: CGFloat(g)/255.0, blue: CGFloat(b)/255.0, alpha: CGFloat(a)/255.0)
31 | }
32 |
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger/SKTUtils/SKNode+Extensions.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013-2014 Razeware LLC
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import SpriteKit
24 |
25 | public extension SKNode {
26 |
27 | /** Lets you treat the node's scale as a CGPoint value. */
28 | public var scaleAsPoint: CGPoint {
29 | get {
30 | return CGPoint(x: xScale, y: yScale)
31 | }
32 | set {
33 | xScale = newValue.x
34 | yScale = newValue.y
35 | }
36 | }
37 |
38 | /**
39 | * Runs an action on the node that performs a closure or function after
40 | * a given time.
41 | */
42 | public func afterDelay(delay: NSTimeInterval, runBlock block: dispatch_block_t) {
43 | runAction(SKAction.sequence([SKAction.waitForDuration(delay), SKAction.runBlock(block)]))
44 | }
45 |
46 | /**
47 | * Makes this node the frontmost node in its parent.
48 | */
49 | public func bringToFront() {
50 | if let parent = self.parent{
51 | removeFromParent()
52 | parent.addChild(self)
53 | }
54 | }
55 |
56 | /**
57 | * Orients the node in the direction that it is moving by tweening its
58 | * rotation angle. This assumes that at 0 degrees the node is facing up.
59 | *
60 | * @param velocity The current speed and direction of the node. You can get
61 | * this from node.physicsBody.velocity.
62 | * @param rate How fast the node rotates. Must have a value between 0.0 and
63 | * 1.0, where smaller means slower; 1.0 is instantaneous.
64 | */
65 | public func rotateToVelocity(velocity: CGVector, rate: CGFloat) {
66 | // Determine what the rotation angle of the node ought to be based on the
67 | // current velocity of its physics body. This assumes that at 0 degrees the
68 | // node is pointed up, not to the right, so to compensate we subtract π/4
69 | // (90 degrees) from the calculated angle.
70 | let newAngle = atan2(velocity.dy, velocity.dx) - π/2
71 |
72 | // This always makes the node rotate over the shortest possible distance.
73 | // Because the range of atan2() is -180 to 180 degrees, a rotation from,
74 | // -170 to -190 would otherwise be from -170 to 170, which makes the node
75 | // rotate the wrong way (and the long way) around. We adjust the angle to
76 | // go from 190 to 170 instead, which is equivalent to -170 to -190.
77 | if newAngle - zRotation > π {
78 | zRotation += π * 2.0
79 | } else if zRotation - newAngle > π {
80 | zRotation -= π * 2.0
81 | }
82 |
83 | // Use the "standard exponential slide" to slowly tween zRotation to the
84 | // new angle. The greater the value of rate, the faster this goes.
85 | zRotation += (newAngle - zRotation) * rate
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger/SKTUtils/SKTAudio.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013-2014 Razeware LLC
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import AVFoundation
24 |
25 | /**
26 | * Audio player that uses AVFoundation to play looping background music and
27 | * short sound effects. For when using SKActions just isn't good enough.
28 | */
29 | public class SKTAudio {
30 | public var backgroundMusicPlayer: AVAudioPlayer?
31 | public var soundEffectPlayer: AVAudioPlayer?
32 |
33 | public class func sharedInstance() -> SKTAudio {
34 | return SKTAudioInstance
35 | }
36 |
37 | public func playBackgroundMusic(filename: String) {
38 | let url = NSBundle.mainBundle().URLForResource(filename, withExtension: nil)
39 | if (url == nil) {
40 | println("Could not find file: \(filename)")
41 | return
42 | }
43 |
44 | var error: NSError? = nil
45 | backgroundMusicPlayer = AVAudioPlayer(contentsOfURL: url, error: &error)
46 | if let player = backgroundMusicPlayer {
47 | player.numberOfLoops = -1
48 | player.prepareToPlay()
49 | player.play()
50 | } else {
51 | println("Could not create audio player: \(error!)")
52 | }
53 | }
54 |
55 | public func pauseBackgroundMusic() {
56 | if let player = backgroundMusicPlayer {
57 | if player.playing {
58 | player.pause()
59 | }
60 | }
61 | }
62 |
63 | public func resumeBackgroundMusic() {
64 | if let player = backgroundMusicPlayer {
65 | if !player.playing {
66 | player.play()
67 | }
68 | }
69 | }
70 |
71 | public func playSoundEffect(filename: String) {
72 | let url = NSBundle.mainBundle().URLForResource(filename, withExtension: nil)
73 | if (url == nil) {
74 | println("Could not find file: \(filename)")
75 | return
76 | }
77 |
78 | var error: NSError? = nil
79 | soundEffectPlayer = AVAudioPlayer(contentsOfURL: url, error: &error)
80 | if let player = soundEffectPlayer {
81 | player.numberOfLoops = 0
82 | player.prepareToPlay()
83 | player.play()
84 | } else {
85 | println("Could not create audio player: \(error!)")
86 | }
87 | }
88 | }
89 |
90 | private let SKTAudioInstance = SKTAudio()
91 |
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger/assets.scnassets/Sounds/jump.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/4-Challenge/SCNFrogger-4/SCNFrogger/assets.scnassets/Sounds/jump.wav
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger/assets.scnassets/Textures/hand.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/4-Challenge/SCNFrogger-4/SCNFrogger/assets.scnassets/Textures/hand.png
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger/assets.scnassets/Textures/hand@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/4-Challenge/SCNFrogger-4/SCNFrogger/assets.scnassets/Textures/hand@2x.png
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger/assets.scnassets/Textures/hand_click.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/4-Challenge/SCNFrogger-4/SCNFrogger/assets.scnassets/Textures/hand_click.png
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger/assets.scnassets/Textures/hand_click@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/4-Challenge/SCNFrogger-4/SCNFrogger/assets.scnassets/Textures/hand_click@2x.png
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFrogger/assets.scnassets/Textures/model_texture.tga:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/4-Challenge/SCNFrogger-4/SCNFrogger/assets.scnassets/Textures/model_texture.tga
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFroggerTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | com.raywenderlich.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/4-Challenge/SCNFrogger-4/SCNFroggerTests/SCNFroggerTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SCNFroggerTests.swift
3 | // SCNFroggerTests
4 | //
5 | // Created by Kim Pedersen on 02/12/14.
6 | // Copyright (c) 2014 RWDevCon. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import XCTest
11 |
12 | class SCNFroggerTests: XCTestCase {
13 |
14 | override func setUp() {
15 | super.setUp()
16 | // Put setup code here. This method is called before the invocation of each test method in the class.
17 | }
18 |
19 | override func tearDown() {
20 | // Put teardown code here. This method is called after the invocation of each test method in the class.
21 | super.tearDown()
22 | }
23 |
24 | func testExample() {
25 | // This is an example of a functional test case.
26 | XCTAssert(true, "Pass")
27 | }
28 |
29 | func testPerformanceExample() {
30 | // This is an example of a performance test case.
31 | self.measureBlock() {
32 | // Put the code you want to measure the time of here.
33 | }
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/5-Conclusion/5-Conclusion.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/5-Conclusion/5-Conclusion.pdf
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Kim Pedersen
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | SCNFrogger
2 | ===============
3 | A 3D Frogger / Crossy Road clone made with Scene Kit and Swift.
4 |
5 | Source Code for my tutorial on Scene Kit at [RWDevCon](http://www.rwdevcon.com) February 6th-7th, 2015 in Washington DC.
6 |
7 | 
8 |
9 | Contains all the steps and materials used during the conference:
10 |
11 | **0-For-Instructor:** All the presentations and markdown files.
12 |
13 | **1-Starter:** The starter project.
14 |
15 | **2-Demo:** The finished Demo project after going through the steps in [Demo Instructions](https://github.com/devindazzle/SceneKitFrogger/blob/master/0-For-Instructor/2-Demo.markdown)
16 |
17 | **3-Lab:** The finished project after completing the Lab via the [lab instructions](https://github.com/devindazzle/SceneKitFrogger/blob/master/0-For-Instructor/3-LabInstructions.markdown)
18 |
19 | **4-Challenge:** The finished project after completing the Challenge via the [challenge instructions](https://github.com/devindazzle/SceneKitFrogger/blob/master/0-For-Instructor/4-ChallengeInstructions.markdown)
20 |
21 | If you just want to see the final result, you should open the project in the "4-Challenge" folder.
22 |
23 | If you find this useful or have any questions or comments, reach out to me on Twitter [@twofly3](https://twitter.com/twofly3)
24 |
25 | The models included in the project is created using the open-source voxel editor [Magica Voxel](https://voxel.codeplex.com) and cleaned up in [Blender](http://www.blender.org).
--------------------------------------------------------------------------------
/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devindazzle/SceneKitFrogger/5da7da0c7e7dc9f914aa30f65350e90cab35bafd/screenshot.png
--------------------------------------------------------------------------------