├── jumpyexample.gif
├── Jumpy.xcodeproj
├── project.xcworkspace
│ └── contents.xcworkspacedata
└── project.pbxproj
├── Jumpy
├── AppDelegate.swift
├── Assets.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
├── Info.plist
├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
└── ViewController.swift
├── README.md
├── LICENSE
└── .gitignore
/jumpyexample.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JARMourato/Jumpy/HEAD/jumpyexample.gif
--------------------------------------------------------------------------------
/Jumpy.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Jumpy/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // Jumpy
4 | //
5 | // Created by JARMourato on 26/07/16.
6 | // Copyright © 2016 JARMourato. 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: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
17 | return true
18 | }
19 | }
20 |
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Jumpy
2 |
3 | The iOS 10 `UIViewPropertyAnimator` enables us to make interactive animations. That fact alone allows this game to be made without any SpriteKit usage whatsoever. It's only a proof of concept
4 |
5 | 
6 |
7 | [](https://swift.org)
8 | [](https://swift.org/about/#platform-support)
9 | [](https://github.com/JARMourato/Jumpy/blob/master/LICENSE)
10 |
11 | # Requirements
12 |
13 | * Xcode 8
14 | * iOS 10
15 | * Swift 3.0
16 |
17 | ## License
18 | **Jumpy** is released under the MIT license. See [LICENSE](https://github.com/JARMourato/Jumpy/blob/master/LICENSE) for details.
19 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2016 JARMourato
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/Jumpy/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "ipad",
35 | "size" : "29x29",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "ipad",
40 | "size" : "29x29",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "40x40",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "40x40",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "76x76",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "76x76",
61 | "scale" : "2x"
62 | }
63 | ],
64 | "info" : {
65 | "version" : 1,
66 | "author" : "xcode"
67 | }
68 | }
--------------------------------------------------------------------------------
/Jumpy/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Main
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## Build generated
6 | build/
7 | DerivedData/
8 |
9 | ## Various settings
10 | *.pbxuser
11 | !default.pbxuser
12 | *.mode1v3
13 | !default.mode1v3
14 | *.mode2v3
15 | !default.mode2v3
16 | *.perspectivev3
17 | !default.perspectivev3
18 | xcuserdata/
19 |
20 | ## Other
21 | *.moved-aside
22 | *.xcuserstate
23 |
24 | ## Obj-C/Swift specific
25 | *.hmap
26 | *.ipa
27 | *.dSYM.zip
28 | *.dSYM
29 |
30 | ## Playgrounds
31 | timeline.xctimeline
32 | playground.xcworkspace
33 |
34 | # Swift Package Manager
35 | #
36 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
37 | # Packages/
38 | .build/
39 |
40 | # CocoaPods
41 | #
42 | # We recommend against adding the Pods directory to your .gitignore. However
43 | # you should judge for yourself, the pros and cons are mentioned at:
44 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
45 | #
46 | # Pods/
47 |
48 | # Carthage
49 | #
50 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
51 | # Carthage/Checkouts
52 |
53 | Carthage/Build
54 |
55 | # fastlane
56 | #
57 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
58 | # screenshots whenever they are needed.
59 | # For more information about the recommended setup visit:
60 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md
61 |
62 | fastlane/report.xml
63 | fastlane/Preview.html
64 | fastlane/screenshots
65 | fastlane/test_output
66 |
--------------------------------------------------------------------------------
/Jumpy/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/Jumpy/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 |
26 |
31 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/Jumpy/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // Jumpy
4 | //
5 | // Created by JARMourato on 26/07/16.
6 | // Copyright © 2016 JARMourato. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | //MARK: Constants
12 |
13 | let jumpHeightStep: CGFloat = 45.0
14 | let fallVelocity: CGFloat = 600 //pointsPerSecond
15 | let jumpVelocity: CGFloat = 200 //pointsPerSecond
16 | let obstacleVelocity: CGFloat = 100 //pointsPerSecond
17 | let rotationAngle: CGFloat = CGFloat(M_PI_2)
18 | let gapConstant: CGFloat = 8.0
19 | let playerHeight: CGFloat = 20.0
20 | let gapHeight: CGFloat = playerHeight*gapConstant
21 | let colors = [#colorLiteral(red: 0.1529411765, green: 0.2196078431, blue: 0.2980392157, alpha: 1), #colorLiteral(red: 0.1294117647, green: 0.1843137255, blue: 0.2470588235, alpha: 1), #colorLiteral(red: 0.1137254902, green: 0.4156862745, blue: 0.6784313725, alpha: 1), #colorLiteral(red: 0.08235294118, green: 0.6980392157, blue: 0.5411764706, alpha: 1), #colorLiteral(red: 0.07058823529, green: 0.5725490196, blue: 0.4470588235, alpha: 1), #colorLiteral(red: 0.1411764706, green: 0.7803921569, blue: 0.3529411765, alpha: 1), #colorLiteral(red: 0.1176470588, green: 0.6431372549, blue: 0.2941176471, alpha: 1), #colorLiteral(red: 0.9333333333, green: 0.7333333333, blue: 0, alpha: 1), #colorLiteral(red: 0.9411764706, green: 0.5450980392, blue: 0, alpha: 1), #colorLiteral(red: 0.8784313725, green: 0.4156862745, blue: 0.03921568627, alpha: 1), #colorLiteral(red: 0.7882352941, green: 0.2470588235, blue: 0, alpha: 1), #colorLiteral(red: 0.8823529412, green: 0.2, blue: 0.1607843137, alpha: 1), #colorLiteral(red: 0.7019607843, green: 0.1411764706, blue: 0.1098039216, alpha: 1), #colorLiteral(red: 0.537254902, green: 0.2352941176, blue: 0.662745098, alpha: 1), #colorLiteral(red: 0.4823529412, green: 0.1490196078, blue: 0.6235294118, alpha: 1), #colorLiteral(red: 0.6862745098, green: 0.7137254902, blue: 0.7333333333, alpha: 1), #colorLiteral(red: 0.5137254902, green: 0.5843137255, blue: 0.5843137255, alpha: 1), #colorLiteral(red: 0.4235294118, green: 0.4745098039, blue: 0.4784313725, alpha: 1)]
22 |
23 |
24 | final class ViewController: UIViewController {
25 |
26 | fileprivate enum State {
27 | case ready
28 | case playing
29 | case over
30 | }
31 |
32 | @IBOutlet var tapToStartLabel: UILabel!
33 | @IBOutlet var scoreLabel: UILabel!
34 | @IBOutlet var maxScoreLabel: UILabel!
35 |
36 | fileprivate var playerAnimator: UIViewPropertyAnimator?
37 | fileprivate var playerRotator: UIViewPropertyAnimator?
38 | fileprivate var player: UIView = UIView(frame: CGRect(x: 0, y: 0, width: playerHeight, height: playerHeight))
39 |
40 | fileprivate var displayLink: CADisplayLink?
41 | fileprivate var state: State = .ready
42 |
43 | fileprivate var obstacles: [UIView] = []
44 | fileprivate var obstacleAnimators: [UIViewPropertyAnimator] = []
45 | fileprivate var obstacleTimer: Timer?
46 |
47 | fileprivate var score: Int = 0
48 | fileprivate var maxScore: Int = 0
49 |
50 | fileprivate var shouldRotate: Bool = false
51 |
52 | override func viewDidLoad() {
53 | super.viewDidLoad()
54 | let tap = UITapGestureRecognizer(target: self, action: #selector(tapped))
55 | view.addGestureRecognizer(tap)
56 | setupPlayer()
57 | resetGame()
58 | }
59 |
60 | func tapped() {
61 | if case .ready = state {
62 | startGame()
63 | }
64 | jump()
65 | }
66 |
67 | }
68 |
69 | extension ViewController {
70 |
71 | func setupPlayer() {
72 | player.backgroundColor = #colorLiteral(red: 0.1490196078, green: 0.5098039216, blue: 0.8352941176, alpha: 1)
73 | view.addSubview(player)
74 | resetPlayerPosition()
75 | }
76 |
77 | func resetPlayerPosition() {
78 | player.center.y = view.center.y
79 | player.center.x = view.frame.size.width*0.25
80 | player.transform = CGAffineTransform.identity
81 | }
82 |
83 | func playerHasFallen() -> Bool {
84 | guard let vFrame = player.layer.presentation()?.frame else {
85 | return false
86 | }
87 |
88 | return vFrame.origin.y > (view.frame.size.height - vFrame.size.height)
89 | }
90 |
91 | func playerHasCollided() -> Bool {
92 | for obstacle in obstacles {
93 | if let playerFrame = player.layer.presentation()?.frame,
94 | let obstacle = obstacle.layer.presentation()?.frame,
95 | playerFrame.intersects(obstacle) {
96 | return true
97 | }
98 | }
99 | return false
100 | }
101 |
102 | func updateScore() {
103 | var count: Int = 0
104 | for (index,obstacle) in obstacles.enumerated().reversed() {
105 | if let playerFrame = player.layer.presentation()?.frame,
106 | let obstacle = obstacle.layer.presentation()?.frame,
107 | playerFrame.origin.x > (obstacle.origin.x + obstacle.size.width) {
108 | obstacles.remove(at: index)
109 | count += 1
110 |
111 | }
112 | }
113 | score += Int(count/2) // One top and one bottom
114 | scoreLabel.text = "Score: \(score)"
115 | }
116 |
117 | }
118 |
119 | extension ViewController {
120 |
121 | fileprivate func randomColor() -> UIColor {
122 | return colors[Int(arc4random_uniform(UInt32(colors.count)))]
123 | }
124 |
125 | func createObstacle() -> UIView {
126 | let width: CGFloat = 30
127 | let height = (view.frame.size.height/2)*1.5
128 | let obstacle = UIView(frame: CGRect(x: 0, y: 0, width: 30, height: height))
129 | obstacle.layer.cornerRadius = 0.2*width
130 | return obstacle
131 | }
132 |
133 | func spawnObstacle(_ outsideView: Bool = false) {
134 | let color = randomColor()
135 | let bottomObstacle = createObstacle()
136 | let factor: CGFloat = outsideView ? 1.25 : 0.75
137 | let startX = view.frame.size.width*factor
138 | let min = view.frame.size.height/2 - bottomObstacle.frame.size.height/2 * 0.4
139 | let max = view.frame.size.height/2 + bottomObstacle.frame.size.height/2 * 0.4
140 | let startY = CGFloat(Float(arc4random()) / 0xFFFFFFFF) * (max - min) + min
141 |
142 | bottomObstacle.frame.origin = CGPoint(x: startX, y: startY)
143 |
144 | let topObstacle = createObstacle()
145 | let topStartY = startY - topObstacle.frame.size.height - gapHeight
146 |
147 | topObstacle.frame.origin = CGPoint(x: startX, y: topStartY)
148 |
149 | bottomObstacle.backgroundColor = color
150 | topObstacle.backgroundColor = color
151 |
152 | view.addSubview(bottomObstacle)
153 | view.addSubview(topObstacle)
154 |
155 | view.sendSubview(toBack: bottomObstacle)
156 | view.sendSubview(toBack: topObstacle)
157 |
158 |
159 | obstacles.append(bottomObstacle)
160 | obstacles.append(topObstacle)
161 |
162 | let distance = startX + bottomObstacle.frame.size.width
163 | let duration = distance/obstacleVelocity
164 |
165 | let bottomAnimator = UIViewPropertyAnimator(duration: TimeInterval(duration), curve: .linear) {
166 | bottomObstacle.frame.origin.x = -bottomObstacle.frame.size.width
167 | }
168 | bottomAnimator.addCompletion {_ in
169 | bottomObstacle.removeFromSuperview()
170 | }
171 |
172 | let topAnimator = UIViewPropertyAnimator(duration: TimeInterval(duration), curve: .linear) {
173 | topObstacle.frame.origin.x = -topObstacle.frame.size.width
174 | }
175 | topAnimator.addCompletion {_ in
176 | topObstacle.removeFromSuperview()
177 | }
178 |
179 | obstacleAnimators.append(bottomAnimator)
180 | obstacleAnimators.append(topAnimator)
181 | }
182 |
183 | func removeObstacles() {
184 | obstacles.forEach{ $0.removeFromSuperview() }
185 | obstacles = []
186 | }
187 |
188 | func moveObstacles() {
189 | while obstacleAnimators.count > 0 {
190 | let animator = obstacleAnimators.removeLast()
191 | guard animator.state == .inactive else { return }
192 | animator.startAnimation()
193 | }
194 | }
195 |
196 | }
197 |
198 | extension ViewController {
199 |
200 | func startDisplayLink() {
201 | displayLink = CADisplayLink(target: self, selector: #selector(displayLinkExecute))
202 | displayLink?.add(to: RunLoop.main, forMode: RunLoopMode.defaultRunLoopMode)
203 | }
204 |
205 | func stopDisplayLink() {
206 | displayLink?.isPaused = true
207 | displayLink?.remove(from: RunLoop.main, forMode: RunLoopMode.defaultRunLoopMode)
208 | displayLink = nil
209 | }
210 |
211 | func displayLinkExecute() {
212 | if playerHasFallen() || playerHasCollided() {
213 | gameOver()
214 | }
215 | updateScore()
216 | }
217 |
218 | func startObstacleSpawnTimer() {
219 | let interval = view.frame.size.width*0.5/obstacleVelocity
220 | obstacleTimer = Timer.scheduledTimer(timeInterval: TimeInterval(interval), target: self, selector: #selector(gerenateObstacle(_:)), userInfo: nil, repeats: true)
221 | }
222 |
223 | func stopObstacleSpawnTimer() {
224 | if let obstacleTimer = obstacleTimer, obstacleTimer.isValid {
225 | obstacleTimer.invalidate()
226 | }
227 | }
228 |
229 | func gerenateObstacle(_ timer: Timer) {
230 | spawnObstacle(true)
231 | moveObstacles()
232 | }
233 | }
234 |
235 | extension ViewController {
236 |
237 | func resetGame() {
238 | removeObstacles()
239 | spawnObstacle()
240 | spawnObstacle(true)
241 | resetPlayerPosition()
242 | tapToStartLabel.isHidden = false
243 | score = 0
244 | scoreLabel.text = "Score: \(score)"
245 | maxScoreLabel.text = maxScore > 0 ? "Max Score: \(maxScore)" : ""
246 | state = .ready
247 | }
248 |
249 | func startGame() {
250 | startDisplayLink()
251 | startObstacleSpawnTimer()
252 | moveObstacles()
253 | maxScoreLabel.text = ""
254 | state = .playing
255 | }
256 |
257 | func gameOver() {
258 | shouldRotate = false
259 | stopObstacleSpawnTimer()
260 | stopDisplayLink()
261 | stopAnimators()
262 | tapToStartLabel.isHidden = false
263 | state = .over
264 | maxScore = max(maxScore, score)
265 | resetGame()
266 | }
267 |
268 | }
269 |
270 | extension ViewController {
271 |
272 | func stopAnimators() {
273 | playerAnimator?.stopAnimation(true)
274 | playerAnimator = nil
275 | playerRotator?.stopAnimation(true)
276 | playerRotator = nil
277 | obstacleAnimators.forEach { $0.stopAnimation(true) }
278 | obstacleAnimators = []
279 | }
280 |
281 | func rotate(_ duration: TimeInterval) {
282 | guard shouldRotate else { return }
283 |
284 | let cubicParameters = UICubicTimingParameters(controlPoint1: CGPoint(x: 0.0, y: 0.4), controlPoint2: CGPoint(x: 0.4, y: 1.0))
285 |
286 | playerRotator = UIViewPropertyAnimator(duration: duration, timingParameters: cubicParameters)
287 |
288 | playerRotator?.addAnimations { // curve: .easeOut
289 | self.player.transform = self.player.transform.rotated(by: rotationAngle)
290 | }
291 | playerRotator?.addCompletion { _ in
292 | self.rotate(duration)
293 | }
294 | playerRotator?.startAnimation()
295 | }
296 |
297 | func jump() {
298 | tapToStartLabel.isHidden = true
299 |
300 | guard let currentHeight = player.layer.presentation()?.frame.origin.y else { return }
301 | playerAnimator?.stopAnimation(true)
302 |
303 | let finalHeight = currentHeight - jumpHeightStep
304 | let duration = jumpHeightStep/jumpVelocity
305 | shouldRotate = true
306 |
307 | playerAnimator = UIViewPropertyAnimator(duration: TimeInterval(duration), curve: .easeOut ){
308 | self.player.frame.origin.y = finalHeight
309 | }
310 | playerAnimator?.addCompletion { _ in
311 | self.shouldRotate = false
312 | self.fall()
313 | }
314 | playerAnimator?.startAnimation()
315 |
316 | rotate(Double(duration)/2.0)
317 | }
318 |
319 | func fall() {
320 | let finalHeight = view.frame.size.height
321 | let currentHeight = player.frame.origin.y
322 | let distanceToBottom = finalHeight - currentHeight
323 | let duration = distanceToBottom/fallVelocity
324 |
325 | playerAnimator = UIViewPropertyAnimator(duration: TimeInterval(duration), curve: .easeIn ){
326 | self.player.frame.origin.y = finalHeight
327 | }
328 | playerAnimator?.startAnimation()
329 | }
330 |
331 | }
332 |
333 |
--------------------------------------------------------------------------------
/Jumpy.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 8159EEE21D4796C5003812D8 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8159EEE11D4796C5003812D8 /* AppDelegate.swift */; };
11 | 8159EEE41D4796C5003812D8 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8159EEE31D4796C5003812D8 /* ViewController.swift */; };
12 | 8159EEE71D4796C5003812D8 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8159EEE51D4796C5003812D8 /* Main.storyboard */; };
13 | 8159EEE91D4796C5003812D8 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8159EEE81D4796C5003812D8 /* Assets.xcassets */; };
14 | 8159EEEC1D4796C5003812D8 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8159EEEA1D4796C5003812D8 /* LaunchScreen.storyboard */; };
15 | /* End PBXBuildFile section */
16 |
17 | /* Begin PBXFileReference section */
18 | 8159EEDE1D4796C5003812D8 /* Jumpy.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Jumpy.app; sourceTree = BUILT_PRODUCTS_DIR; };
19 | 8159EEE11D4796C5003812D8 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
20 | 8159EEE31D4796C5003812D8 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
21 | 8159EEE61D4796C5003812D8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
22 | 8159EEE81D4796C5003812D8 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
23 | 8159EEEB1D4796C5003812D8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
24 | 8159EEED1D4796C5003812D8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
25 | /* End PBXFileReference section */
26 |
27 | /* Begin PBXFrameworksBuildPhase section */
28 | 8159EEDB1D4796C5003812D8 /* Frameworks */ = {
29 | isa = PBXFrameworksBuildPhase;
30 | buildActionMask = 2147483647;
31 | files = (
32 | );
33 | runOnlyForDeploymentPostprocessing = 0;
34 | };
35 | /* End PBXFrameworksBuildPhase section */
36 |
37 | /* Begin PBXGroup section */
38 | 8159EED51D4796C5003812D8 = {
39 | isa = PBXGroup;
40 | children = (
41 | 8159EEE01D4796C5003812D8 /* Jumpy */,
42 | 8159EEDF1D4796C5003812D8 /* Products */,
43 | );
44 | sourceTree = "";
45 | };
46 | 8159EEDF1D4796C5003812D8 /* Products */ = {
47 | isa = PBXGroup;
48 | children = (
49 | 8159EEDE1D4796C5003812D8 /* Jumpy.app */,
50 | );
51 | name = Products;
52 | sourceTree = "";
53 | };
54 | 8159EEE01D4796C5003812D8 /* Jumpy */ = {
55 | isa = PBXGroup;
56 | children = (
57 | 8159EEE11D4796C5003812D8 /* AppDelegate.swift */,
58 | 8159EEE31D4796C5003812D8 /* ViewController.swift */,
59 | 8159EEE51D4796C5003812D8 /* Main.storyboard */,
60 | 8159EEE81D4796C5003812D8 /* Assets.xcassets */,
61 | 8159EEEA1D4796C5003812D8 /* LaunchScreen.storyboard */,
62 | 8159EEED1D4796C5003812D8 /* Info.plist */,
63 | );
64 | path = Jumpy;
65 | sourceTree = "";
66 | };
67 | /* End PBXGroup section */
68 |
69 | /* Begin PBXNativeTarget section */
70 | 8159EEDD1D4796C5003812D8 /* Jumpy */ = {
71 | isa = PBXNativeTarget;
72 | buildConfigurationList = 8159EEF01D4796C5003812D8 /* Build configuration list for PBXNativeTarget "Jumpy" */;
73 | buildPhases = (
74 | 8159EEDA1D4796C5003812D8 /* Sources */,
75 | 8159EEDB1D4796C5003812D8 /* Frameworks */,
76 | 8159EEDC1D4796C5003812D8 /* Resources */,
77 | );
78 | buildRules = (
79 | );
80 | dependencies = (
81 | );
82 | name = Jumpy;
83 | productName = Jumpy;
84 | productReference = 8159EEDE1D4796C5003812D8 /* Jumpy.app */;
85 | productType = "com.apple.product-type.application";
86 | };
87 | /* End PBXNativeTarget section */
88 |
89 | /* Begin PBXProject section */
90 | 8159EED61D4796C5003812D8 /* Project object */ = {
91 | isa = PBXProject;
92 | attributes = {
93 | LastSwiftUpdateCheck = 0800;
94 | LastUpgradeCheck = 0800;
95 | ORGANIZATIONNAME = swiftification;
96 | TargetAttributes = {
97 | 8159EEDD1D4796C5003812D8 = {
98 | CreatedOnToolsVersion = 8.0;
99 | LastSwiftMigration = 0800;
100 | ProvisioningStyle = Automatic;
101 | };
102 | };
103 | };
104 | buildConfigurationList = 8159EED91D4796C5003812D8 /* Build configuration list for PBXProject "Jumpy" */;
105 | compatibilityVersion = "Xcode 3.2";
106 | developmentRegion = English;
107 | hasScannedForEncodings = 0;
108 | knownRegions = (
109 | en,
110 | Base,
111 | );
112 | mainGroup = 8159EED51D4796C5003812D8;
113 | productRefGroup = 8159EEDF1D4796C5003812D8 /* Products */;
114 | projectDirPath = "";
115 | projectRoot = "";
116 | targets = (
117 | 8159EEDD1D4796C5003812D8 /* Jumpy */,
118 | );
119 | };
120 | /* End PBXProject section */
121 |
122 | /* Begin PBXResourcesBuildPhase section */
123 | 8159EEDC1D4796C5003812D8 /* Resources */ = {
124 | isa = PBXResourcesBuildPhase;
125 | buildActionMask = 2147483647;
126 | files = (
127 | 8159EEEC1D4796C5003812D8 /* LaunchScreen.storyboard in Resources */,
128 | 8159EEE91D4796C5003812D8 /* Assets.xcassets in Resources */,
129 | 8159EEE71D4796C5003812D8 /* Main.storyboard in Resources */,
130 | );
131 | runOnlyForDeploymentPostprocessing = 0;
132 | };
133 | /* End PBXResourcesBuildPhase section */
134 |
135 | /* Begin PBXSourcesBuildPhase section */
136 | 8159EEDA1D4796C5003812D8 /* Sources */ = {
137 | isa = PBXSourcesBuildPhase;
138 | buildActionMask = 2147483647;
139 | files = (
140 | 8159EEE41D4796C5003812D8 /* ViewController.swift in Sources */,
141 | 8159EEE21D4796C5003812D8 /* AppDelegate.swift in Sources */,
142 | );
143 | runOnlyForDeploymentPostprocessing = 0;
144 | };
145 | /* End PBXSourcesBuildPhase section */
146 |
147 | /* Begin PBXVariantGroup section */
148 | 8159EEE51D4796C5003812D8 /* Main.storyboard */ = {
149 | isa = PBXVariantGroup;
150 | children = (
151 | 8159EEE61D4796C5003812D8 /* Base */,
152 | );
153 | name = Main.storyboard;
154 | sourceTree = "";
155 | };
156 | 8159EEEA1D4796C5003812D8 /* LaunchScreen.storyboard */ = {
157 | isa = PBXVariantGroup;
158 | children = (
159 | 8159EEEB1D4796C5003812D8 /* Base */,
160 | );
161 | name = LaunchScreen.storyboard;
162 | sourceTree = "";
163 | };
164 | /* End PBXVariantGroup section */
165 |
166 | /* Begin XCBuildConfiguration section */
167 | 8159EEEE1D4796C5003812D8 /* Debug */ = {
168 | isa = XCBuildConfiguration;
169 | buildSettings = {
170 | ALWAYS_SEARCH_USER_PATHS = NO;
171 | CLANG_ANALYZER_NONNULL = YES;
172 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
173 | CLANG_CXX_LIBRARY = "libc++";
174 | CLANG_ENABLE_MODULES = YES;
175 | CLANG_ENABLE_OBJC_ARC = YES;
176 | CLANG_WARN_BOOL_CONVERSION = YES;
177 | CLANG_WARN_CONSTANT_CONVERSION = YES;
178 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
179 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
180 | CLANG_WARN_EMPTY_BODY = YES;
181 | CLANG_WARN_ENUM_CONVERSION = YES;
182 | CLANG_WARN_INT_CONVERSION = YES;
183 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
184 | CLANG_WARN_UNREACHABLE_CODE = YES;
185 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
186 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
187 | COPY_PHASE_STRIP = NO;
188 | DEBUG_INFORMATION_FORMAT = dwarf;
189 | ENABLE_STRICT_OBJC_MSGSEND = YES;
190 | ENABLE_TESTABILITY = YES;
191 | GCC_C_LANGUAGE_STANDARD = gnu99;
192 | GCC_DYNAMIC_NO_PIC = NO;
193 | GCC_NO_COMMON_BLOCKS = YES;
194 | GCC_OPTIMIZATION_LEVEL = 0;
195 | GCC_PREPROCESSOR_DEFINITIONS = (
196 | "DEBUG=1",
197 | "$(inherited)",
198 | );
199 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
200 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
201 | GCC_WARN_UNDECLARED_SELECTOR = YES;
202 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
203 | GCC_WARN_UNUSED_FUNCTION = YES;
204 | GCC_WARN_UNUSED_VARIABLE = YES;
205 | IPHONEOS_DEPLOYMENT_TARGET = 10.0;
206 | MTL_ENABLE_DEBUG_INFO = YES;
207 | ONLY_ACTIVE_ARCH = YES;
208 | SDKROOT = iphoneos;
209 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
210 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
211 | TARGETED_DEVICE_FAMILY = "1,2";
212 | };
213 | name = Debug;
214 | };
215 | 8159EEEF1D4796C5003812D8 /* Release */ = {
216 | isa = XCBuildConfiguration;
217 | buildSettings = {
218 | ALWAYS_SEARCH_USER_PATHS = NO;
219 | CLANG_ANALYZER_NONNULL = YES;
220 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
221 | CLANG_CXX_LIBRARY = "libc++";
222 | CLANG_ENABLE_MODULES = YES;
223 | CLANG_ENABLE_OBJC_ARC = YES;
224 | CLANG_WARN_BOOL_CONVERSION = YES;
225 | CLANG_WARN_CONSTANT_CONVERSION = YES;
226 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
227 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
228 | CLANG_WARN_EMPTY_BODY = YES;
229 | CLANG_WARN_ENUM_CONVERSION = YES;
230 | CLANG_WARN_INT_CONVERSION = YES;
231 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
232 | CLANG_WARN_UNREACHABLE_CODE = YES;
233 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
234 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
235 | COPY_PHASE_STRIP = NO;
236 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
237 | ENABLE_NS_ASSERTIONS = NO;
238 | ENABLE_STRICT_OBJC_MSGSEND = YES;
239 | GCC_C_LANGUAGE_STANDARD = gnu99;
240 | GCC_NO_COMMON_BLOCKS = YES;
241 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
242 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
243 | GCC_WARN_UNDECLARED_SELECTOR = YES;
244 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
245 | GCC_WARN_UNUSED_FUNCTION = YES;
246 | GCC_WARN_UNUSED_VARIABLE = YES;
247 | IPHONEOS_DEPLOYMENT_TARGET = 10.0;
248 | MTL_ENABLE_DEBUG_INFO = NO;
249 | SDKROOT = iphoneos;
250 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
251 | TARGETED_DEVICE_FAMILY = "1,2";
252 | VALIDATE_PRODUCT = YES;
253 | };
254 | name = Release;
255 | };
256 | 8159EEF11D4796C5003812D8 /* Debug */ = {
257 | isa = XCBuildConfiguration;
258 | buildSettings = {
259 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
260 | INFOPLIST_FILE = Jumpy/Info.plist;
261 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
262 | PRODUCT_BUNDLE_IDENTIFIER = com.jarmourato.jumpy;
263 | PRODUCT_NAME = "$(TARGET_NAME)";
264 | SWIFT_VERSION = 3.0;
265 | };
266 | name = Debug;
267 | };
268 | 8159EEF21D4796C5003812D8 /* Release */ = {
269 | isa = XCBuildConfiguration;
270 | buildSettings = {
271 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
272 | INFOPLIST_FILE = Jumpy/Info.plist;
273 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
274 | PRODUCT_BUNDLE_IDENTIFIER = com.jarmourato.jumpy;
275 | PRODUCT_NAME = "$(TARGET_NAME)";
276 | SWIFT_VERSION = 3.0;
277 | };
278 | name = Release;
279 | };
280 | /* End XCBuildConfiguration section */
281 |
282 | /* Begin XCConfigurationList section */
283 | 8159EED91D4796C5003812D8 /* Build configuration list for PBXProject "Jumpy" */ = {
284 | isa = XCConfigurationList;
285 | buildConfigurations = (
286 | 8159EEEE1D4796C5003812D8 /* Debug */,
287 | 8159EEEF1D4796C5003812D8 /* Release */,
288 | );
289 | defaultConfigurationIsVisible = 0;
290 | defaultConfigurationName = Release;
291 | };
292 | 8159EEF01D4796C5003812D8 /* Build configuration list for PBXNativeTarget "Jumpy" */ = {
293 | isa = XCConfigurationList;
294 | buildConfigurations = (
295 | 8159EEF11D4796C5003812D8 /* Debug */,
296 | 8159EEF21D4796C5003812D8 /* Release */,
297 | );
298 | defaultConfigurationIsVisible = 0;
299 | defaultConfigurationName = Release;
300 | };
301 | /* End XCConfigurationList section */
302 | };
303 | rootObject = 8159EED61D4796C5003812D8 /* Project object */;
304 | }
305 |
--------------------------------------------------------------------------------