Skip to content

Commit 1ddd5af

Browse files
committed
Adventure: Version 1.4, 2015-01-17
Swift refactoring to remove global lets and vars, add multiplayer support, and support for game controllers.
1 parent dd08ead commit 1ddd5af

39 files changed

+2149
-1958
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
Copyright (C) 2015 Apple Inc. All Rights Reserved.
3+
See LICENSE.txt for this sample’s licensing information
4+
5+
Abstract:
6+
Defines iOS-specific extensions for the layered character scene.
7+
*/
8+
9+
import SpriteKit
10+
11+
extension AdventureScene {
12+
// MARK: Touch Handling
13+
14+
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
15+
// If we have no hero, we don't need to update the user interface at all.
16+
if heroes.isEmpty || touches.count <= 0 {
17+
return
18+
}
19+
20+
// If a touch has already been processed on the default player (i.e. the only player),
21+
// don't process another one until the next event loop.
22+
if defaultPlayer.movementTouch != nil {
23+
return
24+
}
25+
26+
let touch = touches.anyObject() as UITouch
27+
28+
defaultPlayer.targetLocation = touch.locationInNode(defaultPlayer.hero!.parent)
29+
30+
let nodes = nodesAtPoint(touch.locationInNode(self)) as [SKNode]
31+
32+
let enemyBitmask = ColliderType.GoblinOrBoss.rawValue | ColliderType.Cave.rawValue
33+
34+
var heroWantsToAttack = false
35+
36+
for node in nodes {
37+
// There are multiple values for `ColliderType`. We need to check if we should attack.
38+
if let body = node.physicsBody {
39+
if body.categoryBitMask & enemyBitmask > 0 {
40+
heroWantsToAttack = true
41+
}
42+
}
43+
}
44+
45+
defaultPlayer.fireAction = heroWantsToAttack
46+
defaultPlayer.moveRequested = !heroWantsToAttack
47+
defaultPlayer.movementTouch = touch
48+
}
49+
50+
override func touchesMoved(touches: NSSet, withEvent event: UIEvent) {
51+
// If we have no hero, we don't need to update the user interface at all.
52+
if heroes.isEmpty || touches.count <= 0 {
53+
return
54+
}
55+
56+
// If a touch has been previously recorded, move the player in the direction of the previous
57+
// touch.
58+
if let touch = defaultPlayer.movementTouch {
59+
if touches.containsObject(touch) {
60+
defaultPlayer.targetLocation = touch.locationInNode(defaultPlayer.hero!.parent)
61+
62+
if !defaultPlayer.fireAction {
63+
defaultPlayer.moveRequested = true
64+
}
65+
}
66+
}
67+
}
68+
69+
override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
70+
// If we have no hero, we don't need to update the user interface at all.
71+
if heroes.isEmpty || touches.count <= 0 {
72+
return
73+
}
74+
75+
// If there was a touch being tracked, stop tracking it. Don't move the player anywhere.
76+
if let touch = defaultPlayer.movementTouch {
77+
if touches.containsObject(touch) {
78+
defaultPlayer.movementTouch = nil
79+
defaultPlayer.fireAction = false
80+
}
81+
}
82+
}
83+
}
+4-32
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,18 @@
11
/*
2-
Copyright (C) 2014 Apple Inc. All Rights Reserved.
2+
Copyright (C) 2015 Apple Inc. All Rights Reserved.
33
See LICENSE.txt for this sample’s licensing information
44

55
Abstract:
6-
7-
Application delegate for iOS Adventure
8-
6+
Application delegate for iOS Adventure.
97
*/
108

119

1210
import UIKit
1311

1412
@UIApplicationMain
1513
class AppDelegate: NSObject, UIApplicationDelegate {
16-
var window: UIWindow?
17-
18-
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary) -> Bool {
19-
// Override point for customization after application launch.
20-
return true
21-
}
22-
23-
func applicationWillResignActive(application: UIApplication) {
24-
// 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.
25-
// 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.
26-
}
27-
28-
func applicationDidEnterBackground(application: UIApplication) {
29-
// 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.
30-
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
31-
}
32-
33-
func applicationWillEnterForeground(application: UIApplication) {
34-
// 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.
35-
}
36-
37-
func applicationDidBecomeActive(application: UIApplication) {
38-
// 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.
39-
}
40-
41-
func applicationWillTerminate(application: UIApplication) {
42-
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
43-
}
14+
// MARK: Properties
4415

16+
var window: UIWindow?
4517
}
4618

Adventure/Adventure iOS/Main.storyboard

