Skip to content

Commit a0ba35c

Browse files
committed
Improve triangle peg collision
1 parent d1160db commit a0ba35c

File tree

8 files changed

+77
-34
lines changed

8 files changed

+77
-34
lines changed

‎ps4/peggleclone/SLGameEngine/SLGameEngine.swift‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,11 @@ class SLGameEngine {
175175
}
176176

177177
if numOfCannonBallsLeft == 0 && cannonBallCount == 0 {
178-
gameLogicDelegate.gameLose()
178+
if numOfOrangePegs == 0 {
179+
gameLogicDelegate.gameWin()
180+
} else {
181+
gameLogicDelegate.gameLose()
182+
}
179183
}
180184
}
181185

‎ps4/peggleclone/SLPhysicsEngine/SLPhysicsBody.swift‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ protocol SLPhysicsBody {
2020
var width: Double { get set }
2121
var hasCollided: Bool { get set }
2222
var canIgnore: Bool { get set }
23+
var previousPosition: Point { get set }
2324

2425
func moveTo(position: Point)
2526

‎ps4/peggleclone/SLPhysicsEngine/SLPhysicsBucket.swift‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,18 @@ class SLPhysicsBucket: SLPhysicsBody {
1919
var width: Double
2020
var hasCollided: Bool = false
2121
var canIgnore: Bool = false
22+
var previousPosition: Point
2223

2324
init(position: Point, height: Double, width: Double) {
2425
self.position = position
2526
self.height = height
2627
self.width = width
28+
self.previousPosition = position
2729
}
2830

2931
func moveTo(position: Point) {
3032
self.position = position
33+
self.previousPosition = position
3134
}
3235

3336
func setVelocity(newVelocity: Vector) {

‎ps4/peggleclone/SLPhysicsEngine/SLPhysicsCircle.swift‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ class SLPhysicsCircle: SLPhysicsBody {
2121
var radius: Double
2222
var hasCollided = false
2323
var canIgnore = false
24+
var previousPosition: Point
2425

2526
init(velocity: Vector,
2627
position: Point,
@@ -35,6 +36,7 @@ class SLPhysicsCircle: SLPhysicsBody {
3536
self.mass = Double.pi * radius * radius
3637
self.height = radius * 2
3738
self.width = radius * 2
39+
self.previousPosition = position
3840
}
3941

4042
init(position: Point, isDynamic: Bool, radius: Double) {
@@ -46,9 +48,11 @@ class SLPhysicsCircle: SLPhysicsBody {
4648
self.mass = Double.pi * radius * radius
4749
self.height = radius * 2
4850
self.width = radius * 2
51+
self.previousPosition = position
4952
}
5053

5154
func moveTo(position: Point) {
55+
self.previousPosition = position
5256
self.position = position
5357
}
5458

@@ -117,4 +121,8 @@ class SLPhysicsCircle: SLPhysicsBody {
117121
func addForceToVelocity(force: Vector) {
118122
setVelocity(newVelocity: force.addTo(vector: self.velocity))
119123
}
124+
125+
func containsPoint(_ point: Point) -> Bool {
126+
point.distanceFrom(point: position) <= radius
127+
}
120128
}

‎ps4/peggleclone/SLPhysicsEngine/SLPhysicsCollision.swift‎

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -57,41 +57,56 @@ class SLPhysicsCollision {
5757
// circle.forces.append(collisionNormalVector
5858
// .multiplyWithScalar(scalar: speedAfterRestitution))
5959
// }
60-
let restitution = 2.5
61-
62-
if circleIntersectEdge(circle: circle, vertexOne: triangle.vertexOne, vertexTwo: triangle.vertexTwo) {
60+
var restitution = 0.85
61+
if circleIntersectTriangleVertices(triangle: triangle, circle: circle) {
62+
restitution = 0.95
63+
circle.setVelocity(newVelocity: circle.velocity.negate().multiplyWithScalar(scalar: restitution))
64+
} else if circleIntersectEdge(circle: circle, vertexOne: triangle.vertexOne, vertexTwo: triangle.vertexTwo) {
6365
// rebound counter clockwise
64-
let line = Vector(xDirection: triangle.vertexTwo.xCoordinate - triangle.vertexOne.xCoordinate,
65-
yDirection: triangle.vertexTwo.yCoordinate - triangle.vertexOne.yCoordinate)
66-
let normal = Vector(xDirection: -line.yDirection, yDirection: line.xDirection)
67-
let normalUnitVector = normal.multiplyWithScalar(scalar: 1/normal.magnitude)
68-
let resultant = circle.velocity
69-
.subtract(vector: normalUnitVector
70-
.multiplyWithScalar(scalar: 2 * circle.velocity.dotProductWith(vector: normalUnitVector)))
66+
// let line = Vector(xDirection: triangle.vertexTwo.xCoordinate - triangle.vertexOne.xCoordinate,
67+
// yDirection: triangle.vertexTwo.yCoordinate - triangle.vertexOne.yCoordinate)
68+
// let normal = Vector(xDirection: -line.yDirection, yDirection: line.xDirection)
69+
// let normalUnitVector = normal.multiplyWithScalar(scalar: 1/normal.magnitude)
70+
let resultant = Vector(xDirection: -circle.velocity.yDirection,
71+
yDirection: circle.velocity.xDirection)
72+
// let resultant = circle.velocity
73+
// .subtract(vector: normalUnitVector
74+
// .multiplyWithScalar(scalar: 2 * circle.velocity.dotProductWith(vector: normalUnitVector)))
7175
circle.setVelocity(newVelocity: resultant.multiplyWithScalar(scalar: restitution))
7276
} else if circleIntersectEdge(circle: circle, vertexOne: triangle.vertexTwo, vertexTwo: triangle.vertexThree) {
7377
// rebound clockwise
74-
let line = Vector(xDirection: triangle.vertexThree.xCoordinate - triangle.vertexTwo.xCoordinate,
75-
yDirection: triangle.vertexThree.yCoordinate - triangle.vertexTwo.yCoordinate)
76-
let normal = Vector(xDirection: line.yDirection, yDirection: -line.xDirection)
77-
let normalUnitVector = normal.multiplyWithScalar(scalar: 1/normal.magnitude)
78-
let resultant = circle.velocity
79-
.subtract(vector: normalUnitVector
80-
.multiplyWithScalar(scalar: 2 * circle.velocity.dotProductWith(vector: normalUnitVector)))
78+
// let line = Vector(xDirection: triangle.vertexThree.xCoordinate - triangle.vertexTwo.xCoordinate,
79+
// yDirection: triangle.vertexThree.yCoordinate - triangle.vertexTwo.yCoordinate)
80+
// let normal = Vector(xDirection: line.yDirection, yDirection: -line.xDirection)
81+
// let normalUnitVector = normal.multiplyWithScalar(scalar: 1/normal.magnitude)
82+
let resultant = Vector(xDirection: circle.velocity.yDirection,
83+
yDirection: -circle.velocity.xDirection)
84+
// let resultant = circle.velocity
85+
// .subtract(vector: normalUnitVector
86+
// .multiplyWithScalar(scalar: 2 * circle.velocity.dotProductWith(vector: normalUnitVector)))
8187
circle.setVelocity(newVelocity: resultant.multiplyWithScalar(scalar: restitution))
8288
} else if circleIntersectEdge(circle: circle, vertexOne: triangle.vertexThree, vertexTwo: triangle.vertexOne) {
8389
// rebound clockwise
84-
let line = Vector(xDirection: triangle.vertexOne.xCoordinate - triangle.vertexThree.xCoordinate,
85-
yDirection: triangle.vertexOne.yCoordinate - triangle.vertexThree.yCoordinate)
86-
let normal = Vector(xDirection: line.yDirection, yDirection: -line.xDirection)
87-
let normalUnitVector = normal.multiplyWithScalar(scalar: 1/normal.magnitude)
88-
let resultant = circle.velocity
89-
.subtract(vector: normalUnitVector
90-
.multiplyWithScalar(scalar: 2 * circle.velocity.dotProductWith(vector: normalUnitVector)))
90+
// let line = Vector(xDirection: triangle.vertexOne.xCoordinate - triangle.vertexThree.xCoordinate,
91+
// yDirection: triangle.vertexOne.yCoordinate - triangle.vertexThree.yCoordinate)
92+
// let normal = Vector(xDirection: line.yDirection, yDirection: -line.xDirection)
93+
// let normalUnitVector = normal.multiplyWithScalar(scalar: 1/normal.magnitude)
94+
let resultant = Vector(xDirection: circle.velocity.yDirection,
95+
yDirection: -circle.velocity.xDirection)
96+
// let resultant = circle.velocity
97+
// .subtract(vector: normalUnitVector
98+
// .multiplyWithScalar(scalar: 2 * circle.velocity.dotProductWith(vector: normalUnitVector)))
9199
circle.setVelocity(newVelocity: resultant.multiplyWithScalar(scalar: restitution))
92100
}
93101
}
94102

103+
private func circleIntersectTriangleVertices(
104+
triangle: SLPhysicsTriangle, circle: SLPhysicsCircle) -> Bool {
105+
circle.containsPoint(triangle.vertexOne)
106+
|| circle.containsPoint(triangle.vertexTwo)
107+
|| circle.containsPoint(triangle.vertexThree)
108+
}
109+
95110
private func circleIntersectEdge(circle: SLPhysicsCircle, vertexOne: Point, vertexTwo: Point) -> Bool {
96111
let radiusSqr = circle.radius * circle.radius
97112

‎ps4/peggleclone/SLPhysicsEngine/SLPhysicsTriangle.swift‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ class SLPhysicsTriangle: SLPhysicsBody {
2222
var vertexOne: Point
2323
var vertexTwo: Point
2424
var vertexThree: Point
25+
var previousPosition: Point
2526

2627
init(velocity: Vector,
2728
position: Point,
@@ -42,6 +43,7 @@ class SLPhysicsTriangle: SLPhysicsBody {
4243
yCoordinate: position.yCoordinate + height / 2)
4344
self.vertexThree = Point(xCoordinate: position.xCoordinate + width / 2,
4445
yCoordinate: position.yCoordinate + height / 2)
46+
self.previousPosition = position
4547
}
4648

4749
init(position: Point, height: Double, width: Double, isDynamic: Bool) {
@@ -58,10 +60,12 @@ class SLPhysicsTriangle: SLPhysicsBody {
5860
yCoordinate: position.yCoordinate + height / 2)
5961
self.vertexThree = Point(xCoordinate: position.xCoordinate + width / 2,
6062
yCoordinate: position.yCoordinate + height / 2)
63+
self.previousPosition = position
6164
}
6265

6366
func moveTo(position: Point) {
6467
self.position = position
68+
self.previousPosition = position
6569
}
6670

6771
func setVelocity(newVelocity: Vector) {

‎ps4/peggleclone/SLPhysicsEngine/SLPhysicsWorld.swift‎

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -129,23 +129,30 @@ class SLPhysicsWorld {
129129
let secondBody = collision.secondBody
130130
if firstBody.intersectWith(physicsBody: secondBody) {
131131
// translate them
132-
let intersectAmount = getCircleIntersectAmount(firstBody, secondBody)
133-
// move the dynamic one only
134-
if firstBody.isDynamic {
135-
// move back by intersect amount
136-
firstBody.moveBackBy(distance: intersectAmount)
132+
if let firstCircle = firstBody as? SLPhysicsCircle,
133+
let secondCircle = secondBody as? SLPhysicsCircle {
134+
let intersectAmount = getCircleIntersectAmount(firstCircle, secondCircle)
135+
// move the dynamic one only
136+
if firstCircle.isDynamic {
137+
firstCircle.moveBackBy(distance: intersectAmount)
138+
} else if secondCircle.isDynamic {
139+
secondCircle.moveBackBy(distance: intersectAmount)
140+
}
137141
} else {
138-
// move back by intersect amount
139-
secondBody.moveBackBy(distance: intersectAmount)
142+
if firstBody.isDynamic {
143+
firstBody.moveTo(position: firstBody.previousPosition)
144+
} else {
145+
secondBody.moveTo(position: secondBody.previousPosition)
146+
}
140147
}
141148
}
142149
}
143150
}
144151

145-
private func getCircleIntersectAmount(_ firstBody: SLPhysicsBody, _ secondBody: SLPhysicsBody) -> Double {
152+
private func getCircleIntersectAmount(_ firstBody: SLPhysicsCircle, _ secondBody: SLPhysicsCircle) -> Double {
146153
let xDistance = firstBody.position.xCoordinate - secondBody.position.xCoordinate
147154
let yDistance = firstBody.position.yCoordinate - secondBody.position.yCoordinate
148-
let closestRange = firstBody.width / 2 + secondBody.width / 2
155+
let closestRange = firstBody.radius + secondBody.radius
149156

150157
return closestRange - sqrt((xDistance * xDistance + yDistance * yDistance))
151158
}

‎ps4/peggleclone/Views/LevelDesigner/ButtonsRowView.swift‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ struct ButtonsRowView: View {
4747
.padding()
4848

4949
Button("START") {
50+
levelManager.changeLevel(level: levelManager.level)
5051
gameEngineManager.loadLevel(levelManager: levelManager)
5152
gameEngineManager.start()
5253
gameState = GameState.startFromLevelDesigner

0 commit comments

Comments
 (0)