-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCollider.cpp
129 lines (101 loc) · 3.6 KB
/
Collider.cpp
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
#include "Collider.h"
Collider::Collider(sf::RectangleShape &a_oBody, bool a_bCanCollideTop) :
m_oBody(a_oBody), m_bCanCollideTop(a_bCanCollideTop),
m_oTriangleBody2(sf::ConvexShape()), m_oShape(Rectangle)
{
}
Collider::Collider(sf::ConvexShape &a_oTriangleBody, sf::Vector2f a_oPosition) :
m_oBody(sf::RectangleShape()), m_bCanCollideTop(false),
m_oTriangleBody2(a_oTriangleBody), m_oShape(Triangle), m_oPosition(a_oPosition)
{
}
Collider::~Collider()
{
}
void Collider::Move(float a_dX, float a_dY) {
if (m_oShape == Rectangle)
m_oBody.move(a_dX, a_dY);
else
m_oTriangleBody2.move(a_dX, a_dY);
}
sf::Vector2f Collider::GetPosition() {
if (m_oShape == Rectangle)
return m_oBody.getPosition();
else
return m_oPosition;
}
sf::Vector2f Collider::GetSize() {
if (m_oShape == Rectangle)
return m_oBody.getSize();
else {
sf::FloatRect oDimensions = m_oTriangleBody2.getLocalBounds();
return sf::Vector2f(oDimensions.width, oDimensions.height);
}
}
CollisionType Collider::CheckCollision(Collider &a_oOther) {
sf::Vector2f oThisPosition = GetPosition();
// Top and Bottom of the Block.
float dTop = oThisPosition.y;
float dBottom = dTop + GetSize().y;
// Right and Left of the Block.
float dLeft = oThisPosition.x;
float dRight = dLeft + GetSize().x;
sf::Vector2f oOtherPosition = a_oOther.GetPosition();
// Top and Bottom of the other object.
float dOtherTop = oOtherPosition.y;
float dOtherBottom = oOtherPosition.y + a_oOther.GetSize().y;
float dOtherLeft = oOtherPosition.x;
float dOtherRight = dOtherLeft + a_oOther.GetSize().x;
// Collision Variables.
bool bXCollision = ((dLeft >= dOtherLeft && dLeft <= dOtherRight) ||
(dRight >= dOtherLeft && dRight <= dOtherRight));
// The top of the block collided with the bottom of the other object.
bool bTopCollision = (dTop >= dOtherTop && dTop <= dOtherBottom);
// The bottom of the block collided with the top of the other object.
bool bBottomCollision = (dBottom <= dOtherBottom && dBottom >= dOtherTop);
// If the other object is a rectangle, check for collisions:
if (a_oOther.m_oShape == Rectangle) {
if (bXCollision) {
if (bTopCollision)
return Death;
else if (bBottomCollision) {
if (dBottom > dOtherTop +3) // The block isn't "on top of the CRectObject". It should die.
return Death;
else if (!a_oOther.m_bCanCollideTop)
return Death;
else
m_oBody.move(0, -(abs(dOtherTop - dBottom))); // To adjust it so that it is on the platform.
return AllowedBottomCollision;
}
else
return XCollision;
}
else
return None;
}
// Otherwise, the shape is a triangle.
else {
if (bXCollision) {
if (bTopCollision)
return Death;
else if (bBottomCollision) {
// We will have to calculate if the left or right vertice of the block is in the triangle.
// Calculate how "far up" the block is the triangle.
float dElevation = (dOtherBottom - dBottom) / a_oOther.GetSize().y;
float dHalfSideLength = a_oOther.GetSize().x / 2;
float dTriangleLeft = dOtherLeft + (dElevation * dHalfSideLength);
float dTriangleRight = dOtherLeft + dHalfSideLength + ((1 - dElevation) * dHalfSideLength);
bool bBlockLeftofTriangle = dRight < dTriangleLeft;
bool bBlockRightofTriangle = dLeft > dTriangleRight;
if (!(bBlockLeftofTriangle || bBlockRightofTriangle)) // The block is within the triangle.
return Death;
else
return XCollision;
}
else
return XCollision;
}
else
return None;
}
}