Skip to content

Commit 58dff21

Browse files
committed
Add snapCollision functions
1 parent 1d19320 commit 58dff21

File tree

4 files changed

+156
-53
lines changed

4 files changed

+156
-53
lines changed

include/Object.h

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ class Object : virtual public sf::Sprite {
66
public:
77
Object();
88
Object(sf::Texture &tex);
9-
virtual bool check_collision(Object *obj) const = 0;
9+
virtual bool checkCollision(Object *obj) const = 0;
10+
virtual void snapCollision(Object *obj) = 0;
1011
virtual void drawCollision(sf::RenderTarget *target) const = 0;
1112

1213
sf::Vector2f m_spd_vec;
@@ -23,9 +24,14 @@ class Circle : public Object {
2324
Circle(sf::Texture &tex);
2425
Circle(sf::Texture &tex, float r) : Object(tex), m_radius(r) {}
2526

26-
bool check_collision(Object *obj) const override;
27-
bool check_collision(Circle *obj) const;
28-
bool check_collision(Rectangle *obj) const;
27+
bool checkCollision(Object *obj) const override;
28+
bool checkCollision(Circle *obj) const;
29+
bool checkCollision(Rectangle *obj) const;
30+
31+
void snapCollision(Object *obj) override;
32+
void snapCollision(Circle *obj);
33+
void snapCollision(Rectangle *obj);
34+
2935
void drawCollision(sf::RenderTarget *target) const override;
3036
float getRadius() const { return m_radius; }
3137

@@ -38,9 +44,15 @@ class Rectangle : public Object {
3844
Rectangle() : Object(), m_size(2, 2) {}
3945
Rectangle(sf::Texture &tex);
4046
Rectangle(sf::Texture &tex, sf::Vector2f size) : Object(tex), m_size(size) {}
41-
bool check_collision(Object *obj) const override;
42-
bool check_collision(Rectangle *obj) const;
43-
bool check_collision(Circle *obj) const;
47+
48+
bool checkCollision(Object *obj) const override;
49+
bool checkCollision(Rectangle *obj) const;
50+
bool checkCollision(Circle *obj) const;
51+
52+
void snapCollision(Object *obj) override;
53+
void snapCollision(Circle *obj);
54+
void snapCollision(Rectangle *obj);
55+
4456
void drawCollision(sf::RenderTarget *target) const override;
4557
const sf::Vector2f getSize() const { return m_size; }
4658

src/Game.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ Game::Game(int framerate) : m_input(0) {
3838
c.setPosition(160, 40);
3939
m_object_list.push_back(&c);
4040
m_sprite_layer[1].push_back(&c);
41-
Rectangle r = Rectangle(crate_tex, sf::Vector2f(20.f, 20.f));
41+
Rectangle r = Rectangle(crate_tex, sf::Vector2f(40.f, 400.f));
4242
r.setPosition(90, 240);
4343
m_object_list.push_back(&r);
4444
m_sprite_layer[1].push_back(&r);

src/Object.cpp

Lines changed: 114 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -33,51 +33,135 @@ Rectangle::Rectangle(sf::Texture &tex) {
3333
m_size = object_size;
3434
}
3535

36-
bool Circle::check_collision(Object *obj) const {
36+
bool Circle::checkCollision(Object *obj) const {
3737
if (dynamic_cast<Circle *>(obj)) {
38-
return check_collision(static_cast<Circle *>(obj));
38+
return checkCollision(static_cast<Circle *>(obj));
3939
} else if (dynamic_cast<Rectangle *>(obj)) {
40-
return check_collision(static_cast<Rectangle *>(obj));
40+
return checkCollision(static_cast<Rectangle *>(obj));
41+
} else {
42+
return false;
4143
}
4244
}
4345

44-
bool Rectangle::check_collision(Object *obj) const {
46+
bool Circle::checkCollision(Circle *obj) const {
47+
return len(obj->getPosition() - getPosition()) < (m_radius + obj->m_radius);
48+
}
49+
50+
bool Circle::checkCollision(Rectangle *obj) const {
51+
return (getPosition().x + m_radius >=
52+
obj->getPosition().x - obj->getSize().x / 2 &&
53+
getPosition().x - m_radius <=
54+
obj->getPosition().x + obj->getSize().x / 2 &&
55+
getPosition().y + m_radius >=
56+
obj->getPosition().y - obj->getSize().y / 2 &&
57+
getPosition().y - m_radius <=
58+
obj->getPosition().y + obj->getSize().y / 2);
59+
}
60+
61+
bool Rectangle::checkCollision(Object *obj) const {
4562
if (dynamic_cast<Circle *>(obj)) {
46-
return check_collision(static_cast<Circle *>(obj));
63+
return checkCollision(static_cast<Circle *>(obj));
4764
} else if (dynamic_cast<Rectangle *>(obj)) {
48-
return check_collision(static_cast<Rectangle *>(obj));
49-
} else return false;
65+
return checkCollision(static_cast<Rectangle *>(obj));
66+
} else
67+
return false;
5068
}
5169

52-
bool Circle::check_collision(Circle *obj) const {
53-
return len(obj->getPosition() - getPosition()) < (m_radius + obj->m_radius);
70+
bool Rectangle::checkCollision(Circle *obj) const {
71+
return (getPosition().x + m_size.x >=
72+
obj->getPosition().x - obj->getRadius() / 2 &&
73+
getPosition().x - m_size.x <=
74+
obj->getPosition().x + obj->getRadius() / 2 &&
75+
getPosition().y + m_size.y >=
76+
obj->getPosition().y - obj->getRadius() / 2 &&
77+
getPosition().y - m_size.y <=
78+
obj->getPosition().y + obj->getRadius() / 2);
5479
}
5580

56-
bool Circle::check_collision(Rectangle *obj) const {
57-
return (
58-
getPosition().x + m_radius >= obj->getPosition().x - obj->getSize().x / 2 &&
59-
getPosition().x - m_radius <= obj->getPosition().x + obj->getSize().x / 2 &&
60-
getPosition().y + m_radius >= obj->getPosition().y - obj->getSize().y / 2 &&
61-
getPosition().y - m_radius <= obj->getPosition().y + obj->getSize().y / 2
62-
);
81+
bool Rectangle::checkCollision(Rectangle *obj) const {
82+
return (getPosition().x + m_size.x / 2 >=
83+
obj->getPosition().x - obj->getSize().x / 2 &&
84+
getPosition().x - m_size.x / 2 <=
85+
obj->getPosition().x + obj->getSize().x / 2 &&
86+
getPosition().y + m_size.y / 2 >=
87+
obj->getPosition().y - obj->getSize().y / 2 &&
88+
getPosition().y - m_size.y / 2 <=
89+
obj->getPosition().y + obj->getSize().y / 2);
90+
}
91+
92+
void Circle::snapCollision(Object *obj) {
93+
if (dynamic_cast<Circle *>(obj)) {
94+
snapCollision(static_cast<Circle *>(obj));
95+
} else if (dynamic_cast<Rectangle *>(obj)) {
96+
snapCollision(static_cast<Rectangle *>(obj));
97+
}
6398
}
6499

65-
bool Rectangle::check_collision(Circle *obj) const {
66-
return (
67-
getPosition().x + m_size.x >= obj->getPosition().x - obj->getRadius() / 2 &&
68-
getPosition().x - m_size.x <= obj->getPosition().x + obj->getRadius() / 2 &&
69-
getPosition().y + m_size.y >= obj->getPosition().y - obj->getRadius() / 2 &&
70-
getPosition().y - m_size.y <= obj->getPosition().y + obj->getRadius() / 2
71-
);
100+
void Circle::snapCollision(Circle *obj) {
101+
sf::Vector2f delta = obj->getPosition() - getPosition();
102+
float new_len = m_radius + obj->m_radius;
103+
setPosition(obj->getPosition() - delta * new_len / len(delta));
72104
}
73105

74-
bool Rectangle::check_collision(Rectangle *obj) const {
75-
return (
76-
getPosition().x + m_size.x / 2 >= obj->getPosition().x - obj->getSize().x / 2 &&
77-
getPosition().x - m_size.x / 2 <= obj->getPosition().x + obj->getSize().x / 2 &&
78-
getPosition().y + m_size.y / 2 >= obj->getPosition().y - obj->getSize().y / 2 &&
79-
getPosition().y - m_size.y / 2 <= obj->getPosition().y + obj->getSize().y / 2
80-
);
106+
void Circle::snapCollision(Rectangle *obj) {
107+
sf::Vector2f delta = obj->getPosition() - getPosition();
108+
if (abs(delta.x) / obj->getSize().x < abs(delta.y) / obj->getSize().y) {
109+
if (delta.y < 0) {
110+
return setPosition(
111+
getPosition().x,
112+
obj->getPosition().y + obj->getSize().y / 2 + m_radius + 0.01f);
113+
} else {
114+
return setPosition(
115+
getPosition().x,
116+
obj->getPosition().y - obj->getSize().y / 2 - m_radius - 0.01f);
117+
}
118+
} else {
119+
if (delta.x < 0) {
120+
return setPosition(
121+
obj->getPosition().x + obj->getSize().x / 2 + m_radius + 0.01f,
122+
getPosition().y);
123+
} else {
124+
return setPosition(
125+
obj->getPosition().x - obj->getSize().x / 2 - m_radius - 0.01f,
126+
getPosition().y);
127+
}
128+
}
129+
}
130+
131+
void Rectangle::snapCollision(Object *obj) {
132+
if (dynamic_cast<Circle *>(obj)) {
133+
snapCollision(static_cast<Circle *>(obj));
134+
} else if (dynamic_cast<Rectangle *>(obj)) {
135+
snapCollision(static_cast<Rectangle *>(obj));
136+
}
137+
}
138+
139+
void Rectangle::snapCollision(Circle *obj) {}
140+
141+
void Rectangle::snapCollision(Rectangle *obj) {
142+
sf::Vector2f delta = obj->getPosition() - getPosition();
143+
if (abs(delta.x) / (obj->getSize().x + getSize().x) <
144+
abs(delta.y) / (obj->getSize().y + getSize().y)) {
145+
if (delta.y < 0) {
146+
return setPosition(getPosition().x, obj->getPosition().y +
147+
obj->getSize().y / 2 +
148+
getSize().y / 2 + 0.01f);
149+
} else {
150+
return setPosition(getPosition().x, obj->getPosition().y -
151+
obj->getSize().y / 2 -
152+
getSize().y / 2 - 0.01f);
153+
}
154+
} else {
155+
if (delta.x < 0) {
156+
return setPosition(
157+
obj->getPosition().x + obj->getSize().x / 2 + getSize().x / 2 + 0.01f,
158+
getPosition().y);
159+
} else {
160+
return setPosition(
161+
obj->getPosition().x - obj->getSize().x / 2 - getSize().x / 2 - 0.01f,
162+
getPosition().y);
163+
}
164+
}
81165
}
82166

83167
void Circle::drawCollision(sf::RenderTarget *target) const {

src/Player.cpp

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,29 +22,36 @@ void Player::move(sf::Vector2f velocity, float fr, bool sprint, uint8_t input) {
2222

2323
sf::Sprite::move(m_spd_vec * fr);
2424
checkCollision();
25-
// printf("Framerate: %f", fr);
26-
m_last_pos = getPosition();
25+
m_last_pos = getPosition();
2726
}
2827

2928
void Player::checkCollision() {
3029
if (m_objects_ref != nullptr)
3130
for (int i = 0; i < m_objects_ref->size(); i++) {
32-
if (Circle::check_collision((*m_objects_ref)[i]))
33-
{
31+
if (Circle::checkCollision((*m_objects_ref)[i])) {
3432
if (dynamic_cast<Circle*>((*m_objects_ref)[i])) {
35-
sf::Vector2f m_vec = (*m_objects_ref)[i]->getPosition() - getPosition();
36-
const sf::Vector2f tangent = {m_vec.y, -m_vec.x};
37-
float cos = tangent.x * m_spd_vec.x + tangent.y * m_spd_vec.y / len(m_vec);
38-
39-
sf::Sprite::setPosition(m_last_pos);
40-
m_spd_vec = cos*tangent/len(tangent);
41-
printf("tangent: %f, %f\n", tangent.x, tangent.y);
42-
printf("m_spd_vec: %f, %f\n", m_spd_vec.x, m_spd_vec.y);
33+
const sf::Vector2f delta =
34+
(*m_objects_ref)[i]->getPosition() - getPosition();
35+
const sf::Vector2f tangent = {delta.y, -delta.x};
36+
const float cos =
37+
tangent.x * m_spd_vec.x + tangent.y * m_spd_vec.y / len(delta);
38+
39+
m_spd_vec = cos * tangent / len(tangent) * 0.01f;
40+
snapCollision((*m_objects_ref)[i]);
4341
} else if (dynamic_cast<Rectangle*>((*m_objects_ref)[i])) {
44-
sf::Sprite::setPosition(m_last_pos);
45-
m_spd_vec = sf::Vector2f(0.f, 0.f);
42+
const sf::Vector2f delta =
43+
(*m_objects_ref)[i]->getPosition() - getPosition();
44+
if (abs(delta.x) /
45+
static_cast<Rectangle*>((*m_objects_ref)[i])->getSize().x <
46+
abs(delta.y) /
47+
static_cast<Rectangle*>((*m_objects_ref)[i])->getSize().y) {
48+
m_spd_vec = {0, m_spd_vec.y};
49+
} else {
50+
m_spd_vec = {m_spd_vec.x, 0};
51+
}
52+
snapCollision((*m_objects_ref)[i]);
4653
}
47-
}
54+
}
4855
}
4956
}
5057

0 commit comments

Comments
 (0)