Game Development Reference
The joint is then created using the world's CreateJoint method and stored in the
joint member variable. Because CreateJoint returns a b2Joint pointer, it has
to be cast to a b2PrismaticJoint pointer before assignment.
Notice that it's unnecessary to destroy the joint that the Plunger class is keeping as a
member variable. The joint is automatically destroyed when either body it's attached to
is destroyed, and in this case the BodySprite 's dealloc method destroys the body.
The plunger must also be added to the table. As usual, you do this in the initT-
ableWithWorld method of the TableSetup class after importing the Plun-
ger.h header file. Simply append the following code:
// Add plunger
Plunger *plunger = [Plunger plungerWithWorld:world];
[self addChild:plunger z:-1];
Creating a Universal Contact Listener
To launch the ball automatically on contact, you need some way to react to collisions.
The Box2D physics engine includes the b2ContactListener class. To process
collisions, you have to create a custom class that inherits from b2ContactListen-
er and overrides at least one of the collision callback methods BeginContact ,
EndContact , PreSolve , and PostSolve . You've already created a
Objective-C to collision callbacks.
On the C++ side you commonly end up with code that looks similar to Listing 13-17 .
In principle, you retrieve the two colliding bodies from the b2Contact class. In this
particular case, each body's user data pointer holds a pointer to a BodySprite object,
which lets you compare the classes to decide how to further process the collision. The
verbosity of the code is further increased because a contact's two bodies may be in any
order, even if the same objects collide frequently. That means during any contact, the
plunger might be either bodyA or bodyB , and the ball would be the corresponding
other body. So, you always have to test for both cases.