+13-6
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2-
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6154.16" systemVersion="13D46" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" initialViewController="v0q-4l-l5M">
2+
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6250" systemVersion="14A388a" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" initialViewController="v0q-4l-l5M">
33
<dependencies>
4-
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6153.10"/>
4+
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6244"/>
55
</dependencies>
66
<scenes>
7-
<!--TtC13 Adventure iOS14 View Controller-->
7+
<!--View Controller-->
88
<scene sceneID="yyV-mO-CeJ">
99
<objects>
1010
<viewController id="v0q-4l-l5M" customClass="ViewController" customModule="Adventure_iOS" sceneMemberID="viewController">
@@ -19,11 +19,14 @@
1919
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="16A-mh-zAr" customClass="SKView">
2020
<rect key="frame" x="0.0" y="0.0" width="568" height="320"/>
2121
<subviews>
22+
<imageView userInteractionEnabled="NO" contentMode="center" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="xno-zg-Pex">
23+
<rect key="frame" x="0.0" y="0.0" width="568" height="320"/>
24+
</imageView>
2225
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="logo.png" translatesAutoresizingMaskIntoConstraints="NO" id="cbW-Js-lBh">
2326
<rect key="frame" x="97" y="-10" width="375" height="220"/>
2427
</imageView>
25-
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" style="gray" translatesAutoresizingMaskIntoConstraints="NO" id="pIz-Fq-R4D">
26-
<rect key="frame" x="274" y="195" width="20" height="20"/>
28+
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="pIz-Fq-R4D">
29+
<rect key="frame" x="266" y="178" width="37" height="37"/>
2730
</activityIndicatorView>
2831
<button opaque="NO" alpha="0.0" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="D3u-0r-EFd">
2932
<rect key="frame" x="52" y="238" width="187" height="56"/>
@@ -53,6 +56,7 @@
5356
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
5457
<constraints>
5558
<constraint firstAttribute="bottom" secondItem="D3u-0r-EFd" secondAttribute="bottom" constant="26" id="5jV-Q7-l2G"/>
59+
<constraint firstItem="xno-zg-Pex" firstAttribute="top" secondItem="16A-mh-zAr" secondAttribute="top" id="5ze-I9-NEH"/>
5660
<constraint firstAttribute="centerX" secondItem="pIz-Fq-R4D" secondAttribute="centerX" id="8g4-af-dfp"/>
5761
<constraint firstItem="D3u-0r-EFd" firstAttribute="leading" secondItem="16A-mh-zAr" secondAttribute="leading" constant="52" id="9D3-hX-UFe"/>
5862
<constraint firstAttribute="bottom" secondItem="pIz-Fq-R4D" secondAttribute="bottom" constant="105" id="LKU-Hc-gql"/>
@@ -61,8 +65,11 @@
6165
<constraint firstAttribute="trailing" secondItem="cbW-Js-lBh" secondAttribute="trailing" constant="96" id="dSX-to-wj0"/>
6266
<constraint firstItem="cbW-Js-lBh" firstAttribute="leading" secondItem="16A-mh-zAr" secondAttribute="leading" constant="97" id="eHT-Jy-563"/>
6367
<constraint firstItem="D3u-0r-EFd" firstAttribute="top" secondItem="8p3-dw-Wlu" secondAttribute="top" id="ewn-mk-Lai"/>
68+
<constraint firstItem="xno-zg-Pex" firstAttribute="leading" secondItem="16A-mh-zAr" secondAttribute="leading" id="gQo-J3-hX9"/>
69+
<constraint firstAttribute="trailing" secondItem="xno-zg-Pex" secondAttribute="trailing" id="mX6-Dp-HgX"/>
6470
<constraint firstAttribute="bottom" secondItem="cbW-Js-lBh" secondAttribute="bottom" constant="110" id="oL2-mb-Ifq"/>
6571
<constraint firstItem="D3u-0r-EFd" firstAttribute="bottom" secondItem="8p3-dw-Wlu" secondAttribute="bottom" id="ocY-aj-dcY"/>
72+
<constraint firstAttribute="bottom" secondItem="xno-zg-Pex" secondAttribute="bottom" id="vHi-db-N5e"/>
6673
<constraint firstItem="D3u-0r-EFd" firstAttribute="top" secondItem="cbW-Js-lBh" secondAttribute="bottom" constant="28" id="yGZ-09-NGS"/>
6774
</constraints>
6875
</view>
@@ -74,12 +81,12 @@
7481
<constraint firstItem="16A-mh-zAr" firstAttribute="top" secondItem="U97-k5-wGz" secondAttribute="top" id="PpF-NR-DvY"/>
7582
<constraint firstItem="16A-mh-zAr" firstAttribute="leading" secondItem="U97-k5-wGz" secondAttribute="leading" id="WwN-Ga-R6R"/>
7683
</constraints>
77-
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
7884
</view>
7985
<extendedEdge key="edgesForExtendedLayout"/>
8086
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
8187
<connections>
8288
<outlet property="archerButton" destination="D3u-0r-EFd" id="AJg-vF-7Bf"/>
89+
<outlet property="coverView" destination="xno-zg-Pex" id="q3f-OH-COR"/>
8390
<outlet property="gameLogo" destination="cbW-Js-lBh" id="ocP-sF-U5w"/>
8491
<outlet property="imageView" destination="cbW-Js-lBh" id="aBz-ax-hfk"/>
8592
<outlet property="loadingProgressIndicator" destination="pIz-Fq-R4D" id="0Hd-uO-EDE"/>

