11 int maxPossiblePoints =
static_cast<int>((width / (2 * radius)) * (height / (2 * radius)));
13 int numPointsToCreate = std::min(numPoints, maxPossiblePoints);
15 float spacingX = width / std::ceil(std::sqrt(numPointsToCreate));
16 float spacingY = height / std::ceil(
static_cast<float>(numPointsToCreate) / std::ceil(std::sqrt(numPointsToCreate)));
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});
36 auto it = std::remove_if(
colliders.begin(),
colliders.end(), [&collider](
const auto& obj) {
37 return obj == collider;
46 std::vector<
decltype(
colliders.begin())> elementsToErase;
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);
57 auto ball1 = std::dynamic_pointer_cast<Ball>(collider1);
58 auto ball2 = std::dynamic_pointer_cast<Ball>(collider2);
60 auto brique1 = std::dynamic_pointer_cast<Brique>(collider1);
61 auto brique2 = std::dynamic_pointer_cast<Brique>(collider2);
63 auto rectangle1 = std::dynamic_pointer_cast<Rectangle>(collider1);
64 auto rectangle2 = std::dynamic_pointer_cast<Rectangle>(collider2);
67 ball1->handleCollision({ball2->getCollider()->p.x,ball2->getCollider()->p.y});
68 ball2->handleCollision({ball1->getCollider()->p.x,ball1->getCollider()->p.y});
70 collisions.push_back({collider1->getCollider(), collider2->getCollider(), collisionX, collisionY});
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) {
79 }
else if(rectangle2->super_power == 2 && ball1->Velocity<=2){
80 ball1->Velocity *= {2,2};
81 ball1->bounce_number = 5;
85 collisions.push_back({collider1->getCollider(), collider2->getCollider(), collisionX, collisionY});
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) {
94 }
else if(rectangle1->super_power == 2 && ball2->Velocity<=2){
95 ball2->Velocity *= {2,2};
96 ball2->bounce_number = 5;
100 collisions.push_back({collider1->getCollider(), collider2->getCollider(), collisionX, collisionY});
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) {
109 }
else if(brique2->super_power == 2 && ball1->Velocity<=2){
110 ball1->Velocity *= {2,2};
111 ball1->bounce_number = 5;
114 collisions.push_back({collider1->getCollider(), collider2->getCollider(), collisionX, collisionY});
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) {
124 }
else if(brique1->super_power == 2 && ball2->Velocity<=2){
125 ball2->Velocity *= {2,2};
126 ball2->bounce_number = 5;
130 collisions.push_back({collider1->getCollider(), collider2->getCollider(), collisionX, collisionY});
133 ball1->handleCollisions({collisionX,collisionY});
134 auto wall = std::dynamic_pointer_cast<WALL>(collider2);
137 elementsToErase.push_back(it1);
140 collisions.push_back({collider1->getCollider(), collider2->getCollider(), collisionX, collisionY});
144 ball2->handleCollisions({collisionX,collisionY});
145 auto wall = std::dynamic_pointer_cast<WALL>(collider1);
148 elementsToErase.push_back(it2);
151 collisions.push_back({collider1->getCollider(), collider2->getCollider(), collisionX, collisionY});
159 for (
auto it : elementsToErase) {
163 for (
auto point: ballsVec) {
166 std::shared_ptr<Ball> BallPtr = std::make_shared<Ball>(std::move(ball));
167 BallPtr->setVelocity(0.5,1);
178 std::cout <<
"Collision between "
179 << collision.collider1.lock()->getType()
181 << collision.collider2.lock()->getType()
182 <<
" at point (" << collision.collisionX <<
", " << collision.collisionY <<
")" << std::endl;
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.
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.