Cocos2d-x Study Notes (15th) -------- & gt; physical engine, cocos2d-x Study Notes

Source: Internet
Author: User

Cocos2d-x Study Notes (15) --------> physical engine, cocos2d-x Study Notes
Physical Engine
Cocos2d-xThe engine has two built-in physical engines:Box2DAndChipmunkAnd they are all excellent.2DThe physical engine, and the x engine built themSDK.Box2DWidely used.Box2DTo learn.
Physical engine simulation content:Gravity: The acceleration of gravity is simulated in the game. When a character jumps up in the game, it will be affected by the gravity and move down. In scenarios without ground, people and objects will freely fall into the body due to gravity.Traction (power): In games, for example, the engine of a car, the character itself can provide the power to move forward. This traction is constantly applied to the object, so the object can move in the direction of the Force.Friction: When an object moves on a contact surface such as the ground, it will be affected by the friction. It can stop a moving object due to the friction.ImpactFor example, an explosion will generate a one-time impact on an object in the explosion range, which will generate an instant force to make it move.Collision Detection: When an object collides with another object, the two objects will be affected by the collision force and reaction force. AndBuoyancy,Joint LinkAnd other physical concepts.
Box2D Introduction:Box2DYesbyC ++A lightweight two-dimensional rigid body simulation library developed for writing2DGame developers can use it to make the objects in the game more realistic. Make the gaming world more interactive.Box2DA physical engine is a procedural animation system. There are two ways to play an animation: one is to prepare the image data required for the animation in advance, such as a 2D image in a certain format, and then play it one frame at a time. This pre-prepared animation can be called a data animation. Another method is to dynamically calculate the data required for the animation, such as the new position after moving and the rotation angle. Then, draw the animation based on the data. This kind of dynamic computing can be called procedural animation.Box2DIt is the use of physics to export the location, angle, and other data of the game world objects. WhileBox2DIt's just about pushing and exporting data. It's just about the developer's own thing to do after getting the data.
Some basic objects of Box2D:Physical world: A physical world is a varietyRigid bodies,Fixture fixtures,Constraint constraintsThe set of basic objects interacting with each other in the physical engine. All physical objects are generated in the physical world on the basis of the established physical world. The physical world has a range in2DIn the coordinate system, the range of the physical world is a rectangular area. physical objects in a region can interact with each other and have physical collisions. Once a physical object is out of a region, no physical operations will be performed, it does not have any physical functions.Box2DSupports creating multiple worlds, but this is usually unnecessary. The physical world isBox2DAn engine is the most important object. A game must hold objects in the physical world so that it can access objects in the physical world and know their statuses, then update these statuses to the game interface to reflect various simulated physical phenomena.Rigid body: Most game objects are abstracted as rigid objects in the physical world. They are very hard substances in the physical world. The physical engine assumes that the rigid bodies are not deformed, the distance between any two points remains unchanged. InBox2DIn the physical engine,B2BodyClass is the type that represents the rigid body. During the design and implementation of a physical game, the rigid body usually corresponds to a specific role in the game. Rigid Body inBox2DIt can be divided into two main categories, one is the moving position or rotating dynamic rigid body, this type of rigid body is usually used to represent the active objects in the game; the other is the static rigid body where the position cannot be moved or rotated, this type of rigid body is usually used to represent static objects such as ground platforms in the game.Fixture: Each rigid body must define one or more jigs. The jigs are oneProperty container, It hasShape property shape,Density attribute density,Friction Property frictionAndRestore attributes restitution. When a rigid body has a fixture, it can participate in the collision detection of the physical world, friction and elasticity operations.Shape:2DGeometric Shape object, suchCircular circlrOrPolygon. After the shape is defined, it will be attached to a fixture. As the shape attribute of the fixture, it is an important part of the fixture. The furniture will be detected by the shape during rigid body collision calculation. The shape class stores the geometric data information of the shape, such asCircular circleIt is mainly to save its radius information, as long as you know the radius, you can know the specific size of the circle; another common shape isQuadrilateral rectIt records the width and height of the Quadrilateral.JointJoint is a constraint used to fix two or more rigid bodies together.Box2DDifferent joint types are supported --Turn revolute,Prism prismatic,Distance from distance. For example, a cartoon character's arm movement can define an elbow like a human. The two ends of the joint are the upper arm and the forearm. Some joints can haveRestrict limitsAndMotor motors.Joint limit: The Joint limits the motion range of a Customs node. For example, the human elbow can only motion within a certain angle.Joint motor: Based on the degree of freedom of the joint, the joint motor can drive the object connected to the joint. For example, you can use a motor to drive an elbow rotation.
Introduce Box2D physical world in the game: BecauseXBuilt-in EngineBox2DPhysical engine."Box2D/Box2D. h"Header file. The following code is used to create a physical world, that is, initialization.Box2DThe process of the physical engine is put in the game scenario initialization phase, and the physical world object is used as part of the game world to complete the initialization process.

