Cocos2d-x Study Notes (20) -- box2d getting started

Source: Internet
Author: User

Cocos2d-x Study Notes (20) -- box2d getting started
Before reading this article, you 'd better read the self-taught notes of the box2d physical engine I wrote. 1. Make some preparations to better understand the code.
Step 1: Create a coco2d-win32 project, remember to hook up the Box2D option at creation, named box2d;
Step 2: Add the following classes in HelloWorldScene. h:
[Plain]
Class Box2DTest: public CCLayer
{
Protected:
B2World * m_world;
 
Public:
Box2DTest ();
~ Box2DTest ();
 
Void addSprite (CCPoint point );
Void update (ccTime dt );
};
Step 3: Add the following code to HelloWorldScene. cpp:
Const int tagSprite = 1;
# Define PTM_RATIO 32
[Plain]
/*************************************** *********************************/
/* Box2DTest */
/*************************************** *********************************/
Box2DTest: Box2DTest ()
{
SetIsTouchEnabled (true );
SetIsAccelerometerEnabled (true); // sets acceleration.
 
CCSize size = CCDirector: shareddire()-> getWinSize ();
 
B2Vec2 gravity (0.0f,-10.0f );
Bool doSleep = true;
 
M_world = new b2World (gravity );
M_world-> SetAllowSleeping (doSleep );
M_world-> SetContinuousPhysics (true );
 
// Define a surface object
B2BodyDef groundBodyDef;

B2Body * groundBody = m_world-> CreateBody (& groundBodyDef );
B2PolygonShape groundBox;
 
// Bottom wall
GroundBox. SetAsBox (size. width/PTM_RATIO, 0, b2Vec2 (0, 0), 0 );
GroundBody-> CreateFixture (& groundBox, 0 );
 
// Wall
GroundBox. SetAsBox (size. width/PTM_RATIO, 0, b2Vec2 (0, size. height/PTM_RATIO), 0 );
GroundBody-> CreateFixture (& groundBox, 0 );
 
// Left Wall
GroundBox. SetAsBox (0, size. height/PTM_RATIO, b2Vec2 (0, 0), 0 );
GroundBody-> CreateFixture (& groundBox, 0 );
 
// Right wall
GroundBox. SetAsBox (0, size. height/PTM_RATIO, b2Vec2 (size. width/PTM_RATIO, 0), 0 );
GroundBody-> CreateFixture (& groundBox, 0 );
 
CCSpriteBatchNode * brick = CCSpriteBatchNode: batchNodeWithFile ("brick.png ");
AddChild (brick, 2, tagSprite );
 
AddSprite (ccp (size. width/2, size. height/2 ));
 
ScheduleUpdate ();
}
[Plain]
Box2DTest ::~ Box2DTest ()
{
Delete m_world;
M_world = NULL;
}

First, create a world object and set the gravity field.
The next step is to add a surface object to a world object. The earth object is a hollow quadrilateral, which is equivalent to four walls. Because the earth object is a static object, groundBody-> CreateFixture () the second parameter is set to 0;
Call the scheduleUpdate () function in the constructor to simulate time updates and implement updates in update.
In box2d, you can call step to update the screen.
[Plain]
Void Box2DTest: addSprite (CCPoint point)
{
CCSpriteBatchNode * batch = (CCSpriteBatchNode *) getChildByTag (tagSprite );
 
CCSprite * sprite = CCSprite: spriteWithTexture (batch-> getTexture (), CCRectMake (, 32 ));
Batch-> addChild (sprite );
 
Sprite-> setPosition (ccp (point. x, point. y ));
 
// Create a dynamic object
B2BodyDef bodyDef;
BodyDef. type = b2_dynamicBody;
BodyDef. position. Set (point. x/PTM_RATIO, point. y/PTM_RATIO );
BodyDef. userData = sprite;
B2Body * body = m_world-> CreateBody (& bodyDef );
 
B2PolygonShape dynamicBox;
DynamicBox. SetAsBox (0.5f, 0.5f );
 
B2FixtureDef fixtureDef;
FixtureDef. shape = & dynamicBox;
FixtureDef. friction = 0.3f;
FixtureDef. density = 1.0;
Body-> CreateFixture (& fixtureDef );
 
}
Here we will talk about the unit in box2d, because box2d uses meters as the unit of length. However, in programming, we use pixels as the basic unit.
To this end, I have summarized the principle that all objects to be added to the world need to be converted into meters in pixel units. To display objects in the world on the screen, convert the object's meter unit to pixel unit.
[Plain]
B2BodyDef bodyDef;
BodyDef. type = b2_dynamicBody;
BodyDef. position. Set (point. x/PTM_RATIO, point. y/PTM_RATIO );
BodyDef. userData = sprite;
[Plain] view plaincopy
// Bind the sprite genie to the object
[Plain]
B2Body * body = m_world-> CreateBody (& bodyDef );

