Skip to content

Commit a1f6c14

Browse files
committed
Create delegate to handle powerups
1 parent c567c12 commit a1f6c14

File tree

9 files changed

+157
-23
lines changed

9 files changed

+157
-23
lines changed

‎ps4/peggleclone.xcodeproj/project.pbxproj‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
6834AD2727C762CA00F5A4E3 /* KaboomPeg.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6834AD2627C762CA00F5A4E3 /* KaboomPeg.swift */; };
2424
6834AD2927C76DB300F5A4E3 /* SpookyPegPersistance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6834AD2827C76DB300F5A4E3 /* SpookyPegPersistance.swift */; };
2525
6834AD2B27C76DC600F5A4E3 /* KaboomPegPersistance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6834AD2A27C76DC600F5A4E3 /* KaboomPegPersistance.swift */; };
26+
6834AD2D27C7D0A000F5A4E3 /* PowerUpHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6834AD2C27C7D09F00F5A4E3 /* PowerUpHandler.swift */; };
2627
684FFA3C27C4C4EA000CD3D5 /* Point.swift in Sources */ = {isa = PBXBuildFile; fileRef = 684FFA3B27C4C4E9000CD3D5 /* Point.swift */; };
2728
684FFA3E27C4D547000CD3D5 /* Vector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 684FFA3D27C4D547000CD3D5 /* Vector.swift */; };
2829
68686A9327B2E0D800B97394 /* GameCanvasView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68686A9227B2E0D800B97394 /* GameCanvasView.swift */; };
@@ -71,6 +72,7 @@
7172
6834AD2627C762CA00F5A4E3 /* KaboomPeg.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KaboomPeg.swift; sourceTree = "<group>"; };
7273
6834AD2827C76DB300F5A4E3 /* SpookyPegPersistance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpookyPegPersistance.swift; sourceTree = "<group>"; };
7374
6834AD2A27C76DC600F5A4E3 /* KaboomPegPersistance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KaboomPegPersistance.swift; sourceTree = "<group>"; };
75+
6834AD2C27C7D09F00F5A4E3 /* PowerUpHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PowerUpHandler.swift; sourceTree = "<group>"; };
7476
684FFA3B27C4C4E9000CD3D5 /* Point.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Point.swift; sourceTree = "<group>"; };
7577
684FFA3D27C4D547000CD3D5 /* Vector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Vector.swift; sourceTree = "<group>"; };
7678
68686A9227B2E0D800B97394 /* GameCanvasView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameCanvasView.swift; sourceTree = "<group>"; };
@@ -159,6 +161,7 @@
159161
isa = PBXGroup;
160162
children = (
161163
6831831427B4FEC900732E00 /* SLGameEngine.swift */,
164+
6834AD2C27C7D09F00F5A4E3 /* PowerUpHandler.swift */,
162165
);
163166
path = SLGameEngine;
164167
sourceTree = "<group>";
@@ -367,6 +370,7 @@
367370
687C2B4127B61CF500D1BB1E /* PegColor.swift in Sources */,
368371
68143567279EE7D700A16058 /* PegsRowView.swift in Sources */,
369372
68B6B8D527C54138004CE9E2 /* PeggleObjectPersistance.swift in Sources */,
373+
6834AD2D27C7D0A000F5A4E3 /* PowerUpHandler.swift in Sources */,
370374
6834AD2B27C76DC600F5A4E3 /* KaboomPegPersistance.swift in Sources */,
371375
684FFA3C27C4C4EA000CD3D5 /* Point.swift in Sources */,
372376
68143578279FF0FB00A16058 /* LevelDesignerCanvasView.swift in Sources */,

‎ps4/peggleclone/Models/KaboomPeg.swift‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
import Foundation
99

