Pages

Sunday, March 10, 2013

Box2d Objective C Basic Sample

Javascript Version is here
http://jslogic.blogspot.in/2013/03/box2d-javascript-basic-sample.html


Which I have made in Box2D with Javascript. Now its time to convert this in Objective C. So here it is 

First Install Cocos2d as per RayWenderlich Blog
http://www.raywenderlich.com/28602/intro-to-box2d-with-cocos2d-2-x-tutorial-bouncing-balls

Now create a new Box2D project
and update HelloWorldLayer.h as below, If not



#import <GameKit/GameKit.h>

// When you import this file, you import all the cocos2d classes
#import "cocos2d.h"
#import "Box2D.h"
#import "GLES-Render.h"

//Pixel to metres ratio. Box2D uses metres as the unit for measurement.
//This ratio defines how many pixels correspond to 1 Box2D "metre"
//Box2D is optimized for objects of 1x1 metre therefore it makes sense
//to define the ratio so that your most common object type is 1x1 metre.
#define PTM_RATIO 32

// HelloWorldLayer
@interface HelloWorldLayer : CCLayer <GKAchievementViewControllerDelegate, GKLeaderboardViewControllerDelegate>
{
    CCTexture2D *spriteTexture_; // weak ref
    b2World* world;     // strong ref
    GLESDebugDraw *m_debugDraw;  // strong ref
}

// returns a CCScene that contains the HelloWorldLayer as the only child
+(CCScene *) scene;

@end



Now Delete the Code in init function of HelloWorld.mm and put the following code in init function


-(id) init
{
    if( (self=[super init])) {
        // init physics
        [self initPhysics];
        //This method allows to update the screen used for animation
        [self scheduleUpdate];
    }
    return self;
}


Now the main logic is written in initPhysics function



-(void) initPhysics
{
    
    CGSize s = [[CCDirector sharedDirector] winSize];
    
    b2Vec2 gravity;
    gravity.Set(0.0f, -10.0f);
    world = new b2World(gravity);
    
    
    // Do we want to let bodies sleep?
    world->SetAllowSleeping(true);
    
    world->SetContinuousPhysics(true);
    
    m_debugDraw = new GLESDebugDraw( PTM_RATIO );
    world->SetDebugDraw(m_debugDraw);
    
    uint32 flags = 0;
    flags += b2Draw::e_shapeBit;
    //  flags += b2Draw::e_jointBit;
    //  flags += b2Draw::e_aabbBit;
    //  flags += b2Draw::e_pairBit;
    //  flags += b2Draw::e_centerOfMassBit;
    m_debugDraw->SetFlags(flags);
    
    
    // Define the ground body.
    b2BodyDef groundBodyDef;
    groundBodyDef.position.Set(0, 0); // bottom-left corner
    
    // Call the body factory which allocates memory for the ground body
    // from a pool and creates the ground box shape (also from a pool).
    // The body is also added to the world.
    b2Body* groundBody = world->CreateBody(&groundBodyDef);
    
    // Define the ground box shape.
    b2EdgeShape groundBox;
    
    // bottom
    
    groundBox.Set(b2Vec2(0,0), b2Vec2(s.width/PTM_RATIO,0));
    groundBody->CreateFixture(&groundBox,0);
    
    // top
    groundBox.Set(b2Vec2(0,s.height/PTM_RATIO), b2Vec2(s.width/PTM_RATIO,s.height/PTM_RATIO));
    groundBody->CreateFixture(&groundBox,0);
    
    // left
    groundBox.Set(b2Vec2(0,s.height/PTM_RATIO), b2Vec2(0,0));
    groundBody->CreateFixture(&groundBox,0);
    
    // right
    groundBox.Set(b2Vec2(s.width/PTM_RATIO,s.height/PTM_RATIO), b2Vec2(s.width/PTM_RATIO,0));
    groundBody->CreateFixture(&groundBox,0);
    
    b2BodyDef bodyDef;
    bodyDef.type = b2_dynamicBody;
    
    b2PolygonShape carShape;
    b2Vec2 vertics[] = {
        b2Vec2 (0.0f, 0.0f),
        b2Vec2 (0.5f, -2.0f),
        b2Vec2 (1.0f, 3.0f),
        b2Vec2 (0.3f, 3.0f),
        b2Vec2 (0.0f, 1.0f)
    };
    carShape.Set(vertics, 5);
    
    b2FixtureDef fixtureDef;
    fixtureDef.shape = &carShape;
    fixtureDef.density = 1.0f;
    fixtureDef.friction = 0.5f;
    fixtureDef.restitution = 0.2f;
    
    bodyDef.position.Set(5, 400/PTM_RATIO/2);
    world->CreateBody(&bodyDef)->CreateFixture(&fixtureDef);
}