Friday, 11 January 2013

Box2D introduction


The physics engine used by Tank Rampage is called Box2D. Just like Cocos2d, it’s
open source and widely supported. It’s written in C++, and as a result part of our project is written in C++. Hence the fact that our implementation files are all named Classname.mm, as this is required file containing C++.

           
The structure of a Box2D project
            A Box2D physics simulation consists of a world to which bodies are added. Since it doesn’t handle the visual representation of the bodies, textures have to be attached to these bodies in order for the player to see them. For developing purposes, a debug view can be shown.
 A Box2D debug draw with a number of circles and rectangles



Using Box2D
            In order for a sprite to stay at the same position as its bodies, the developer has to write code handling this problem. In Tank Rampage, this is handled by the Levelhelper API (more on which later). A solution for this problem could look similar to this pseudo code:

-(void)updatePos{
    
    self.sprite.position=ccp(body->GetPosition().x,body->GetPosition().y);
    self.sprite.rotation=-1*CC_RADIANS_TO_DEGREES(body->GetAngle());
    
}

Note that rotation in Cocos2d is listed in degrees, where as Box2D rotation is noted in radials, hence the conversion from radians to degrees.

Bodies
Box2D bodies have variables such as mass, friction and restitution (or ‘bounciness’). Forces and impulses can be applied to bodies on different anchor points, and their velocity can be set. A Box2D world’s gravity can be changed.
            A Box2D body can be static, kinematic or dynamic. A static body can collide with only dynamic bodies and acts as if it has infinite mass (but internally, Box2D stores a mass of zero), resulting in a velocity of zero (such as a floor or wall). They can be moved manually by the user. A kinematic body moves according to its velocity and does not respond to forces. They can only collide with dynamic bodies. Dynamic bodies are fully simulated. They can be moved by the user or according to forces and collide with all body types. Dynamic bodies always have a finite mass, usually somewhere between 0 and 2.
            A body is made up of fixtures. Fixtures have collision geometry and density (that is can be overridden by the body they’re a part of). Bodies are always rigid, meaning that two fixtures attached to the same body do not move relative to each other.
            When a body is moving at a high speed, an effect called tunneling may occur. Tunneling happens when a body passes through another, even though they should collide.  This happens because the position of a body is calculated every frame, and when a body’s velocity is high enough, one frame it may be cruising towards an object, and the next it may have already passed it. In order to avoid this, a body can be labeled as a bullet. It does however impact performance, and should not be used on all dynamic bodies on a mobile platform.
            One final feature of Box2D is the ability of bodies to sleep.  When Box2D determines that a body has come to rest, it is not simulated anymore (and put to sleep). This saves processing power and thus increases performance. When an awake body collides with an asleep body, the body is woken.

Joints
            Box2D joints are used to attach objects to the world or to each other. For instance, the wheels of a car to the car body, or a tanks barrel to a tank body. There are numerous types of joints such as revolute joints, distance joints an pulley joints, all with slightly differing behaviors.
            Joints can contain motors. This can be used to control the position of and rotation of a joint (similar to robotics in real life), or simulate friction. Motors can have velocity and torque.
            Data such as the bodies attached to the joint and reaction forces can be attained from joints, allowing for events such as breaking joints when a certain force is exceeded.

No comments:

Post a Comment