// Define the gravity acceleration b2Vec2 gravity; // set the vertical gravity acceleration gravity. set (0.0f,-9.8f);/* use the previously defined gravity acceleration to generate a physical world object, in this way, all objects in the world will be affected by the acceleration of gravity */b2World * phyWorld = new b2World (gravity); // all objects in the physical world participate in the collision detection, no sleep object phyWorld-> SetAllowSleeping (false); // consecutive collision detection to prevent the event phyWorld-> SetContinuousPhysics (true) when the object passes through another object ); // set the collision listener phyWorld-> SetContactListener (listener );
With the above code, you can XThe engine establishes a physical world. The last step of the above Code is to set the listening object for collision of various objects in the physical world -- Listener, It is B2ContactListenerType. After an object in the world is captured by a physical engine, a collision listener is used. B2ContactListenerTo realize collision detection and response. What we need to do is define a Collision detector to implement its collision callback function. The following functions need to be implemented. Virtual void BeginContact (b2Contact * contact): The callback function at the beginning of a collision. It is generally used for simple collision detection;
Virtual void EndContact (b2Contact * contact): Callback function after collision, which is generally used for simple collision detection;
Virtual void PreSolve (b2Contact * contact, const b2Manifold * oldManifold): The callback function before the collision solution. The solution refers to the impact produced by the collision. This callback function must be used to calculate the damage caused by the collision impact;
Virtual void PostSolve (b2Contact * contact, const b2ContactImpulse * impulse): This callback function is used to calculate the damage caused by collision impact and other effects after collision resolution.

Among the four callback methods, the first two functions are limited but simple to use. The last two provide a large amount of information, but they are complicated to use. This depends on the specific requirements of the game, if our gaming process has low physical requirements and only implements the collision detection function, we mainly use BeginContact (b2Contact * contact)This callback function is enough. If we want to deal with the effect before and after the collision, we can calculate the movement after the physical collision based on the interaction force generated in the collision, then we must make good use of all the four functions, which work together to simulate a more realistic and complex physical collision effect. Introduced during game Initialization Box2DAfter the physical world is implemented and the collision callback function is implemented, the initialization of the physical world is completed. The rest of the work is based on the game requirements, various physical objects are generated in advance or dynamically during the game. For example, a rigid body object.
Define object to achieve gravity effect: In physical simulation games, there are usually a large number of rigid bodies in this physical world. Sometimes these rigid bodies are created during game initialization. They have premade attributes such as location, density, and volume. The other scenario is to dynamically generate rigid bodies in real time based on the game process, and set the position and other attributes for the Rigid Body. Box2DIt is an efficient physical engine, so the real-time dynamic generation of rigid bodies is very fast, as long as the number is not very large, it will not affect the running speed of the game, A rigid body usually corresponds to a role or a part of the role in this game. For example, in a flying shooting game, the airplane body can be represented by a rigid body or a combination of multiple rigid bodies, the rigid body is the abstraction of the game role in the physical world. The physical changes of the rigid body collision must finally be fed back to the role in the game.
// First generate the b2BodyDef struct instance b2BodyDef spriteBodyDef; // specify that the type defined by the rigid body is a dynamic rigid body, indicating that the rigid body is a spriteBodyDef that can be moved in the physical world. type = b2_dynamicBody; // you can specify the initial position spriteBodyDef. position. set (5.0f, 5.0f); // use the spriteBodyDef object to generate the real Rigid Body Bodyb2Body * spriteBody = phyWorld-> CreateBody (& spriteBodyDef); // generate a rectangular shape, defines the size range b2PolygonShape spriteShape; spriteShape. setAsBox (10.0f, 10.0f); // The Clamp object b2FixtureDef spriteShapeDef to be used by the rigid Body is generated next; // the shape of the specified fixture is the shape of the newly generated rectangular spriteShapeDef. shape = & spriteShape; // set its physical density spriteShapeDef. density = 10.0f; // set your own collision group spriteShapeDef. filter. categoryBits = 0x0010; // Group 2nd // specifies the group in which the user will collide with spriteShapeDef. filter. maskBits = 0x0001; // 1st groups // use the defined fixture to generate a rigid body spriteBody-> CreateFixture (& spriteShapeDef );
At this point, there is a rigid body object in the physical world. Here we want to emphasize the collision group information when the rigid body fixture is defined. Filter. categoryBitsDefine the fixture of the Rigid Body in Group 2nd. Filter. maskBitsDefined as 1st groups. In this way, the jigs of this rigid body will collide with the rigid body jigs in the first group, and other groups or rigid body jigs in the same group, even if there is a contact, there will be no collision event. This is Box2DThe collision group filtering function of the physical engine. This is useful in games. After this rigid body is defined, if its position is not set, it will appear in the physical world's origin by default, that is, coordinates. (0, 0).
Collision Detection of objects: B2ContactListener: It is the whole Box2The listening and response classes that cause collisions in the physical world. Box2DThe collision time in the physical world can be B2ContactListenerType listener detected and processed in the collision response function. We usually use our own game world as the interface implementation class for collision detection, that is, to define a certain game world class (Here we assume that it is called WorldClass), we let it inherit from B2ContactListener WorldClass instance object can capture and process the collision in the physical world. For example:
class World :public b2ContactListener
The processing callback function corresponding to the physical world is also declared here. In this example, we only respond to the event at the moment of collision, and do not process other events in detail. Therefore, the collision detection function declaration is as follows.
// Collision Event Callback Function virtual void BeginContact (b2Contact * contact); virtual void EndContact (b2Contact * contact) {B2_NOT_USED (contact); // close this event, do not process} virtual void PreSolve (b2Contact * contact, const b2Manifold * oldManifold) {B2_NOT_USED (contact); // close this event, do not process B2_NOT_USED (oldManifold ); // close this event without processing} virtual void PostSolve (b2Contact * contact, const b2ContactImpulse * impulse) {B2_NOT_USED (contact); // close this event, do not process B2_NOT_USED (impulse); // close this event, do not process}


