casse-brick latest
Ce projet est réalisé dans le cadre du cours de Programmation Avancée en M1 Informatique de l'université de Strasbourg.
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.