Adventure/Adventure iOS/ViewController.swift

+42-15
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
11
/*
2-
Copyright (C) 2014 Apple Inc. All Rights Reserved.
2+
Copyright (C) 2015 Apple Inc. All Rights Reserved.
33
See LICENSE.txt for this sample’s licensing information
44

55
Abstract:
6-
7-
Defines the iOS view controller for Adventure
8-
6+
Defines the iOS view controller for Adventure.
97
*/
108

119
import SpriteKit
1210

1311
class ViewController: UIViewController {
14-
@IBOutlet weak var skView: SKView!
12+
// MARK: Properties
13+
14+
@IBOutlet weak var coverView: UIImageView!
1515

16+
@IBOutlet weak var skView: SKView!
17+
1618
@IBOutlet weak var imageView: UIImageView!
1719

1820
@IBOutlet weak var gameLogo: UIImageView!
@@ -24,14 +26,28 @@ class ViewController: UIViewController {
2426
@IBOutlet weak var warriorButton: UIButton!
2527

2628
var scene: AdventureScene!
29+
30+
// MARK: View Life Cycle
31+
32+
override func viewDidLoad() {
33+
// On iPhone/iPod touch we want to see a similar amount of the scene as on iPad.
34+
// So, we set the scale of the image to be used to double the scale of the image,
35+
// This effectively scales the cover image to 50%, matching the scene scaling.
36+
var image = UIImage(named: "cover")!
37+
if UIDevice.currentDevice().userInterfaceIdiom == .Phone {
38+
image = UIImage(CGImage: image.CGImage, scale: image.scale * 2.0, orientation: UIImageOrientation.Up)!
39+
}
40+
41+
coverView.image = image
42+
}
2743

2844
override func viewWillAppear(animated: Bool) {
2945
super.viewWillAppear(animated)
3046

3147
// Start the progress indicator animation.
3248
loadingProgressIndicator.startAnimating()
3349

34-
AdventureScene.loadSceneAssetsWithCompletionHandler {
50+
AdventureScene.loadSceneAssetsWithCompletionHandler { loadedScene in
3551
var viewSize = self.view.bounds.size
3652

3753
// On iPhone/iPod touch we want to see a similar amount of the scene as on iPad.
@@ -42,34 +58,45 @@ class ViewController: UIViewController {
4258
viewSize.width *= 2
4359
}
4460

45-
self.scene = AdventureScene(size: viewSize)
61+
self.scene = loadedScene
62+
self.scene.size = viewSize
4663
self.scene.scaleMode = .AspectFill
4764

48-
self.loadingProgressIndicator.stopAnimating()
49-
self.loadingProgressIndicator.hidden = true
50-
65+
#if DEBUG
5166
self.skView.showsDrawCount = true
5267
self.skView.showsFPS = true
68+
#endif
5369

54-
self.skView.presentScene(self.scene)
55-
56-
UIView.animateWithDuration(2.0) {
57-
self.archerButton.alpha = 1.0
58-
self.warriorButton.alpha = 1.0
70+
self.scene.finishedMovingToView = {
71+
UIView.animateWithDuration(2.0, animations: {
72+
self.archerButton.alpha = 1.0
73+
self.warriorButton.alpha = 1.0
74+
self.coverView.alpha = 0.0
75+
}, completion: { finished in
76+
self.loadingProgressIndicator.stopAnimating()
77+
self.loadingProgressIndicator.hidden = true
78+
self.coverView.removeFromSuperview()
79+
})
5980
}
81+
82+
self.skView.presentScene(self.scene)
6083
}
6184
}
85+
86+
// MARK: IBActions
6287

6388
@IBAction func chooseArcher(_: AnyObject) {
6489
scene.startLevel(.Archer)
6590
gameLogo.hidden = true
91+
6692
warriorButton.hidden = true
6793
archerButton.hidden = true
6894
}
6995

7096
@IBAction func chooseWarrior(_: AnyObject) {
7197
scene.startLevel(.Warrior)
7298
gameLogo.hidden = true
99+
73100
warriorButton.hidden = true
74101
archerButton.hidden = true
75102
}

Adventure/Adventure iOS/iOSLayeredCharacterSceneEvents.swift

-74
This file was deleted.

0 commit comments

Comments
 (0)