Use joints to connect to a rigid body: Connector: The connector can connect two or more rigid bodies to restrict objects in the world or between objects.
Distance Connector( Distance Joint): The most common and simplest connector is usually called a connector that maintains a certain distance between two points on two rigid bodies. When you specify a distance connector, the corresponding two rigid bodies should already be in the proper position. Then, specify two anchor points in the world coordinate system. The first anchor points are connected to body1, and the second anchor points are connected to body2. These points represent the constant of the distance to be maintained. In this way, no matter how the two objects move, they will maintain a fixed distance, just like connecting the two objects with a pole. The distance connector can also become soft, just like connecting a spring, through adjustment in Definition Frequency( Frequency) And resistance NI rate( Damping ratio) Two constants to achieve soft effects. The following is a distance connector that defines a spring effect.
b2DistanceJointDef jointDef;jointDef.Initialize(body1, body2, body1->GetPosition(),body2->GetPosition());jointDef.collideConnected = true;jointDef.frequencyHz = 4.0f;jointDef.dampingRatio = 0.5f;jointDef.length = 10;phyWorld->CreateJoint(&jointDef);
The distance connector is widely used. The fixed Distance connector can simulate physical phenomena such as the climbing and the rope bound to objects. Soft connectors can be used to simulate physical phenomena such as springboards and rubber bands.

