Cocos2d-x Study Notes (15)--------> Physics engine

Source: Internet
Author: User

Physics engine
The cocos2d-x engine incorporates two physical engines, box2d and Chipmunk, which are excellent 2D physics engines, and the X engine incorporates them in The SDK . box2d Use is more extensive, here choose box2d to study.
What the physics engine simulates : Gravity : Simulates the gravitational acceleration in the game, when the character jumps up and then moves downward, in the absence of ground scenes, the characters and objects are free fall by gravity. Traction (Power): In games like the engine of a car, the character itself provides the power to move forward, which is continuously acting on the object, so that the object can move in the direction of the force. Friction : When the object moves on the surface of the contact surface, it is affected by friction, which can make the moving object stop due to the effect of friction. Impact : For example, the explosion will produce a one-time impact, the explosion within the scope of the object to create a momentary effect of the force, so that it movement up. Collision Detection : When an object collides with another object, two objects are affected by the force and reaction of the collision. There are physical concepts such as buoyancy , joint linking , and so on.
box2d Introduction : box2d is a lightweight two-dimensional rigid-body simulation library developed by C + + that is used to write 2D games that developers can use to make objects in the game move more realistically. Make the world of the game more interactive. The box2d physics engine is a procedural animation system. There are two ways to animate: one is to prepare the image data needed for the animation beforehand, such as a format2Dpicture, and then play it in one frame at a frame. This pre-prepared can be called a data animation. The other is to dynamically calculate the data needed for the animation, such as the new position after the move, the angle of rotation, and so on, and then draw on the data. This dynamic calculation can be called a procedural animation. box2d is to use the physics method, deduce the game world object position, angle and so on data. and box2d is just the derivation of the data, as to how to deal with the data after it is the developer's own business.
some basic objects of box2d : physical world world : A physical world is a variety of Rigid body bodies , fixture fixtures , constraints constraints A collection of basic object interactions in the physical engine. All physical objects are generated in the physical world on the basis that the physical world has been established. The physical world has a range, in the all-in-one coordinate system, the physical world is a rectangular region, the physical objects within the region can interact with each other, physical collisions and other effects, once the physical objects to the region, will no longer perform physical operations, no longer have any physical effect. box2d supports creating multiple worlds, but this is usually not necessary. The physical world is the most important object of the box2d engine, and the game must hold the physical world object in order to access various objects in the physical world, knowing their state , and then update these states to the game interface to reflect the physical phenomena of various simulations. Rigid body rigid body: Most game objects in the physical world are abstracted into rigid objects, which are very hard substances in the physical world, the physical engine assumes that the rigid body is not deformed, and that the distance between any two points above it remains unchanged. In the box2d physics engine, the B2body class is the type that represents the rigid body. When designing a physical game, a rigid body usually corresponds to a character in the game that has a specific shape. Rigid bodies in the box2d are divided into two main categories, a kind of dynamic rigid body that can move position or rotate, which is usually used to represent the active object in the game, the other is static rigid body which cannot be moved and rotated, this kind of rigid body is usually used to indicate still life such as ground platform in game. Fixture Fixture: Each rigid body needs to define one or more fixtures, which are a property container that has shape attributes shape, The density attribute density, the friction attribute friction , and the recovery property restitution. When a rigid body has a fixture, it can participate in the physical world of collision detection, friction and elastic operations. shape shape : * Geometric Shape objects, such as round circlr or polygon Polygon . After the shape is defined, it is attached to a fixture, as the shape of the fixture exists, it is an important part of the fixture, furniture in the rigid body collision operation will be detected through the shape. The shape class holds primarily geometric data information about the shape, such as a round circle is primarily the radius information that holds it, As long as you know the radius to know the size of the circle; another commonly used shape is the quadrilateral rect , which mainly records the width and height information of the quads. Joint Joint: A joint is a constraint that is used to fasten two or more rigid bodies together. box2d supports different joint types-- rotating revolute, prismatic prismatic, distance distance and so on. For example, the cartoon character's arm movement, can define a human elbow joint, the joint ends are the upper arm and the forearm two rigid bodies. Some joints can have limited limits and motor Motors. Joint Limit jointlimit: The joint limit limits the range of motion of a joint point. Human elbows, for example, can only move within a certain angle. Joint Motors JointMotor: Depending on the degree of freedom of the joint, the joint motor can drive the object to which the joint is connected. For example, you can use a motor to drive the rotation of an elbow.
Introducing the box2d physical world into the game: Because xThe engine has built-in box2dPhysics engine, so where the physical engine is needed, just introduce "box2d/box2d.h"Header file, the following code is the creation of the physical world, that is, initialization box2dThe process of the physics engine, this process is placed in the game scene initialization phase, the physical World object as part of the game world to complete the initialization process.
Defines the gravitational acceleration b2vec2 gravity;//to set the vertical direction of the gravity gravity. Set (0.0f, -9.8f);/* uses the newly defined gravitational acceleration to generate the physical world object so that all objects in the world are affected by the gravitational acceleration */b2world* Phyworld = new B2world (gravity); Objects in the physical world are involved in collision detection, no dormant object phyworld->setallowsleeping (FALSE);//continuous collision detection to avoid the occurrence of an object passing through another object phyworld-> Setcontinuousphysics (TRUE);//Set Collision Listener Phyworld->setcontactlistener (listener);
With the above code, you can xBuild a physical world in the engine, the last step of the code above, to set the listener for the collision of various objects in the physical world-- Listener, it is B2contactlistenerType. A collision listener is used when the physical engine captures objects in the world that collide B2contactlistenercallback method to implement collision detection and response functions. All we have to do is define a collision detector and implement its collision callback function. The following functions are required for implementation. virtual void begincontact(b2contact* contact): The callback function at the beginning of collision, the general simple collision detection is used;
virtual void endcontact(b2contact* contact): The callback function after the collision occurs, the general simple collision detection is used;
virtual void presolve(b2contact* contact, const b2manifold* oldmanifold): The callback function before the collision, the solution is to calculate the impact force generated by the collision, it is necessary to calculate the impact impact of the damage caused by the effect of the need to use this callback function;
virtual void postsolve(b2contact* contact, const b2contactimpulse* Impulse): This callback function is needed to calculate the effects of the collision-solved callback function when it is necessary to compute the damage caused by impact impact.

