Quelques optimisations
This commit is contained in:
		
							parent
							
								
									405456d2b1
								
							
						
					
					
						commit
						578d950ec7
					
				|  | @ -14,6 +14,7 @@ private: | |||
| 
 | ||||
| protected: | ||||
|     mutable sf::Sprite sprite; | ||||
|     sf::FloatRect aabb; | ||||
| 
 | ||||
|     /**
 | ||||
|      * Initialisation des propriétés du bloc donné | ||||
|  |  | |||
|  | @ -6,7 +6,15 @@ | |||
| 
 | ||||
| const unsigned int Block::TYPE_ID = 2; | ||||
| 
 | ||||
| Block::Block() : Object() {} | ||||
| Block::Block() : Object() { | ||||
|     aabb = sf::FloatRect( | ||||
|         -Constants::GRID / 2, | ||||
|         -Constants::GRID / 2, | ||||
|         Constants::GRID, | ||||
|         Constants::GRID | ||||
|     ); | ||||
| } | ||||
| 
 | ||||
| Block::~Block() {} | ||||
| 
 | ||||
| Object::Ptr Block::clone() const { | ||||
|  | @ -77,11 +85,11 @@ void Block::kill(Game& game) { | |||
| } | ||||
| 
 | ||||
| sf::FloatRect Block::getAABB() const { | ||||
|     return sf::FloatRect( | ||||
|         getPosition().x - Constants::GRID / 2, | ||||
|         getPosition().y - Constants::GRID / 2, | ||||
|         Constants::GRID, Constants::GRID | ||||
|     ); | ||||
|     sf::FloatRect transl_aabb = aabb; | ||||
|     transl_aabb.left += getPosition().x; | ||||
|     transl_aabb.top += getPosition().y; | ||||
| 
 | ||||
|     return transl_aabb; | ||||
| } | ||||
| 
 | ||||
| float Block::getRadius() const { | ||||
|  |  | |||
|  | @ -180,24 +180,22 @@ bool AABBToAABB(CollisionData& data) { | |||
|     return true; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * Dictionnaire associant les types impliqués | ||||
|  * dans une collision à leur fonction de résolution | ||||
|  */ | ||||
| std::map< | ||||
|     std::pair<CollisionType, CollisionType>, | ||||
|     std::function<bool(CollisionData&)> | ||||
| > collision_map = { | ||||
|     {std::make_pair(CollisionType::CIRCLE, CollisionType::CIRCLE), circleToCircle}, | ||||
|     {std::make_pair(CollisionType::CIRCLE, CollisionType::AABB), circleToAABB}, | ||||
|     {std::make_pair(CollisionType::AABB, CollisionType::AABB), AABBToAABB}, | ||||
|     {std::make_pair(CollisionType::AABB, CollisionType::CIRCLE), AABBToCircle} | ||||
| }; | ||||
| 
 | ||||
| CollisionData::CollisionData() {} | ||||
| bool getCollisionData(CollisionData& data) { | ||||
|     return collision_map[std::make_pair( | ||||
|         data.obj_a->getCollisionType(), | ||||
|         data.obj_b->getCollisionType() | ||||
|     )](data); | ||||
|     CollisionType type_a = data.obj_a->getCollisionType(); | ||||
|     CollisionType type_b = data.obj_b->getCollisionType(); | ||||
| 
 | ||||
|     if (type_a == CollisionType::CIRCLE && type_b == CollisionType::CIRCLE) { | ||||
|         return circleToCircle(data); | ||||
|     } | ||||
| 
 | ||||
|     if (type_a == CollisionType::CIRCLE && type_b == CollisionType::AABB) { | ||||
|         return circleToAABB(data); | ||||
|     } | ||||
| 
 | ||||
|     if (type_a == CollisionType::AABB && type_b == CollisionType::CIRCLE) { | ||||
|         return AABBToCircle(data); | ||||
|     } | ||||
| 
 | ||||
|     return AABBToAABB(data); | ||||
| } | ||||
|  |  | |||
							
								
								
									
										49
									
								
								src/game.cpp
								
								
								
								
							
							
						
						
									
										49
									
								
								src/game.cpp
								
								
								
								
							|  | @ -127,22 +127,21 @@ void Game::update() { | |||
| 
 | ||||
|     pending_kill.empty(); | ||||
| 
 | ||||
|     // détection des objets déplaçables en dehors de la zone de jeu
 | ||||
|     for (auto it = objects.begin(); it != objects.end(); it++) { | ||||
|         if (!isInZone(*it) && (*it)->getMass() != 0) { | ||||
|             // l'objet est sorti de la zone, on le signale et on
 | ||||
|             // planifie sa mort à la prochaine frame
 | ||||
|             (*it)->kill(*this); | ||||
|             pending_kill.push_back(*it); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // détection des objets en collision
 | ||||
|     for (unsigned int i = 0; i < objects.size(); i++) { | ||||
|         Object::Ptr obj_a = objects[i]; | ||||
|     for (auto it = objects.begin(); it != objects.end(); it++) { | ||||
|         Object::Ptr obj_a = *it; | ||||
| 
 | ||||
|         for (unsigned int j = i + 1; j < objects.size(); j++) { | ||||
|             Object::Ptr obj_b = objects[j]; | ||||
|         // l'objet est sorti de la zone, on le signale et on
 | ||||
|         // planifie sa mort à la prochaine frame
 | ||||
|         if (!isInZone(obj_a) && obj_a->getMass() != 0) { | ||||
|             obj_a->kill(*this); | ||||
|             pending_kill.push_back(obj_a); | ||||
|         } | ||||
| 
 | ||||
|         // on regarde s'il est en collision avec
 | ||||
|         // d'autres objets
 | ||||
|         for (auto jt = it + 1; jt != objects.end(); jt++) { | ||||
|             Object::Ptr obj_b = *jt; | ||||
|             CollisionData data; | ||||
| 
 | ||||
|             data.obj_a = obj_a; | ||||
|  | @ -154,28 +153,24 @@ void Game::update() { | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // intégration des forces dans la vitesse (seconde moitié)
 | ||||
|     for (unsigned int i = 0; i < objects.size(); i++) { | ||||
|         objects[i]->updateVelocity(*this); | ||||
|     // intégration des forces dans la vitesse
 | ||||
|     for (auto it = objects.begin(); it != objects.end(); it++) { | ||||
|         (*it)->updateVelocity(*this); | ||||
|     } | ||||
| 
 | ||||
|     // résolution des collisions détectées
 | ||||
|     for (unsigned int i = 0; i < colliding.size(); i++) { | ||||
|         CollisionData& collided = colliding[i]; | ||||
|         collided.obj_a->solveCollision(*this, collided.obj_b, collided.normal); | ||||
|     for (auto it = colliding.begin(); it != colliding.end(); it++) { | ||||
|         it->obj_a->solveCollision(*this, it->obj_b, it->normal); | ||||
|     } | ||||
| 
 | ||||
|     // intégration de la vitesse dans la position
 | ||||
|     for (unsigned int i = 0; i < objects.size(); i++) { | ||||
|         objects[i]->updatePosition(); | ||||
|     for (auto it = objects.begin(); it != objects.end(); it++) { | ||||
|         (*it)->updatePosition(); | ||||
|     } | ||||
| 
 | ||||
|     // application de la correction positionnelle
 | ||||
|     for (unsigned int i = 0; i < colliding.size(); i++) { | ||||
|         CollisionData& collided = colliding[i]; | ||||
|         collided.obj_a->positionalCorrection( | ||||
|             collided.obj_b, collided.normal, collided.depth | ||||
|         ); | ||||
|     for (auto it = colliding.begin(); it != colliding.end(); it++) { | ||||
|         it->obj_a->positionalCorrection(it->obj_b, it->normal, it->depth); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -204,6 +204,14 @@ bool Object::detectCollision(Object::Ptr obj, CollisionData& data) const { | |||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     // si on a affaire à deux objets de masse infinie et
 | ||||
|     // de vitesse nulle, pas de collision
 | ||||
|     if (getMassInvert() == 0 && obj->getMassInvert() == 0 && | ||||
|         getVelocity().x == 0 && getVelocity().y == 0 && | ||||
|         obj->getVelocity().x == 0 && obj->getVelocity().y == 0) { | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     // si les deux boîtes englobantes des deux objets ne
 | ||||
|     // s'intersectent pas, il ne risque pas d'y avoir de collision
 | ||||
|     if (!getAABB().intersects(obj->getAABB())) { | ||||
|  | @ -252,9 +260,9 @@ void Object::solveCollision(Level& level, Object::Ptr obj, const sf::Vector2f& n | |||
|     // les coefficients de friction utilisés sont les moyennes de ceux des deux objets
 | ||||
|     rel_velo = obj->getVelocity() - getVelocity(); | ||||
|     dot_normal = rel_velo.x * normal.x + rel_velo.y * normal.y; | ||||
|      | ||||
| 
 | ||||
|     sf::Vector2f tangent = rel_velo - dot_normal * normal; | ||||
|     float tangent_length = std::sqrt(tangent.x * tangent.x + tangent.y * tangent.y); | ||||
|     float tangent_length = tangent.x * tangent.x + tangent.y * tangent.y; | ||||
| 
 | ||||
|     // la tangente est nulle : pas de frottement à générer
 | ||||
|     // on évite ainsi une division par zéro
 | ||||
|  | @ -262,7 +270,7 @@ void Object::solveCollision(Level& level, Object::Ptr obj, const sf::Vector2f& n | |||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     tangent /= tangent_length; | ||||
|     tangent /= std::sqrt(tangent_length); | ||||
| 
 | ||||
|     float magnitude = -(rel_velo.x * tangent.x + rel_velo.y * tangent.y) / | ||||
|         (getMassInvert() + obj->getMassInvert()); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue