2 Physical engines are integrated in the Cocos2d-x, one is Chipmunk and the other is box2d. The former is written in C language, with fewer documents and examples. box2d is written in C ++ and has complete documents and materials. Therefore, most developers choose box2d when they need to use a physical engine. Box2d is a simulation engine used to simulate the movements of a rigid body in the physical world. With the box2d physical engine, objects in the world can be moved according to the law of motion.
Note: The classes in box2d are prefixed with B2, so do not conflict with your name.
1. First, we will introduce the basic concepts that need to be used.
World: the world represents a space that follows the laws of physics. All objects are moving in the world. The world has the functions of creating and destroying rigid bodies and joints.
Body: A very hard substance. The distance between any two points on it remains unchanged. The rigid bodies are divided into static rigid bodies, dynamic rigid bodies, and prism rigid bodies (floating rigid bodies)
Shape: a 2D collision ry strictly attached to the body ). The shape is attached to the rigid body by association, so that the rigid body has a visual shape.
Joint (joint): It is a constraint used to fix two or more objects together. Box2d supports the following joint types: rotation, prism, distance, and so on. Joints support limits and motors)
Joint limit: A joint limit (Joint limit) limits the motion range of a joint. For example, the human elbow can only perform a certain range of motion.
Joint motor: A joint horse can drive the connected object according to the degree of freedom of the joint. For example, you can use a motor to drive an elbow rotation.
2. Now we can use box2d to experience the simulated physical world.
(1) first, we need to create a world. To create a world, we need two steps. First, we need to generate a gravity vector and then generate a world based on the gravity vector.
Bool helloworld: Init ()
{
If (! Cclayer: Init ())
{
Return false;
}
// The two parameters of b2vec2 indicate the gravity in the direction of X and Y, and positive and negative indicate the direction.
B2vec2 gravity (0.0f,-10.0f );
// Create a box2d world
World = new b2world (gravity );
// Set the rigid body to sleep (when the rigid body reaches the boundary, stop the calculation of the Rigid Body to save the CPU)
World-> setallowsleeping (true );
// Use continuous physical detection
World-> setcontinuousphysics (true );
// Register the collision detection listener
World-> setcontactlistener (this );
// Create a floating Rigid Body
Addbird (1, 3.33, b2_kinematicbody );
// Create a static Rigid Body
Addgrass (5.0, 0.5, b2_staticbody );
// Set the screen to touch
Settouchenabled (true );
// Initiate thread callback Simulation
This-> scheduleupdate ();
Return true;
}
(2) create a non-static Rigid Body
Void helloworld: addbird (float X, float y, b2bodytype objecttype) {/***** create a rigid body parameter (including location and type) * *** // defines the sprite used by the rigid body * sprite = ccsprite: Create ("bird.png"); addchild (sprite ); // configure the definition of the Rigid Body (similar to stealth, no physical Rigid Body) b2bodydef; def. position = b2vec2 (x, y); // sets the position def. type = objecttype; // The type of the configured rigid body. There are three types: static rigid body, floating rigid body, and dynamic rigid body if (objecttype = b2_kinematicbody) {def. linearvelocity = b2vec2 (2, 0); // two parameters represent the horizontal speed and vertical speed} // define the shape (polygon here) b2polygonshape birdshape; // define the boundary (World boundary). The parameter is half width and half height, because the generated size is twice the size of the input parameter birdshape. setasbox (sprite-> getcontentsize (). width/ratio/2, Sprite-> getcontentsize (). height/ratio/2); // configure the volume of the Rigid Body (material (meat object) b2fixturedef fixturedef; fixturedef. density = 1; // density fixturedef. friction = 0.3; // friction factor fixturedef. restitution = 0.8f; // rebound effect fixturedef. shape = & birdshape; // configure the object of the rigid body/****** construct the shape of the Rigid Body ***** // create the rigid body birdbody = World-> createbody (& def ); // Add the material to the rigid body: birdbody-> createfixture (& fixturedef); // bind the sprite to the rigid body birdbody-> setuserdata (sprite );}
(3) Add a static Rigid Body
Void helloworld: addgrass (float X, float y, b2bodytype objecttype) {/***** create a rigid body parameter (including location and type) * *** // defines the sprite ccsprite * sprite = ccsprite: Create ("grass.png"); addchild (sprite, 1) used by the rigid body ); // configure the definition of the Rigid Body (similar to stealth, no physical Rigid Body) b2bodydef; def. position = b2vec2 (x, y); // sets the position def. type = objecttype; // configure the type of the rigid body. There are three types: static rigid body, floating rigid body, and dynamic rigid body. // define the shape (polygon here) b2polygonshape grassshape; // define the border (World border). The parameter is half width and half height, because the generated size is twice the size of the input parameter grassshape. setasbox (sprite-> getcontentsize (). width/ratio/2, Sprite-> getcontentsize (). height/ratio/2); // configure the volume of the Rigid Body (material (meat object) b2fixturedef fixturedef; fixturedef. density = 1; fixturedef. friction = 0.3; fixturedef. shape = & grassshape; // configure the object of the rigid body/****** construct the shape of the Rigid Body ***** // create the rigid body grassbody = World-> createbody (& def ); // Add the material to the rigid body grassbody-> createfixture (& fixturedef); // bind the sprite to the rigid body grassbody-> setuserdata (sprite );}
(4) driving the simulated world
// The world class is used to drive the simulation of void helloworld: Update (float a) {float32 timestep = 1.0f/60.f; // The first parameter of the step () function is the number of time steps, the following two parameters are respectively the speed stage and location stage world-> step (timestep, 8, 3); ccsprite * s; For (b2body * B = World-> getbodylist (); b; B = B-> getnext () {If (B-> getuserdata ()! = NULL) {S = (ccsprite *) B-> getuserdata ();
// Floating motion simulation S-> setposition (CCP (B-> getposition (). x * ratio, B-> getposition (). y * Ratio); If (S-> getposition (). x <-10 | S-> getposition (). x> 490 | S-> getposition (). Y <-10) {This-> removechild (s); World-> destroybody (B );}}}}
(5) You can touch the screen to add a rigid body to the touch screen.
void HelloWorld::registerWithTouchDispatcher(void){ CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 1, false);}
bool HelloWorld::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent){ CCPoint p = pTouch->getLocation(); addBird(p.x / RATIO, p.y / RATIO, b2_dynamicBody); return true;}
(6) Let the helloworld class inherit b2contactlistener and rewrite the begincontact function to implement rigid body collision detection.
// Collision detection void helloworld: begincontact (b2contact * contact) {If (contact-> getfixturea ()-> getbody () = grassbody | contact-> getfixtureb () -> getbody () = grassbody) {cclog ("A bird lands on the lawn! ") ;}Else {cclog (" collision between birds ");}}
Effect:
Box2d physical engine in cocos2d-x