-(id)init{// always call "super" init// Apple recommends to re-assign "self" with the "super" return valueif((self=[superinit])){// enable touchesself.isTouchEnabled=YES;// enable accelerometerself.isAccelerometerEnabled=YES;CGSizescreenSize=[CCDirectorsharedDirector].winSize;CCLOG(@"Screen width %0.2f screen height %0.2f",screenSize.width,screenSize.height);// Define the gravity vector.b2Vec2gravity;gravity.Set(0.0f,-10.0f);// Do we want to let bodies sleep?// This will speed up the physics simulationbooldoSleep=true;// Construct a world object, which will hold and simulate the rigid bodies.world=newb2World(gravity,doSleep);world->SetContinuousPhysics(true);// Debug Draw functionsm_debugDraw=newGLESDebugDraw(PTM_RATIO);world->SetDebugDraw(m_debugDraw);uint32flags=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.b2BodyDefgroundBodyDef;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.b2PolygonShapegroundBox;// bottomgroundBox.SetAsEdge(b2Vec2(0,0),b2Vec2(screenSize.width/PTM_RATIO,0));groundBody->CreateFixture(&groundBox,0);// topgroundBox.SetAsEdge(b2Vec2(0,screenSize.height/PTM_RATIO),b2Vec2(screenSize.width/PTM_RATIO,screenSize.height/PTM_RATIO));groundBody->CreateFixture(&groundBox,0);// leftgroundBox.SetAsEdge(b2Vec2(0,screenSize.height/PTM_RATIO),b2Vec2(0,0));groundBody->CreateFixture(&groundBox,0);// rightgroundBox.SetAsEdge(b2Vec2(screenSize.width/PTM_RATIO,screenSize.height/PTM_RATIO),b2Vec2(screenSize.width/PTM_RATIO,0));groundBody->CreateFixture(&groundBox,0);//Set up spriteCCSpriteBatchNode*batch=[CCSpriteBatchNodebatchNodeWithFile:@"blocks.png"capacity:150];[selfaddChild:batchz:0tag:kTagBatchNode];[selfaddNewSpriteWithCoords:ccp(screenSize.width/2,screenSize.height/2)];CCLabelTTF*label=[CCLabelTTFlabelWithString:@"Tap screen"fontName:@"Marker Felt"fontSize:32];[selfaddChild:labelz:0];[labelsetColor:ccc3(0,0,255)];label.position=ccp(screenSize.width/2,screenSize.height-50);[selfschedule:@selector(tick:)];}returnself;}
-(void)addNewSpriteWithCoords:(CGPoint)p{CCLOG(@"Add sprite %0.2f x %02.f",p.x,p.y);CCSpriteBatchNode*batch=(CCSpriteBatchNode*)[selfgetChildByTag:kTagBatchNode];//We have a 64x64 sprite sheet with 4 different 32x32 images. The following code is//just randomly picking one of the imagesintidx=(CCRANDOM_0_1()>.5?0:1);intidy=(CCRANDOM_0_1()>.5?0:1);CCSprite*sprite=[CCSpritespriteWithBatchNode:batchrect:CGRectMake(32*idx,32*idy,32,32)];[batchaddChild:sprite];sprite.position=ccp(p.x,p.y);// Define the dynamic body.//Set up a 1m squared box in the physics worldb2BodyDefbodyDef;bodyDef.type=b2_dynamicBody;bodyDef.position.Set(p.x/PTM_RATIO,p.y/PTM_RATIO);bodyDef.userData=sprite;b2Body*body=world->CreateBody(&bodyDef);// Define another box shape for our dynamic body.b2PolygonShapedynamicBox;dynamicBox.SetAsBox(.5f,.5f);//These are mid points for our 1m box// Define the dynamic body fixture.b2FixtureDeffixtureDef;fixtureDef.shape=&dynamicBox;fixtureDef.density=1.0f;fixtureDef.friction=0.3f;body->CreateFixture(&fixtureDef);}
-(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/int32velocityIterations=8;int32positionIterations=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);//Iterate over the bodies in the physics worldfor(b2Body*b=world->GetBodyList();b;b=b->GetNext()){if(b->GetUserData()!=NULL){//Synchronize the AtlasSprites position and rotation with the corresponding bodyCCSprite*myActor=(CCSprite*)b->GetUserData();myActor.position=CGPointMake(b->GetPosition().x*PTM_RATIO,b->GetPosition().y*PTM_RATIO);myActor.rotation=-1*CC_RADIANS_TO_DEGREES(b->GetAngle());}}}
-(void)ccTouchesMoved:(NSSet*)toucheswithEvent:(UIEvent*)event{for(UITouch*touchintouches){CGPointlocation=[touchlocationInView:touch.view];location=[[CCDirectorsharedDirector]convertToGL:location];location=[selfconvertToNodeSpace:location];b2Vec2b2Location=b2Vec2(location.x/PTM_RATIO,location.y/PTM_RATIO);if(mouseJoint){mouseJoint->SetTarget(b2Location);}}}-(void)ccTouchesEnded:(NSSet*)toucheswithEvent:(UIEvent*)event{//Add a new body/atlas sprite at the touched locationfor(UITouch*touchintouches){CGPointlocation=[touchlocationInView:[touchview]];location=[[CCDirectorsharedDirector]convertToGL:location];// [self addNewSpriteWithCoords: location];if(mouseJoint){world->DestroyJoint(mouseJoint);mouseJoint=NULL;}}}