Quelques optimisations
This commit is contained in:
parent
405456d2b1
commit
578d950ec7
|
@ -14,6 +14,7 @@ private:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
mutable sf::Sprite sprite;
|
mutable sf::Sprite sprite;
|
||||||
|
sf::FloatRect aabb;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialisation des propriétés du bloc donné
|
* Initialisation des propriétés du bloc donné
|
||||||
|
|
|
@ -6,7 +6,15 @@
|
||||||
|
|
||||||
const unsigned int Block::TYPE_ID = 2;
|
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() {}
|
Block::~Block() {}
|
||||||
|
|
||||||
Object::Ptr Block::clone() const {
|
Object::Ptr Block::clone() const {
|
||||||
|
@ -77,11 +85,11 @@ void Block::kill(Game& game) {
|
||||||
}
|
}
|
||||||
|
|
||||||
sf::FloatRect Block::getAABB() const {
|
sf::FloatRect Block::getAABB() const {
|
||||||
return sf::FloatRect(
|
sf::FloatRect transl_aabb = aabb;
|
||||||
getPosition().x - Constants::GRID / 2,
|
transl_aabb.left += getPosition().x;
|
||||||
getPosition().y - Constants::GRID / 2,
|
transl_aabb.top += getPosition().y;
|
||||||
Constants::GRID, Constants::GRID
|
|
||||||
);
|
return transl_aabb;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Block::getRadius() const {
|
float Block::getRadius() const {
|
||||||
|
|
|
@ -180,24 +180,22 @@ bool AABBToAABB(CollisionData& data) {
|
||||||
return true;
|
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() {}
|
CollisionData::CollisionData() {}
|
||||||
bool getCollisionData(CollisionData& data) {
|
bool getCollisionData(CollisionData& data) {
|
||||||
return collision_map[std::make_pair(
|
CollisionType type_a = data.obj_a->getCollisionType();
|
||||||
data.obj_a->getCollisionType(),
|
CollisionType type_b = data.obj_b->getCollisionType();
|
||||||
data.obj_b->getCollisionType()
|
|
||||||
)](data);
|
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();
|
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
|
// détection des objets en collision
|
||||||
for (unsigned int i = 0; i < objects.size(); i++) {
|
for (auto it = objects.begin(); it != objects.end(); it++) {
|
||||||
Object::Ptr obj_a = objects[i];
|
Object::Ptr obj_a = *it;
|
||||||
|
|
||||||
for (unsigned int j = i + 1; j < objects.size(); j++) {
|
// l'objet est sorti de la zone, on le signale et on
|
||||||
Object::Ptr obj_b = objects[j];
|
// 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;
|
CollisionData data;
|
||||||
|
|
||||||
data.obj_a = obj_a;
|
data.obj_a = obj_a;
|
||||||
|
@ -154,28 +153,24 @@ void Game::update() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// intégration des forces dans la vitesse (seconde moitié)
|
// intégration des forces dans la vitesse
|
||||||
for (unsigned int i = 0; i < objects.size(); i++) {
|
for (auto it = objects.begin(); it != objects.end(); it++) {
|
||||||
objects[i]->updateVelocity(*this);
|
(*it)->updateVelocity(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// résolution des collisions détectées
|
// résolution des collisions détectées
|
||||||
for (unsigned int i = 0; i < colliding.size(); i++) {
|
for (auto it = colliding.begin(); it != colliding.end(); it++) {
|
||||||
CollisionData& collided = colliding[i];
|
it->obj_a->solveCollision(*this, it->obj_b, it->normal);
|
||||||
collided.obj_a->solveCollision(*this, collided.obj_b, collided.normal);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// intégration de la vitesse dans la position
|
// intégration de la vitesse dans la position
|
||||||
for (unsigned int i = 0; i < objects.size(); i++) {
|
for (auto it = objects.begin(); it != objects.end(); it++) {
|
||||||
objects[i]->updatePosition();
|
(*it)->updatePosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
// application de la correction positionnelle
|
// application de la correction positionnelle
|
||||||
for (unsigned int i = 0; i < colliding.size(); i++) {
|
for (auto it = colliding.begin(); it != colliding.end(); it++) {
|
||||||
CollisionData& collided = colliding[i];
|
it->obj_a->positionalCorrection(it->obj_b, it->normal, it->depth);
|
||||||
collided.obj_a->positionalCorrection(
|
|
||||||
collided.obj_b, collided.normal, collided.depth
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -204,6 +204,14 @@ bool Object::detectCollision(Object::Ptr obj, CollisionData& data) const {
|
||||||
return false;
|
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
|
// si les deux boîtes englobantes des deux objets ne
|
||||||
// s'intersectent pas, il ne risque pas d'y avoir de collision
|
// s'intersectent pas, il ne risque pas d'y avoir de collision
|
||||||
if (!getAABB().intersects(obj->getAABB())) {
|
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;
|
dot_normal = rel_velo.x * normal.x + rel_velo.y * normal.y;
|
||||||
|
|
||||||
sf::Vector2f tangent = rel_velo - dot_normal * normal;
|
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
|
// la tangente est nulle : pas de frottement à générer
|
||||||
// on évite ainsi une division par zéro
|
// 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
tangent /= tangent_length;
|
tangent /= std::sqrt(tangent_length);
|
||||||
|
|
||||||
float magnitude = -(rel_velo.x * tangent.x + rel_velo.y * tangent.y) /
|
float magnitude = -(rel_velo.x * tangent.x + rel_velo.y * tangent.y) /
|
||||||
(getMassInvert() + obj->getMassInvert());
|
(getMassInvert() + obj->getMassInvert());
|
||||||
|
|
Loading…
Reference in New Issue