1010
class KaboomPeg: Peg {
11+
var activated = false
12+
var radiusOfExplosion: Double = 200.0
13+
1114
init(center: Point, radius: Double = 25) {
1215
super.init(color: .greenPeg, center: center, radius: radius)
1316
self.shadow = .red
@@ -27,4 +30,12 @@ class KaboomPeg: Peg {
2730
override func copy() -> Peg {
2831
KaboomPeg(center: self.center, radius: self.radius)
2932
}
33+
34+
func setActivated() {
35+
self.activated = true
36+
}
37+
38+
func setNotActivated() {
39+
self.activated = false
40+
}
3041
}

‎ps4/peggleclone/Models/Point.swift‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,15 @@ struct Point: Equatable {
2020
self.xCoordinate = xCoordinate
2121
self.yCoordinate = yCoordinate
2222
}
23+
24+
func distanceFrom(point: Point) -> Double {
25+
let xDist = xCoordinate - point.xCoordinate
26+
let yDist = yCoordinate - point.yCoordinate
27+
28+
return sqrt(xDist * xDist + yDist * yDist)
29+
}
30+
31+
func vectorTo(point: Point) -> Vector {
32+
Vector(xDirection: point.xCoordinate - xCoordinate, yDirection: point.yCoordinate - yCoordinate)
33+
}
2334
}

‎ps4/peggleclone/Models/SpookyPeg.swift‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ class SpookyPeg: Peg {
3030
self.activated = true
3131
}
3232

33+
func setNotActivated() {
34+
self.activated = false
35+
}
36+
3337
override func copy() -> Peg {
3438
SpookyPeg(center: self.center, radius: self.radius)
3539
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
//
2+
// PowerUpHandler.swift
3+
// peggleclone
4+
//
5+
// Created by Stuart Long on 24/2/22.
6+
//
7+
8+
import Foundation
9+
import SwiftUI
10+
11+
class PowerUpHandler {
12+
private var spookyBallsActivated = 0
13+
14+
func handlePowerUp(powerPeg: Peg, mappings: [PeggleObject: SLPhysicsBody], cannonBall: Peg) {
15+
if let spookyPeg = powerPeg as? SpookyPeg {
16+
if !spookyPeg.activated {
17+
spookyBallsActivated += 1
18+
print(spookyBallsActivated)
19+
spookyPeg.setActivated()
20+
}
21+
} else if let kaboomPeg = powerPeg as? KaboomPeg {
22+
if !kaboomPeg.activated {
23+
// find area of hit
24+
for (key, value) in mappings where isWithinExplosionRadius(kaboomPeg: kaboomPeg, physicsBody: value) {
25+
// TODO: make peggleobject have a glow method?
26+
if let peg = key as? Peg {
27+
peg.glow()
28+
value.setCollided()
29+
}
30+
}
31+
// move ball back
32+
guard let cannonBallPhysicsBody = mappings[cannonBall] else {
33+
return
34+
}
35+
if isWithinExplosionRadius(kaboomPeg: kaboomPeg, physicsBody: cannonBallPhysicsBody) {
36+
let forceDirection = kaboomPeg.center.vectorTo(point: cannonBallPhysicsBody.position)
37+
let distance = kaboomPeg.center.distanceFrom(point: cannonBallPhysicsBody.position)
38+
let ratio = 15 * (1 - distance / kaboomPeg.radiusOfExplosion)
39+
cannonBallPhysicsBody.addForceToVelocity(force: forceDirection.multiplyWithScalar(scalar: ratio))
40+
}
41+
kaboomPeg.setActivated()
42+
}
43+
}
44+
}
45+
46+
private func isWithinExplosionRadius(kaboomPeg: KaboomPeg, physicsBody: SLPhysicsBody) -> Bool {
47+
kaboomPeg.center.distanceFrom(point: physicsBody.position) <= kaboomPeg.radiusOfExplosion + physicsBody.width
48+
}
49+
50+
func removePowerPeg(powerPeg: Peg) {
51+
if let spookyPeg = powerPeg as? SpookyPeg {
52+
spookyPeg.setNotActivated()
53+
} else if let kaboomPeg = powerPeg as? KaboomPeg {
54+
kaboomPeg.setNotActivated()
55+
}
56+
}
57+
58+
func handleCannonBall(
59+
canvasDimension: CGRect, cannonBall: Peg, cannonBallPhysicsBody: SLPhysicsBody,
60+
gameLogicDelegate: GameLogicDelegate) {
61+
if spookyBallsActivated > 0 {
62+
gameLogicDelegate.spookCannonBall(cannonBall: cannonBall)
63+
}
64+
65+
if spookyBallsActivated > 0 && isOutOfScreen(peg: cannonBall, canvasDimensions: canvasDimension) {
66+
gameLogicDelegate.didMove(peggleObject: cannonBall,
67+
newLocation: Point(xCoordinate: cannonBall.center.xCoordinate, yCoordinate: 0))
68+
cannonBallPhysicsBody.moveTo(position: Point(xCoordinate: cannonBall.center.xCoordinate, yCoordinate: 0))
69+
cannonBallPhysicsBody
70+
.setVelocity(newVelocity: cannonBallPhysicsBody.velocity.multiplyWithScalar(scalar: 0.5))
71+
spookyBallsActivated -= 1
72+
print("used one spooky ball, \(spookyBallsActivated) left")
73+
}
74+
}
75+
76+
private func isOutOfScreen(peg: Peg, canvasDimensions: CGRect) -> Bool {
77+
peg.center.yCoordinate >= canvasDimensions.height + peg.radius
78+
}
79+
80+
func resetCount() {
81+
self.spookyBallsActivated = 0
82+
}
83+
}

‎ps4/peggleclone/SLGameEngine/SLGameEngine.swift‎

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class SLGameEngine {
2323
private var numOfCannonBallsLeft: Int
2424
private var numOfOrangePegs: Int
2525
private var cannonBallInBucket = false
26-
private var spookyBallsActivated = 0
26+
private var powerUpHandler = PowerUpHandler()
2727

2828
init(canvasDimensions: CGRect) {
2929
self.canvasDimensions = canvasDimensions
@@ -37,7 +37,7 @@ class SLGameEngine {
3737
self.bucket = bucket
3838
self.numOfCannonBallsLeft = 10
3939
self.numOfOrangePegs = 0
40-
self.spookyBallsActivated = 0
40+
self.powerUpHandler.resetCount()
4141

4242
var physicsObjects: [SLPhysicsBody] = []
4343
for peggleObject in level.peggleObjects {
@@ -123,7 +123,7 @@ class SLGameEngine {
123123
moveCannonBall(cannonBall, cannonBallPhysicsBody, gameLogicDelegate)
124124

125125
let collisions = cannonBallPhysicsBody.collisionsWith
126-
let currentCollisions = handleCollisions(collisions, gameLogicDelegate, cannonBallCount)
126+
let currentCollisions = handleCollisions(collisions, gameLogicDelegate, cannonBallCount, cannonBall)
127127

128128
let similarPositionLimit = 75
129129

@@ -170,7 +170,8 @@ class SLGameEngine {
170170
}
171171

172172
private func handleCollisions(
173-
_ collisions: [SLPhysicsBody], _ gameLogicDelegate: GameLogicDelegate, _ cannonBallCount: Int) -> [Peg] {
173+
_ collisions: [SLPhysicsBody], _ gameLogicDelegate: GameLogicDelegate,
174+
_ cannonBallCount: Int, _ cannonBall: Peg) -> [Peg] {
174175
var currentCollisions: [Peg] = []
175176

176177
for (key, value) in mappings where value.hasCollided {
@@ -179,17 +180,23 @@ class SLGameEngine {
179180
if contains(arr: collisions, physicsBody: value) {
180181
currentCollisions.append(peg)
181182
}
182-
if let spookyPeg = peg as? SpookyPeg {
183-
if !spookyPeg.activated {
184-
spookyBallsActivated += 1
185-
print(spookyBallsActivated)
186-
spookyPeg.setActivated()
187-
}
183+
// TODO: refactor
184+
if peg is SpookyPeg || peg is KaboomPeg {
185+
powerUpHandler.handlePowerUp(powerPeg: peg, mappings: mappings, cannonBall: cannonBall)
188186
}
187+
// if let spookyPeg = peg as? SpookyPeg {
188+
// if !spookyPeg.activated {
189+
// spookyBallsActivated += 1
190+
// print(spookyBallsActivated)
191+
// spookyPeg.setActivated()
192+
// }
193+
// }
194+
// TODO: add the handler
189195
if cannonBallCount == 0 {
190196
gameLogicDelegate.didRemove(peg: peg)
191197
mappings.removeValue(forKey: peg)
192198
value.ignore()
199+
powerUpHandler.removePowerPeg(powerPeg: peg)
193200
if peg.color == .orangeGlow {
194201
numOfOrangePegs -= 1
195202
if numOfOrangePegs == 0 {
@@ -203,26 +210,30 @@ class SLGameEngine {
203210
return currentCollisions
204211
}
205212

213+
// TODO: add handler
206214
private func moveCannonBall(
207215
_ cannonBall: Peg, _ cannonBallPhysicsBody: SLPhysicsBody, _ gameLogicDelegate: GameLogicDelegate) {
208216
cannonBall.center = cannonBallPhysicsBody.position
209217
gameLogicDelegate.didMove(peggleObject: cannonBall, newLocation: cannonBallPhysicsBody.position)
210-
if spookyBallsActivated > 0 {
211-
gameLogicDelegate.spookCannonBall(cannonBall: cannonBall)
212-
}
218+
// if spookyBallsActivated > 0 {
219+
// gameLogicDelegate.spookCannonBall(cannonBall: cannonBall)
220+
// }
213221
if isCannonBallInBucket(cannonBallPhysicsBody) {
214222
cannonBallInBucket = true
215223
}
216-
217-
if spookyBallsActivated > 0 && isOutOfScreen(peg: cannonBall) {
218-
gameLogicDelegate.didMove(peggleObject: cannonBall,
219-
newLocation: Point(xCoordinate: cannonBall.center.xCoordinate, yCoordinate: 0))
220-
cannonBallPhysicsBody.moveTo(position: Point(xCoordinate: cannonBall.center.xCoordinate, yCoordinate: 0))
221-
cannonBallPhysicsBody
222-
.setVelocity(newVelocity: cannonBallPhysicsBody.velocity.multiplyWithScalar(scalar: 0.5))
223-
spookyBallsActivated -= 1
224-
print("used one spooky ball, \(spookyBallsActivated) left")
225-
}
224+
powerUpHandler.handleCannonBall(canvasDimension: canvasDimensions,
225+
cannonBall: cannonBall,
226+
cannonBallPhysicsBody: cannonBallPhysicsBody,
227+
gameLogicDelegate: gameLogicDelegate)
228+
// if spookyBallsActivated > 0 && isOutOfScreen(peg: cannonBall) {
229+
// gameLogicDelegate.didMove(peggleObject: cannonBall,
230+
// newLocation: Point(xCoordinate: cannonBall.center.xCoordinate, yCoordinate: 0))
231+
// cannonBallPhysicsBody.moveTo(position: Point(xCoordinate: cannonBall.center.xCoordinate, yCoordinate: 0))
232+
// cannonBallPhysicsBody
233+
// .setVelocity(newVelocity: cannonBallPhysicsBody.velocity.multiplyWithScalar(scalar: 0.5))
234+
// spookyBallsActivated -= 1
235+
// print("used one spooky ball, \(spookyBallsActivated) left")
236+
// }
226237
}
227238

228239
private func isOutOfScreen(peg: Peg) -> Bool {

‎ps4/peggleclone/SLPhysicsEngine/SLPhysicsBody.swift‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,6 @@ protocol SLPhysicsBody {
4242
func addCollisionWith(physicsBody: SLPhysicsBody)
4343

4444
func clearCollisionsWith()
45+
46+
func addForceToVelocity(force: Vector)
4547
}

‎ps4/peggleclone/SLPhysicsEngine/SLPhysicsBucket.swift‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,4 +113,8 @@ class SLPhysicsBucket: SLPhysicsBody {
113113
func clearCollisionsWith() {
114114
// do nothing
115115
}
116+
117+
func addForceToVelocity(force: Vector) {
118+
// do nothing
119+
}
116120
}

‎ps4/peggleclone/SLPhysicsEngine/SLPhysicsCircle.swift‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,4 +111,8 @@ class SLPhysicsCircle: SLPhysicsBody {
111111
func clearCollisionsWith() {
112112
self.collisionsWith.removeAll()
113113
}
114+
115+
func addForceToVelocity(force: Vector) {
116+
setVelocity(newVelocity: force.addTo(vector: self.velocity))
117+
}
114118
}

0 commit comments

Comments
 (0)