Here, because we need to add a dynamic object to the world object, all objects that enter the world need to be converted into meters according to the principle I have mentioned, here I use a 32 pixel value of 1 meter (see the PTM_RATIO definition ).
[Plain]
B2PolygonShape dynamicBox;
DynamicBox. SetAsBox (0.5f, 0.5f );
In addition, because SetAsBox is set to the actual distance, the actual length and width are 1 m and 1 m, which is equivalent to 32 pixel length and 32 pixel width, it is exactly the size of the image I used.

[Plain]
For (b2Body * B = m_world-> GetBodyList (); B = B-> GetNext ())
{
If (B-> GetUserData ()! = NULL)
{
CCSprite * sprite = (CCSprite *) B-> GetUserData ();
Sprite-> setPosition (ccp (B-> GetPosition (). x * PTM_RATIO, B-> GetPosition (). y * PTM_RATIO ));
}
}
This code first facilitates all object objects in the world, and then displays the object on the screen. Note: because we are displaying objects in the world object on the screen, we need to convert the meter unit to the pixel unit.
[Plain]
Void Box2DTest: update (ccTime dt)
{
 
Int velocityIterations = 8;
Int positionIterations = 1;
 
// You should call b2World: Step every game loop
M_world-> Step (dt, velocityIterations, positionIterations );
 

For (b2Body * B = m_world-> GetBodyList (); B = B-> GetNext ())
{
If (B-> GetUserData ()! = NULL)
{
CCSprite * sprite = (CCSprite *) B-> GetUserData ();
Sprite-> setPosition (ccp (B-> GetPosition (). x * PTM_RATIO, B-> GetPosition (). y * PTM_RATIO ));
}
}
}
Here, update is the content updated per frame, which is automatically called by the program. The first parameter of the step function is the time step, also called the Integrator. The official documents are as follows:
Box2D uses a numerical algorithm called integrator. The Integrator simulates continuous physical equations at discrete time points. It runs together with traditional game animation loops. We need to select a time step for Box2D. Generally, the physical engine used for the game requires a speed of at least 60Hz, that is, 1/60 of the time step. You can use a larger time step, but you must be more careful with the definition of your world. We do not like the time step changes too much, so do not associate the time step with the frame rate (unless you really have to do so ).
The second parameter is speed iteration. You can adjust the motion of an object. The third parameter is location iteration. You can adjust the object location to reduce the overlap between objects.
Step 5:
Here, only one object is monotonous. To this end, I modified the original code and clicked on the screen to constantly increase the number of objects in the world.
[Cpp]
Void Box2DTest1: ccTouchesEnded (CCSet * pTouches, CCEvent * pEvent)
{
CCSetIterator it;
CCTouch * touch;
 
For (it = pTouches-> begin (); it! = PTouches-> end (); it ++)
{
Touch = (CCTouch *) (* it );
CCPoint location = touch-> locationInView (touch-> view ());
Location = CCDirector: sharedDirector ()-> convertToGL (location );
 
AddSprite (location );
}
}
Add the ccTouchesEnded class to Box2DTest1 to respond to touch screen events.
Modify the update function at the same time:
[Cpp]
Void Box2DTest1: update (ccTime dt)
{
 
Int velocityIterations = 8;
Int positionIterations = 1;
 
// You should call b2World: Step every game loop
M_world-> Step (dt, velocityIterations, positionIterations );
 
 
For (b2Body * B = m_world-> GetBodyList (); B = B-> GetNext ())
{
If (B-> GetUserData ()! = NULL)
{
CCSprite * sprite = (CCSprite *) B-> GetUserData ();
Sprite-> setPosition (ccp (B-> GetPosition (). x * PTM_RATIO, B-> GetPosition (). y * PTM_RATIO ));
Sprite-> setRotation (-1 * CC_RADIANS_TO_DEGREES (B-> GetAngle ()));
}
}
}

Set CCSprite * sprite = CCSprite: spriteWithTexture (batch-> getTexture (), CCRectMake (, 32 ));
Change to CCSprite * sprite = CCSprite: spriteWithTexture (batch-> getTexture (), CCRectMake (rand () % 2) * 32, (rand () % 2) * 32, 32 ));

 
 

 
 
 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.