Box2D - Problems with distanceJoint and RevoluteJoint
Hi,
I want to do a barrier with b2_dynamicbody but when i create a circle and set its velocity to 1.0, this break the barrier and i dont want this to happen.
I test with Distancejoint and RevoluteJoint but it doesnt work.
Configuration:
Mac OS X 10.6
Cocos2D 99.5
Xcode 3.2.5
iOS SDK 4.2
HelloWorldScene.h:
Code:
// When you import this file, you import all the cocos2d classes
#import "cocos2d.h"
#import "Box2D.h"
#import "GLES-Render.h"
// HelloWorld Layer
@interface HelloWorld : CCLayer
{
b2World* world;
b2Body* circle1;
b2Body* circle2;
GLESDebugDraw *m_debugDraw;
}
// returns a Scene that contains the HelloWorld as the only child
+(id) scene;
-(void) createCircles;
-(void) createBarrierDistance;
-(void) createBarrierRevolute;
@end
HelloWorldScene.mm:
Code:
#import "HelloWorldScene.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
// enums that will be used as tags
enum {
kTagTileMap = 1,
kTagBatchNode = 1,
kTagAnimation1 = 1,
};
// HelloWorld implementation
@implementation HelloWorld
+(id) scene
{
// 'scene' is an autorelease object.
CCScene *scene = [CCScene node];
// 'layer' is an autorelease object.
HelloWorld *layer = [HelloWorld node];
// add layer as a child to scene
[scene addChild: layer];
// return the scene
return scene;
}
// initialize your instance here
-(id) init
{
if ((self=[super init])) {
// enable touches
self.isTouchEnabled = YES;
CGSize screenSize = [CCDirector sharedDirector].winSize;
// Define the gravity vector.
b2Vec2 gravity;
gravity.Set(0.0f, -10.0f);
// Do we want to let bodies sleep?
// This will speed up the physics simulation
bool doSleep = false;
// Construct a world object, which will hold and simulate the rigid bodies.
world = new b2World(gravity, doSleep);
// Debug Draw functions
m_debugDraw = new GLESDebugDraw( PTM_RATIO );
world->SetDebugDraw(m_debugDraw);
uint32 flags = 0;
flags += b2DebugDraw::e_shapeBit;
// flags += b2DebugDraw::e_jointBit;
// flags += b2DebugDraw::e_aabbBit;
// flags += b2DebugDraw::e_pairBit;
// flags += b2DebugDraw::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.
b2PolygonShape groundBox;
// bottom
groundBox.SetAsEdge(b2Vec2(0,0), b2Vec2(screenSize.width/PTM_RATIO,0));
groundBody->CreateFixture(&groundBox,0);
// top
groundBox.SetAsEdge(b2Vec2(0,screenSize.height/PTM_RATIO), b2Vec2(screenSize.width/PTM_RATIO,screenSize.height/PTM_RATIO));
groundBody->CreateFixture(&groundBox,0);
// left
groundBox.SetAsEdge(b2Vec2(0,screenSize.height/PTM_RATIO), b2Vec2(0,0));
groundBody->CreateFixture(&groundBox,0);
// right
groundBox.SetAsEdge(b2Vec2(screenSize.width/PTM_RATIO,screenSize.height/PTM_RATIO), b2Vec2(screenSize.width/PTM_RATIO,0));
groundBody->CreateFixture(&groundBox,0);
// Create circles
[self createCircles];
// Create Distance Joint
[self createBarrierDistance];
// Create Revolute Joint
[self createBarrierRevolute];
[self schedule: @selector(tick:)];
}
return self;
}
- (void) createBarrierDistance {
b2PolygonShape shape;
shape.SetAsBox(8.0f/PTM_RATIO, 2.5f/PTM_RATIO);
b2FixtureDef fd;
fd.shape = &shape;
fd.density = 20.0f;
fd.friction = 0.2f;
b2BodyDef bd;
bd.type = b2_staticBody;
bd.position.Set(60.0f/PTM_RATIO, 220.0f/PTM_RATIO);
b2Body* first = world->CreateBody(&bd);
first->CreateFixture(&fd);
b2DistanceJointDef jointDef;
float distance = 70.0f/PTM_RATIO;
b2Body* next;
next = first;
int i = 1;
do {
b2BodyDef bd;
if (i == 9) {
bd.type = b2_staticBody;
}
else {
bd.type = b2_dynamicBody;
}
bd.position.Set(distance, 220.0f/PTM_RATIO);
b2Body* body = world->CreateBody(&bd);
body->CreateFixture(&fd);
jointDef.Initialize(next, body, next->GetPosition(), body->GetPosition());
world->CreateJoint(&jointDef);
distance = distance + 15.0f/PTM_RATIO;
next = body;
i++;
} while (i < 10);
}
- (void) createBarrierRevolute
{
b2PolygonShape shape;
shape.SetAsBox(8.0f/PTM_RATIO, 2.5f/PTM_RATIO);
b2FixtureDef fd;
fd.shape = &shape;
fd.density = 20.0f;
fd.friction = 0.2f;
b2BodyDef bd;
bd.type = b2_staticBody;
bd.position.Set(260.0f/PTM_RATIO, 220.0f/PTM_RATIO);
b2Body* first = world->CreateBody(&bd);
first->CreateFixture(&fd);
b2RevoluteJointDef jd;
jd.collideConnected = true;
b2Body* next;
next = first;
int i = 1;
float distance = 270.0f/PTM_RATIO;
do {
b2BodyDef bd;
if (i == 9) {
bd.type = b2_staticBody;
}
else {
bd.type = b2_dynamicBody;
}
bd.position.Set(distance, 220.0f/PTM_RATIO);
b2Body* body = world->CreateBody(&bd);
body->CreateFixture(&fd);
jd.Initialize(next, body, next->GetPosition());
world->CreateJoint(&jd);
distance = distance + 10.0f/PTM_RATIO;
next = body;
i++;
} while (i < 10);
}
- (void) createCircles
{
// Circle 1
b2BodyDef bd;
bd.position.Set(100.0f/PTM_RATIO, 200.0f/PTM_RATIO);
bd.type = b2_kinematicBody;
bd.fixedRotation = false;
bd.allowSleep = false;
circle1 = world->CreateBody(&bd);
circle1->SetLinearVelocity(b2Vec2(0.0,1.0));
b2CircleShape shapecircle;
shapecircle.m_radius = 0.5f;
b2FixtureDef fdcircle;
fdcircle.shape = &shapecircle;
fdcircle.density = 20.0f;
circle1->CreateFixture(&fdcircle);
// Circle 2
b2BodyDef bd1;
bd1.position.Set(310.0f/PTM_RATIO, 200.0f/PTM_RATIO);
bd1.type = b2_kinematicBody;
bd1.fixedRotation = false;
bd1.allowSleep = false;
circle2 = world->CreateBody(&bd1);
circle2->SetLinearVelocity(b2Vec2(0.0,1.0));
b2CircleShape shapecircle2;
shapecircle2.m_radius = 0.5f;
b2FixtureDef fdcircle2;
fdcircle2.shape = &shapecircle2;
fdcircle2.density = 20.0f;
circle2->CreateFixture(&fdcircle2);
}
-(void) draw
{
// Default GL states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY
// Needed states: GL_VERTEX_ARRAY,
// Unneeded states: GL_TEXTURE_2D, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY
glDisable(GL_TEXTURE_2D);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
world->DrawDebugData();
// restore default GL states
glEnable(GL_TEXTURE_2D);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
}
-(void) tick: (ccTime) dt
{
//It is recommended that a fixed time step is used with Box2D for stability
//of the simulation, however, we are using a variable time step here.
//You need to make an informed choice, the following URL is useful
//http://gafferongames.com/game-physics/fix-your-timestep/
int32 velocityIterations = 8;
int32 positionIterations = 1;
// Instruct the world to perform a single step of simulation. It is
// generally best to keep the time step and iterations fixed.
world->Step(dt, velocityIterations, positionIterations);
}
// on "dealloc" you need to release all your retained objects
- (void) dealloc
{
// in case you have something to dealloc, do it in this method
delete world;
world = NULL;
delete m_debugDraw;
// don't forget to call "super dealloc"
[super dealloc];
}
@end