The four callback methods, the first two features limited but simple to use, the latter two provide a large amount of information, but the use of more complex, this depends on the specific requirements of the game, if our game process on the physical requirements are not high, only to achieve collision detection function, then we mainly use begincontact(b2contact* contact)This callback function is sufficient, if we want to deal with the effect before and after the collision, according to the interaction force generated in the collision to calculate the movement after the physical collision, then we must make good use of all these four functions, they combine to simulate a more realistic and complex physical collision effect. Introduced during game initialization box2dPhysical world, and then implement the collision callback function, our physical world initialization work is done, the rest of the work is based on the game requirements, pre-build or dynamic generation of various physical objects during the game. such as rigid body objects.
Define object objects to achieve gravity effects :in the physics simulation game, there will be a large number of rigid bodies in the physical world. Sometimes these rigid bodies are created when the game is initialized, they have prefabricated properties such as position, density, volume, etc., while the other is to animate the powertrain body in real time and set the position of the rigidbody for the rigid body according to the game process. box2d is an efficient physics engine, so the real-time dynamic generation of rigid bodies is very fast, as long as the quantity is not very large, it will not affect the speed of the game, the rigid body will usually correspond to a role in the game or part of the role, such as in the flight shooting game, The body of an airplane can be represented by a combination of a rigid body or multiple rigid bodies, which is the abstraction of the physical world of a game character, and the physical change of a rigid body collision is ultimately fed back to the character in the game.
First, create an instance of the struct B2bodydef b2bodydef spritebodydef;//specifies that the type defined by the rigid body is a dynamic rigid body, indicating that the rigid body is a spritebodydef.type = b2_ that can be moved in the physical world dynamicbody;//set the initial position of the rigid body definition spriteBodyDef.position.Set (5.0f,5.0f);//Next use the Spritebodydef object to generate a real rigid body bodyb2body* Spritebody = Phyworld->createbody (&spritebodydef);//generate a rectangular shape, define the size range B2polygonshape Spriteshape; Spriteshape.setasbox (10.0f, 10.0f);//The Next generation of fixture objects to be used by the body body b2fixturedef spriteshapedef;// Specifies that the shape of the fixture is just the resulting rectangle spriteshapedef.shape = &spriteshape;//set its physical density spriteshapedef.density = 10.0f;// Set your own collision Group SpriteShapeDef.filter.categoryBits = 0x0010;//Group 2nd//Specify which group you will collide with spriteShapeDef.filter.maskBits = 0x0001 ;//1th Group//use a defined fixture to generate rigid body spritebody->createfixture (&spriteshapedef);
At this point, there is a rigid body object in the physical world, which emphasizes the collision grouping information when the fixture of a rigid body is defined, where filter.categorybitsThe fixture of the rigid body is defined in group 2nd and the next filter.maskbitsDefined as group 1th, so that the fixture of the rigid body collides with the rigid fixture in the first group, while the other groups or rigid fixtures in the same group, even if there is contact, do not collide, which is box2dCollision grouping filtering for the physics engine. This is very useful in the game.after defining this rigid body., it defaults to the origin of the physical world, the point of coordinates (0,0) , when it is not set.
To achieve collision detection of objects: B2contactlistener: It is the whole Box2A collision-monitoring and response class in the physical world that occurs in box2dThe collision time in the physical world can be B2contactlistenerType of listener detection and is processed in the collision response function. Usually we are implementing our own implementation of the game world as a collision detection interface implementation class, that is, in the definition of one of our own game world class (here we assume that it is called WorldClass), we let it inherit from B2contactlistener, so WorldThe instance object of the class can capture and process the collision of the physical world. For example
Class World:p ublic B2contactlistener
The processing callback function corresponding to the physical world is also declared here, in this case we only respond to events that occurred at the moment of the collision, and other events are not dealt with in detail, so the function declaration of the collision detection 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 handle}virtual void Presolve (b2contact* contact, const b2manifold* oldmanifold) {b2_not_used (Contact) ;//Close this event, do not handle b2_not_used (oldmanifold);//Close this event, do not handle}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}


using joints to connect rigid bodies connector: The connector can connect two or more rigid bodies together to limit the role of objects or objects within the world.
Distance connector( Distance Joint): The most common and simplest connector is the distance connector that is commonly said to maintain 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 place. The two anchor points are then specified in the world coordinate system, the first anchor point is connected to the Body1, and the second anchor point is connected to a body2. These points represent constants of the distance that should be maintained. This way, no matter how the two objects move, they will maintain a fixed distance between them, just as they are connected with a pole. The distance connector can also become soft, just like connecting a spring, in the definition by adjusting Frequency( Frequency) and Resistance Gini rate( damping ratio) Two constants to achieve a soft effect, 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, and the fixed distance connector can simulate the physical phenomena of the warping board, the rope that binds the object, and the soft connector can be used to simulate the physical phenomena such as the springboard and rubber bands.

Rotary Connectors( Revolute Joint): The rotary Connector acts on two rigid bodies and allows two rigid bodies to share the same anchor point, often referred to as a Hinge Point( Hinge Point)。 The rotary connector has a range of degrees of freedom relative to the rotation of two objects. This angle 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 in the correct position. In the following example code, two rigid bodies are rotated through a connector with the centroid of the first object as Hinge Point( Hinge Point) are connected together. When BodybWhen rotating counterclockwise, the angle of the swivel connector is positive. Just like box2dRotation is measured in radians, as in all other corners in the In general, Rotary connectors use Initialize ()After the method is created, the rotation connector has zero angle and is independent of the current angle of the two objects. On some occasions you can hope to control Connection Angle( Joint Angle), the following code gives the setup of the Rotary connector and the limit 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);
Rotary connectors are also used in a wide range of applications where rotary switches are involved, such as the wheels of a car. As long as the power or torque is acting on the wheel rigid body to let the connector rotate, the car can move forward or backward.

