-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathSKDamagableSpriteNode.swift
158 lines (113 loc) · 4.47 KB
/
SKDamagableSpriteNode.swift
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
extension NSDate: Comparable { }
public func ==(lhs: NSDate, rhs: NSDate) -> Bool {
return lhs.isEqualToDate(rhs)
}
public func <(lhs: NSDate, rhs: NSDate) -> Bool {
return lhs.compare(rhs) == .OrderedAscending
}
//
// Damageable.swift
//
import Foundation
import SpriteKit
import UIKit
import AudioToolbox
/**
Protocol & extension that adds "damagable" functionality to a SKNode
- Node gets life points that can be substracted
- onDeath() is triggered when the node "dies"
- Support for nodes that have children. Use it when all of them should be able to get damaged but the life points (of the parent node) should only be substracted once for each damaging event (i.e. when the hero's body parts are all children and both feets are contacted by the same fire)
Usage:
1) Create a class that conforms to DamagableNode for your parent node and a class that conforms to DamageChild for all your parent nodes children
2) If you want to apply damage to a node check if the node conforms to "Damagable" and apply the damage via subtractHealthPoints() or use getAffectedSKNode() to access the parent/master node and do what ever you want
*/
protocol SKDamagable {
/// Subtract health points
func subtractHealthPoints(number:Int)
/// Returns health points
func getHealthPoints() -> Int
/// Returns self if it is the father node, otherwise it should return the parent node
func getAffectedSKNode() -> SKNode
}
protocol SKDamagableChild:SKDamagable {
var parentNode:SKDamageableMaster! { get set }
}
/// Class redirects all damaging events to the parent node
extension SKDamagableChild where Self:SKNode {
/// Substract health points from the parents node call this only when you are sure the same damage event is not called by other children of your parent
func subtractHealthPoints(number: Int) {
parentNode.subtractHealthPoints(number)
}
/// Returns health points of master node
func getHealthPoints() -> Int {
return parentNode.getHealthPoints()
}
/// Returns master node
func getAffectedSKNode() -> SKNode {
return parentNode.getAffectedSKNode()
}
}
class SKDamagableSpriteNode:SKSpriteNode, SKDamagableChild {
var parentNode: SKDamageableMaster!
init(parentNode:SKDamageableMaster, texture:SKTexture) {
self.parentNode = parentNode
super.init(texture: texture, color: UIColor.whiteColor(), size: texture.size())
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
/* Master node */
protocol SKDamageableMaster: class, SKDamagable {
var healthPoints:Int { get set }
func updateHealthPoints(number:Int) -> Void
func afterUpdateHealthPoints() -> Void
func onDeath() -> Void
}
/* Master node */
extension SKDamageableMaster where Self:SKNode {
func subtractHealthPoints(number:Int) {
updateHealthPoints(healthPoints-number)
}
func updateHealthPoints(number:Int) {
if (number <= 0) {
healthPoints = 0
onDeath()
} else {
healthPoints = number
}
afterUpdateHealthPoints()
}
func getHealthPoints()->Int {
return self.healthPoints
}
func getAffectedSKNode() -> SKNode {
return self as SKNode
}
}
/// Protocol that adds SKDamageEvents to SKDamagable
protocol SKDamagableWithDamageEvents:class, SKDamagable, SKDamagableEventManager {
/// Adds and applies SKDamageEvent and subtracts health of node
func addAndApplyDamageEvent(event: SKDamageEvent) -> Void
}
/// Default implementation for protocol SKDamagableWithDamageEvents
extension SKDamagableWithDamageEvents {
/// Adds and applies SKDamageEvent and subtracts health of node
func addAndApplyDamageEvent(event: SKDamageEvent) -> Void {
event.applied = true
event.appliedTime = NSDate().timeIntervalSince1970
damageEvents.append(event)
self.subtractHealthPoints(event.damagePoints)
print(self.getHealthPoints())
}
}
/// Updates an SKLabelNode with new health points & vibrates
protocol DamageableUserCharacter:SKDamageableMaster, SKDamagableWithDamageEvents {
var healthPointsLabelNode:SKLabelNode { get }
}
extension DamageableUserCharacter {
func afterUpdateHealthPoints() {
healthPointsLabelNode.text = "\(healthPoints)"
AudioServicesPlayAlertSound(SystemSoundID(kSystemSoundID_Vibrate))
}
}