Rotating Connector( Revolute Joint): The rotating connector acts on two rigid bodies at the same time and shares the same anchor point with the two rigid bodies. Hinge point( Hinge point). The Rotary connector has a degree of freedom relative to the rotation of two objects. This is called Connection Angle( Joint angle).
To customize a rotating connection, we need to provide two rigid bodies and a simple anchor point in the world. The initialization method assumes that the object is already in the correct position. In the following example code, two rigid bodies use the center of the first object Hinge point( Hinge Point. When BodyBWhen it turns counter-clockwise, the angle of the rotating connector is positive. Just like Box2DThe rotation is based on radians. Generally, the rotating connector is used. Initialize ()After the method is created, the angle of the rotating connector is zero, regardless of the current angle of the two objects. In some cases, you may want to control Connection Angle( Joint angle), The following code specifies the creation of the rotating connector and the restriction setting of the connection angle:
b2RevoluteJointDef jointDef;jointDef.Initialize(body1,body2, b2Vec2(body1->GetPosition().x-15,body1->GetPosition().y+15));jointDef.lowerAngle = -0.5 * b2_pi;jointDef.upperAngle = 0.25 * b2_pi;jointDef.enableLimit = true;phyWorld->CreateJoint(&jointDef);
The Rotary connector is also widely used. Any place that involves the rotary switch can be implemented using the rotary connector, for example, the wheel of a car. We only need to apply the power or torque to the wheel Rigid Body to let the connector rotate, the car can move forward or backward.

Translation Connector( Prismatic Joint): The translation connector runs the two associated rigid bodies to pan along the specific axis. The translation link prevents relative rotation. Therefore, the translation connection has only one degree of freedom in the direction.
b2PrismaticJointDef jointDef;jointDef.Initialize(body1,body2,body2->GetPosition(), body2->GetPosition());jointDef.lowerTranslation = -100.0f;jointDef.upperTranslation = 100.0f;jointDef.enableLimit = true;phyWorld->CreateJoint(&jointDef);
Translation connector is also widely used in games: when an object is moved across a plane from another object, a translation connector, such as a vertical elevator, needs to be used, you can use the translation connector to simulate the implementation.

Box2D debug Rendering: During the test, all rigid bodies should be visible, so that we can observe the detailed process and results of various phenomena such as physical collisions. This requires us to introduce GLESDebugDrawClass. It is used OpenGLESThe underlying plotting method accurately draws the shape of a rigid body to a functional class on the screen. GLESDebugDrawClass located Cocos2d-x SDKOf GLES-Render.hFile. All Box2DTo debug the physical engine, you need to copy these two classes to the game class file directory and reference these two files. The two files also define B2DrawClass, which provides a majority of abstract methods for drawing ry. Use: GLESDebugDrawType object is set to the physical world object, and then confirm what needs to be drawn, the content that can be drawn includes Shape, Centroid, Joint, AABB box(That is, the rectangular box that can enclose a rigid body.
DebugDraw = new GLESDebugDraw (); // create a new debug rendering module phyWorld-> SetDebugDraw (debugDraw); // set uint32 flags = 0; flags + = b2Draw: e_shapeBit; // shape flags + = b2Draw: e_aabbBit; // AABB block flags + = b2Draw: e_centerOfMassBit; // object center flags + = b2Draw: e_jointBit; // joint debugDraw-> SetFlags (flags); scheduleUpdate (); // each frame calls an update method to refresh the screen.
ScheduleUpdateThe function calls Update. This method can be written as follows:
void HelloWorld::update(float dt){phyWorld->Step(0.03f,10,10);}
In this way, the screen will be refreshed at each frame, and the content in the physical engine will become visible.

Box2D speed and performance considerations: The physical engine actually occupies hardware resources. Because of the large number of rigid body collision detection in the engine, the computing of various forces is very expensive. CPUOperation Time. Especially when the number of rigid bodies increases significantly, Box2DThe calculation amount will increase in the geometric level. So use Box2When using a physical engine, you must pay attention to several techniques to optimize performance and improve simulation. (1) Distinguish static and dynamic rigid bodies: If an object can be defined using a static rigid body, do not use a dynamic rigid body to define it. Static rigid bodies only perform collision detection without considering the impact of force on them. Compared with dynamic rigid bodies, the calculation workload of static rigid bodies is much smaller and can be reduced. CPU. (2) Enable dynamic rigid body sleep attribute: During physical engine initialization, you can set whether to allow dynamic rigid body sleep to improve performance. If you set to allow a dynamic rigid body to sleep, some rigid bodies that are subject to a small force or are not subject to a force will remain static, and they will enter sleep SleepStatus. Enter SleepThe state of the rigid body, will not perform physical operations, this can reduce the operation time, know that they are again affected by the Force in motion, will be awakened from the sleep state, continue to participate in physical computing.
(3) Set unit conversion Parameters: Game screens are measured in pixels, while physical engines are measured in meters. Here there is a conversion relationship between meters and pixels. The physical engine has a reasonable unit scope of work in Box2DMedium, the object size is best in 0.1 metersTo 10 metersIf the range is exceeded, the object may become unreal. Therefore, designing an object in the game requires a reasonable range of pixel units. We usually set the conversion value 32In this way, in the game 32*32An object of pixel size, in the physical engine, is 1 M * 1 mWithin such a reasonable size range, Box2DThe simulation results of the engine will be more realistic.
(4) Set bullet attributes: The dynamic rigid body sometimes moves at high speed. if the distance between the two frames of the rigid body exceeds the length of the collision object, the collision detection function is lost, the rigid body directly passes through the obstacle. Therefore, if a rigid body moves fast, you need to set this rigid body to the bullet type, that is, the dynamic rigid body type of high-speed movement. SetBullet (true)Function. When such a rigid body moves, it calculates whether the movement of each unit is a collision, and does not directly pass through the obstacle.

Code Generation Tool for complex Polygon: When the shape of a game object becomes rich and complex, it is unrealistic to manually write code to define the shape of the object. This requires some effective tools to define the shape of the object, VertexhelperThe software is an open-source and free fixed-point rendering tool. You can use a visual interface to draw a polygon that you want. The vertex data that makes up these polygon will be given in the form of C ++ code. After copying and pasting, you can put the complex polygon Generation Code into your own class.

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.