Handle Collisions

Learn how to configure, capture and respond to collisions

Create Collision Rules

By default, the Engine uses a collision strategy called Full Collision in which every object collide which each other. If you want to create your own collisions configuration you have to create a nero::CollisionRule object, setup the rules that specify which object can collide with which one, then apply the rules to the Game World. The method canCollide(std::string categoryA, std::string categoryB), takes two object categories (Learn about categories here).

//create a collision rule object
nero::CollisionRule collisionRule;

//add the rules
collisionRule.canCollide(CategoryPool.player, CategoryPool.ground);
collisionRule.canCollide(CategoryPool.player, CategoryPool.wall);
collisionRule.canCollide(CategoryPool.player, CategoryPool.platform);
collisionRule.canCollide(CategoryPool.player, CategoryPool.box);
collisionRule.canCollide(CategoryPool.player, CategoryPool.coin);
collisionRule.canCollide(CategoryPool.player, CategoryPool.key);
collisionRule.canCollide(CategoryPool.player, CategoryPool.star);

//apply the rules
collisionRule.apply(getWorld());

You can remove all collisions in your Scene by calling the method noCollision on the Game World.

nero::CollisionRule collisionRule;
collisionRule.noCollision(getWorld());

You can restore the default collision strategy by calling the method fullCollision on the Game World.

nero::CollisionRule collisionRule;
collisionRule.fullCollision(getWorld());

Handle Methods

Collisions can be caught at four (4) moments. The two mains moments are when a collision begins and when it ends. During the collision phase, while the Engine is trying to resolve the collision (compute how to respond to it), you have the possibility to handle the collision before and after the collision resolution. Those four (4) moments are represented by four functions Contact Begin, Contact End, Pre Solve Contact and Post Solve Contact.

  • Respond to collisions when a contact begins
void MyScene::handleCollisionContactBegin(Collision collision)
{
    //handle collision
}
  • Respond to collisions when a contact ends
void MyScene::handleCollisionContactEnd(Collision collision)
{
    //handle collision
}
  • Respond to collisions while the objects are touching (overlapping) but before the Engine computes the resulted forces
void MyScene::handleCollisionPreSolveContact(Collision collision)
{
    //handle collision
}
  • Respond to collisions while the objects are touching (overlapping) but after the Engine computes the resulted forces
void MyScene::handleCollisionPostSolveContact(Collision collision)
{
    //handle collision
}

The Collision Object

As you can see, all four methods to respond to collision has a parameter  collision of type nero::Collision. The nero::Collision object contains all the information on the collision that just occurred.

  • Retrieve the two objects colliding : You can retrieve the two object colliding with the following methods
void MyScene::handleCollisionContactBegin(Collision collision)
{
    PhysicObject::Ptr	objectA = collision.getObjectA();
PhysicObject::Ptr   objectB = collision.getObjectB();
}
  • Check collision using Object Category : Using the method isColliding you can check if one or two objects are colliding based their categories. If there is a collision, you can retrieve the colliding objects with the method getObject(std::string indicator).
void MyScene::handleCollisionContactBegin(Collision collision)
{
	//check if two objects are colliding
    if(collision.isColliding("category_1", "category_2"))
    {
    	auto object_1 = collision.getObject("category_1");
    	auto object_2 = collision.getObject("category_2");

    	//do something
    }

    //check if one object is colliding
    if(collision.isColliding("category_1")
    {
    	auto object_1 = collision.getObject("category_1"));

    	//do something
    }
}
  • Check collision using Object Name : Using the method isObjectColliding you can check if one or two objects are colliding based their names. If there is a collision, you can retrieve the colliding objects with the method getObject(std::string indicator).
void MyScene::handleCollisionContactBegin(Collision collision)
{
	//check if two objects are colliding
    if(collision.isObjectColliding("name_1", "name_2"))
    {
    	auto object_1 = collision.getObject("name_1");
    	auto object_2 = collision.getObject("name_2");

    	//do something
    }

    //check if one object is colliding
    if(collision.isObjectColliding("name_1"))
    {
    	auto object_1 = collision.getObject("name_1");

    	//do something
    }
}
  • Disabling a collision

The image below, shows the entire process during a Collision. First the method Contact Begin is called, then the two methods Pre Solve and Post Solve are called repeatedly during the overlapping phase and finally the method Contact End is called.

You can stop that process by disable the Collision. If you disable the Collision in Contact Begin for example the Engine will stop processing the Collision and the methods Pre Solve, Post Solve and Contact End will not be called.

void MyScene::handleCollisionContactBegin(Collision collision)
{
	collision.setEnabled(false);
}
  • Retrieve Contact information : The collision object provides many information on the contact, here is a list of methods to retrieve those information
//Contact
float                       getFriction();
float                       getRestition();
float                       getTangentSpeed();

bool                        isEnabled();
bool                        isTouching();

//Contact Manifold
sf::Vector2f                getLocalNormal();
sf::Vector2f                getLocalPoint();
int                         getPointCount();
float                       getNormalImpulse(int index);
float                       getTangentImpulse(int index);

//Contact world Manifold
sf::Vector2f                getNormal();
std::vector   getPoints();
std::vector          getSeparations();

//Old Manifold
sf::Vector2f                getOldLocalNormal();
sf::Vector2f                getOldLocalPoint();
int                         getOldPointCount();
float                       getOldNormalImpulse(int index);
float                       getOldTangentImpulse(int index);

//Contact Impulse : PostSolve
int                         getImpulseCount();
std::vector          getNormalImpulses();
std::vector          getTangentImpulses();
  • Modify the collision : You can also use the collision object to modify or adjust certain properties of the collision while it is ongoing
void                        resetFriction();
void                        resetRestitution();

void                        setFriction(float friction);
void                        setRestitution(float restitution);
void                        setTangentSpeed(float speed);

You have successfully subscribed to the newsletter

There was an error while trying to send your request. Please try again.

Nero Games will use the information you provide on this form to be in touch with you and to provide updates and marketing.