2dx_icon_512_rounded

Cocos2dx-js + Chipmunk – Part 7: Detecting collisions

Hello, after some tutorials about creating static and dynamic physics object, now is time to learn how to detect collisions between these objects.

As always, I assume that you have project created with previous parts of this tutorial.

1. Some code modifications:
First of all, add new array variable:

var physicsObjects = [];

Secondly, add these lines at the end of functions:

physicsObjects.push([phBody, phShape, phNode]);

at the end of function addPhysicsCircle, and

physicsObjects.push([phBody, shape, phNode]);

 

2. Collisions detection stuff:
To detect collisions we need two kind of objects. In Chipmunk, we set the kind of object with setCollisionType function. This function gets collisionType parameter which is just a integer. So to our code we need to add these lines:

var COLLISION_TYPE_STATIC = 1;
var COLLISION_TYPE_DYNAMIC = 2;

And next we have to set proper collision types to the proper objects. Add this line:

shape.setCollisionType(COLLISION_TYPE_STATIC);

to the addStaticObject function, and this line:

shape.setCollisionType(COLLISION_TYPE_DYNAMIC);

to addPhysicsBox and addPhysicsCircle functions.

Next step is to write function which handle collision. So firstly register collision handler function by this line:

space.addCollisionHandler(COLLISION_TYPE_STATIC, COLLISION_TYPE_DYNAMIC, this.collisionStaticDynamic.bind(this), null, null, null);

Place it right after line:

this.rootNode.schedule(update);

And finally add this collision handler function definition:

PhysicsScene.prototype.collisionStaticDynamic = function(arbiter, space) {
	//#1
	for (i = 0; i < arbiter.getBodies().length; i++) {
		//#2
		for (j = 0; j < physicsObjects.length; j++) {
			//#3
			if (arbiter.getBodies()[i].getHandle() == physicsObjects[j][0].getHandle()) {
				//#4
				if (physicsObjects[j][2].getScale() > 1) {
					physicsObjects[j][2].runAction(cc.ScaleTo.create(0.2, 1));
				}
				//#5
				else {
					physicsObjects[j][2].runAction(cc.ScaleTo.create(0.2, 1.5));
				}
			}
		}
	}

	return true;
};

There are some places in the code needing explanation:
#1 – Iterate over arbiter.getBodies() array. Arbiter is an Chipmunk object that handle every body taking part in the collision.
#2 – Iterate over our physics objects array.
#3 – Compare every body’s handle variable. Handle is a variable that is just an unique hash for every body. If hashes are equal, go forward.
#4 – If body’s scale is higher than 1, scale it to 1.
#5 – Else scale it to 1.5

4. Compile and run
Let’s see what happen:

physicsPart6

Sourcehttps://bitbucket.org/galante/chipmunktutorialresources/commits/branch/master