Pan connector( Prismatic Joint): The two rigid bodies associated with the Pan connector run are panned along a specific axis. Panning joins block relative rotation. Therefore, the panning connection has only one direction of freedom.
B2prismaticjointdef jointdef;jointdef.initialize (Body1,body2,body2->getposition (), body2->GetPosition ()); Jointdef.lowertranslation = -100.0f;jointdef.uppertranslation = 100.0f;jointdef.enablelimit = true;phyWorld-> Createjoint (&JOINTDEF);
Pan connector applications are also widespread in the game: When an object crosses a plane with another object, it needs to use a translation connector, such as a vertical lift, to simulate the implementation using a translation connector.

box2d Debug Rendering : During testing, all rigid body shapes should be visible so that we can observe the detailed processes and results of various physical collisions, which requires us to introduce GlesdebugdrawClass. It is used OpenglesThe underlying drawing method, which accurately draws the shape of a rigid body to a function class on the screen. GlesdebugdrawClass is located in cocos2d-x SDKOf Gles-render.hFile. All if the game needs to be used to box2dPhysics engine and need to debug, it is necessary to copy these two classes to the game's class file directory and refer to these two files. The two files also define the B2drawClass, which provides most of the abstract methods for drawing geometry. Use: First, you will GlesdebugdrawObjects of the type are set to the physical World object, and then confirm what needs to be drawn and what can be drawn include the body's ProfilecentroidJointsaabb Surround Box(i.e. a rectangular bounding box that surrounds a rigid body).
Debugdraw = new Glesdebugdraw ();//Create a new debug render module Phyworld->setdebugdraw (Debugdraw) here;//Set UInt32 flags = 0;flags + = b2draw::e_shapebit;//Shape Flags + = B2draw::e_aabbbit;//aabb Block flags + b2draw::e_centerofmassbit;//material body Heart flags + b2draw::e _jointbit;//Joint Debugdraw->setflags (Flags), scheduleupdate ();//each frame invokes a method called Update to refresh the screen
scheduleupdatefunction will be called in each frame, a UpdateThe method. This method can be written like this:
void Helloworld::update (float dt) {phyworld->step (0.03f,10,10);}
This allows the screen to be refreshed at each frame, and the contents of the physics engine become visible.

box2d Speed and performance considerations: The physical engine is actually more hardware-intensive, because a lot of rigid-body collision detection in the engine, the effects of various forces are computationally expensive CPUOperation time. Especially when the number of rigid bodies is increasing, box2dThe computational volume will grow at a geometric level. So use Box2Physics engine, it is important to pay attention to performance optimization and several techniques to improve the simulation degree. (1) distinguishing between static and dynamic rigid bodies: If an object can be defined using a static rigid body, then it must not be defined with a dynamic rigid body. Because the static rigid body only carries on the collision detection, does not consider the force to its influence, relative to the dynamic rigid body, the static rigid body computation is much smaller, may reduce CPUThe burden. (2) start dynamic rigid body sleep properties: When the physical engine is initialized, performance can be improved by setting whether to allow dynamic rigid body hibernation. If the setting allows dynamic rigid bodies to sleep, some rigid bodies that are subjected to very small forces or are not subjected to force, they will remain stationary, and they will go to sleep SleepState. Enter SleepState of the rigid body, will not be physical operations, so that can reduce the computational time, know that they are again under the action of the Force, will be awakened from hibernation, continue to participate in the physical calculation.
(3) Set Unit conversion parameters: The game screen is measured in pixels, while the physical engine is in meters, and there is a unit conversion relationship between meters and pixels. The physics engine has a reasonable unit of work range, in box2d, the size of the object is best 0.1 MTo 10 m, if this range is exceeded, the performance of the object may become untrue. So when designing a game's object size, its pixel units also need to have a reasonable range. We usually set the conversion value to +, so in the game 32*32Pixel-sized object, in the physics engine it is 1 m * * MSize, within such a reasonable size range, box2dThe simulation effect of the engine will be more realistic.
(4) Set bullet Properties: Dynamic rigid bodies sometimes move at high speeds, and if a rigid body moves between two frames more than the height of the colliding object, the collision detection loses its detection function and the rigid body passes through the obstacle directly. So if a rigid body moves very fast, you need to set this rigid body as a bullet type, which is a dynamic rigid body type that moves at high speed, using Setbullet (True)Function. Such a rigid body, when moving, calculates whether the movement of each unit is colliding and does not occur directly through the barrier.

code generation tools for complex polygons: 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, which requires some useful tools to define the shape of the object, VertexhelperSoftware is an open source free fixed-point drawing tool. You can draw any polygon you want with a visual interface. The vertex data that makes up these polygons will be given in C + + code and copied and pasted to put the complex polygon generation code into its own class.

Cocos2d-x Study Notes (15)--------> Physics engine

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.