casse-brick
Loading...
Searching...
No Matches
CollisionManager.cpp
Go to the documentation of this file.
1//
2// Created by nicolas elfering on 08.05.24.
3//
4
5#include "CollisionManager.h"
6#include "Ball.h"
7#include "brique.h"
8#include "WALL.h"
9
10std::vector<point> evenlySpacedPointsInRect(float x, float y, float width, float height, int numPoints, float radius) {
11 int maxPossiblePoints = static_cast<int>((width / (2 * radius)) * (height / (2 * radius)));
12
13 int numPointsToCreate = std::min(numPoints, maxPossiblePoints);
14
15 float spacingX = width / std::ceil(std::sqrt(numPointsToCreate));
16 float spacingY = height / std::ceil(static_cast<float>(numPointsToCreate) / std::ceil(std::sqrt(numPointsToCreate)));
17
18 std::vector<point> points;
19 for (int i = 0; i < numPointsToCreate; ++i) {
20 int row = i / static_cast<int>(std::ceil(std::sqrt(numPointsToCreate)));
21 int col = i % static_cast<int>(std::ceil(std::sqrt(numPointsToCreate)));
22 float pointX = x + spacingX * (col + 0.5);
23 float pointY = y + spacingY * (row + 0.5);
24 points.push_back({pointX, pointY});
25 }
26
27 return points;
28}
29
30void CollisionManager::addCollider(const std::shared_ptr<CollidingObject>& collider) {
31 colliders.push_back(collider);
32}
33
34void CollisionManager::removeCollider(const std::shared_ptr<CollidingObject>& collider) {
35 // Use std::remove_if algorithm along with a lambda function to find the collider
36 auto it = std::remove_if(colliders.begin(), colliders.end(), [&collider](const auto& obj) {
37 return obj == collider; // Assuming equality comparison for colliders
38 });
39
40 // Remove the collider from the list
41 colliders.erase(it, colliders.end());
42}
43
45 collisions.clear();
46 std::vector<decltype(colliders.begin())> elementsToErase;
47 int ballsToSpawn = 0;
48 for (auto it1 = colliders.begin(); it1 != colliders.end(); ++it1) {
49 for (auto it2 = std::next(it1); it2 != colliders.end(); ++it2) {
50 auto& collider1 = *it1;
51 auto& collider2 = *it2;
52 auto result = collider1->getCollider()->collided(*collider2->getCollider());
53 if (std::get<0>(result)) {
54 float collisionX = std::get<1>(result);
55 float collisionY = std::get<2>(result);
56
57 auto ball1 = std::dynamic_pointer_cast<Ball>(collider1);
58 auto ball2 = std::dynamic_pointer_cast<Ball>(collider2);
59
60 auto brique1 = std::dynamic_pointer_cast<Brique>(collider1);
61 auto brique2 = std::dynamic_pointer_cast<Brique>(collider2);
62
63 auto rectangle1 = std::dynamic_pointer_cast<Rectangle>(collider1);
64 auto rectangle2 = std::dynamic_pointer_cast<Rectangle>(collider2);
65
66 if(ball1 && ball2){
67 ball1->handleCollision({ball2->getCollider()->p.x,ball2->getCollider()->p.y});
68 ball2->handleCollision({ball1->getCollider()->p.x,ball1->getCollider()->p.y});
69
70 collisions.push_back({collider1->getCollider(), collider2->getCollider(), collisionX, collisionY});
71
72 }else if(ball1 && rectangle2){
73 rectangle2->handleCollisions({collisionX,collisionY});
74 ball1->handleCollisions({collisionX,collisionY});
75 if(rectangle2->collision_counter == 0){
76 elementsToErase.push_back(it2);
77 if(rectangle2->super_power == 1) {
78 ballsToSpawn++;
79 }else if(rectangle2->super_power == 2 && ball1->Velocity<=2){
80 ball1->Velocity *= {2,2};
81 ball1->bounce_number = 5;
82 }
83 }
84
85 collisions.push_back({collider1->getCollider(), collider2->getCollider(), collisionX, collisionY});
86
87 }else if(ball2 && rectangle1){
88 rectangle1->handleCollisions({collisionX,collisionY});
89 ball2->handleCollisions({collisionX,collisionY});
90 if(rectangle1->collision_counter == 0){
91 elementsToErase.push_back(it1);
92 if(rectangle1->super_power == 1) {
93 ballsToSpawn++;
94 }else if(rectangle1->super_power == 2 && ball2->Velocity<=2){
95 ball2->Velocity *= {2,2};
96 ball2->bounce_number = 5;
97 }
98 }
99
100 collisions.push_back({collider1->getCollider(), collider2->getCollider(), collisionX, collisionY});
101
102 }else if(ball1 && brique2){
103 brique2->handleCollisions({collisionX,collisionY});
104 ball1->handleCollision({collisionX,collisionY});
105 if(brique2->collision_counter == 0){
106 elementsToErase.push_back(it2);
107 if(brique2->super_power == 1) {
108 ballsToSpawn++;
109 }else if(brique2->super_power == 2 && ball1->Velocity<=2){
110 ball1->Velocity *= {2,2};
111 ball1->bounce_number = 5;
112 }
113 }
114 collisions.push_back({collider1->getCollider(), collider2->getCollider(), collisionX, collisionY});
115
116 }
117 else if(ball2 && brique1){
118 brique1->handleCollisions({collisionX,collisionY});
119 ball2->handleCollision({collisionX,collisionY});
120 if(brique1->collision_counter == 0){
121 elementsToErase.push_back(it1);
122 if(brique1->super_power == 1) {
123 ballsToSpawn++;
124 }else if(brique1->super_power == 2 && ball2->Velocity<=2){
125 ball2->Velocity *= {2,2};
126 ball2->bounce_number = 5;
127 }
128 }
129
130 collisions.push_back({collider1->getCollider(), collider2->getCollider(), collisionX, collisionY});
131 }
132 else if (ball1) {
133 ball1->handleCollisions({collisionX,collisionY});
134 auto wall = std::dynamic_pointer_cast<WALL>(collider2);
135 if(wall){
136 if(wall->kills){
137 elementsToErase.push_back(it1);
138 numBalls--;
139 }else{
140 collisions.push_back({collider1->getCollider(), collider2->getCollider(), collisionX, collisionY});
141 }
142 }
143 }else if(ball2){
144 ball2->handleCollisions({collisionX,collisionY});
145 auto wall = std::dynamic_pointer_cast<WALL>(collider1);
146 if(wall){
147 if(wall->kills){
148 elementsToErase.push_back(it2);
149 numBalls--;
150 }else{
151 collisions.push_back({collider1->getCollider(), collider2->getCollider(), collisionX, collisionY});
152 }
153 }
154 }
155
156 }
157 }
158 }
159 for (auto it : elementsToErase) {
160 colliders.erase(it);
161 }
162 auto ballsVec = evenlySpacedPointsInRect(200,((600-10)/2),100,50,ballsToSpawn,20);
163 for (auto point: ballsVec) {
164 if(numBalls<=2){
165 Ball ball = Ball(point.x,point.y,10,{255, 0, 0, 255},"circle");
166 std::shared_ptr<Ball> BallPtr = std::make_shared<Ball>(std::move(ball));
167 BallPtr->setVelocity(0.5,1);
168 addCollider(BallPtr);
169 numBalls++;
170 }
171 }
172
173 return numBalls==0;
174}
175
177 for (const auto& collision : collisions) {
178 std::cout << "Collision between "
179 << collision.collider1.lock()->getType()
180 << " and "
181 << collision.collider2.lock()->getType()
182 << " at point (" << collision.collisionX << ", " << collision.collisionY << ")" << std::endl;
183 }
184}
185
186
std::vector< point > evenlySpacedPointsInRect(float x, float y, float width, float height, int numPoints, float radius)
The Ball class represents a ball object in the game.
Definition Ball.h:20
bool detectCollisions()
Detects collisions between collisionObject.
void removeCollider(const std::shared_ptr< CollidingObject > &collider)
Removes a collisionObject from the collision manager.
std::vector< CollisionInfo > collisions
The collection of collision information.
std::vector< std::shared_ptr< CollidingObject > > colliders
The collection of colliding objects.
void addCollider(const std::shared_ptr< CollidingObject > &collider)
Adds a collisionObject to the collision manager.
void printCollisions() const
Prints information about collisions to the console.
int numBalls
The number of balls in the collision manager.
The point struct represents a point in 2D space.
float y
The y-coordinate of the point.
float x
The x-coordinate of the point.