RSS

Tag Archives: motion

Using swipe to flick a body

A few days back, a reader ( Chris ) wanted to know how to flick a body using a swipe. So i created a sample for him that uses swipe variables to flick the body in the given direction. Frist we will have to determine the body that is being flicked:

-(b2Body *) getBodyAtLocation:(b2Vec2) aLocation {
for (b2Body* b = world->GetBodyList(); b; b = b->GetNext())
{
b2Fixture* bodyFixture = b->GetFixtureList();
if (bodyFixture->TestPoint(aLocation)){
return b;
}
}
return NULL;
}

This function will fetch the body that is under the tap location. Note that the function take b2World coordinates. To convert the Cocos2d Coordinates to box2d coordinates, use this function:

-(b2Vec2) toMeters:(CGPoint)point
{
return b2Vec2(point.x / PTM_RATIO, point.y / PTM_RATIO);
}

Now, using the two functions above, we write out ccTouchesBegan function:

- (void) ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
startPoint = [[CCDirector sharedDirector] convertToGL:[[touches anyObject] locationInView:[[touches anyObject] view]]];
freeBody = [self getBodyAtLocation:[self toMeters:startPoint]];
}

Once we have the body reference in the freeBody variable, we will access it in ccTouchesEnded function:

- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
if (freeBody) {
//this is the maximum force that can be applied
const CGFloat maxForce = 1000;

//get the location of the end point of the swipe
UITouch *myTouch = [touches anyObject];
CGPoint location = [myTouch locationInView:[myTouch view]];
location = [[CCDirector sharedDirector] convertToGL:location];

//get the rotation b/w the start point and the end point
CGFloat rotAngle = atan2f(location.y - startPoint.y,location.x - startPoint.x);

//the distance of the swipe if the force
CGFloat distance = ccpDistance(startPoint, location) * 0.5;

//put a cap on the force, too much of it will break the rope
if (distance>maxForce) distance = maxForce;

//apply force
freeBody->ApplyForce(b2Vec2(cosf(rotAngle) * distance, sinf(rotAngle) * distance), freeBody->GetPosition());

//lose the weak reference to the body for next time usage.
freeBody = nil;
}
}

The distance of the swipe is converted to the force of the swipe and the angle is determined from the start and end point of the swipe. Here is a link to the source files

Picture shows the origina position of the object at the start of the swipe and the resultant motion because of the flicking

 
Leave a comment

Posted by on April 1, 2012 in Box2d, cocos2d, Objective C, Xcode

 

Tags: , , , , , , , , , ,

 
Follow

Get every new post delivered to your Inbox.

Join 47 other followers

%d bloggers like this: