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);
|
||||
}
|
||||
|
|
43
src/game.cpp
43
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
|
||||
// détection des objets en collision
|
||||
for (auto it = objects.begin(); it != objects.end(); it++) {
|
||||
if (!isInZone(*it) && (*it)->getMass() != 0) {
|
||||
Object::Ptr obj_a = *it;
|
||||
|
||||
// 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);
|
||||
}
|
||||
if (!isInZone(obj_a) && obj_a->getMass() != 0) {
|
||||
obj_a->kill(*this);
|
||||
pending_kill.push_back(obj_a);
|
||||
}
|
||||
|
||||
// détection des objets en collision
|
||||
for (unsigned int i = 0; i < objects.size(); i++) {
|
||||
Object::Ptr obj_a = objects[i];
|
||||
|
||||
for (unsigned int j = i + 1; j < objects.size(); j++) {
|
||||
Object::Ptr obj_b = objects[j];
|
||||
// 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())) {
|
||||
|
@ -254,7 +262,7 @@ void Object::solveCollision(Level& level, Object::Ptr obj, const sf::Vector2f& n
|
|||
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