Hi guys as the title suggest i want to move a box2d body the direction of motion .. can anyone give some clue how can i achieve this ? Thanks
right now i am using
b->SetLinearImpusle(force,direciton);
the body just rotates according to the collision
If you want just to apply an impulse in specified direction:
b2Vec2 direction(1, 0);
direction.Normalize();
float force = 10.0f;
b->ApplyLinearImpulse(force*direction, b->GetPosition());
the second parameter of ApplyLinearImpulse is the point where to apply the impulse
Related
I want to apply a velocity vector to a dynamic body in the cursor direction:
void Game::mousePressEvent(QMouseEvent *e){
double angle = atan2(realBall->GetPosition().y - e->pos().y(), realBall->GetPosition().x - e->pos().x());
realBall->SetLinearVelocity(b2Vec2(-cos(angle) * 50, -sin(angle) * 50));
}
But the dynamic body has an incorrect direction, so i think that the cursor position it's wrong.
Thank you for the help!
First, you must know that in order for your code to work, the coordinates of your screen and the coordinates of box2d must match. Be aware that if you use screen coordinates in pixels, it means that the size of one pixel matches an 1 meter in box2d. But let’s assume that you have already taken all this into account. Then I would not advise you to use trigonometry for calculations. So you can easily make a mistake. In this case, simple vector operations will be enough for you: substraction, scaling and normalizing a vector. You can try this: velocity = (cursor_position - real_ball_position).normalize().scale(50f). In box2d there is a b2Vec class for vector operations. You can read about it in detail in the documentation.
i'm losing myself in this...
Situation:
Working on a game in cocos2d with box2d and I have a ropejoint between one fixed body and one dynamic body.
When I drop the dynamic body is swings from left to right and then from right to left due to the gravity in the world.
The problem:
The swings are getting shorter and shorter till finally the dynamic body hangs still beneath the fixed body. This is normal behavior but I need it to keep swinging.
My thoughts:
I think I need to apply a tangential force to the ropejoint in the direction of the swinging but how to do this is a mystery for now :)
Try setting the damping factor of the rope joint to zero
ropeJointDef.dampingRatio = 0.0f;
Hope it helps!
Here is a little code that should help you with your little problem
bool YourClass::init(){
CCCallFunc *swingL = CCCallFunc::create(this,callfunc_selector(YourClass::swingLeft));
CCDelayTime *delay = CCDelayTime::create(5);
CCCallFunc *swingR = CCCallFunc::create(this, callfunc_selector(YourClass::swingRight));
this->runAction(CCRepeatForever::create(CCSequence::create(swingL,delay,swingR,NULL)));
}
void YourClass::swingLeft(){
b2Body *dynamicBody = get your body from b2world;
dynamicBody->SetLinearVelocity(b2Vec2(-10, 0));//set velocity of the swing
}
void YourClass::swingRight(){
b2Body *dynamicBody = get your body from b2world;
dynamicBody->SetLinearVelocity(b2Vec2(10, 0));//set velocity of the swing
}
I try to detect collision between two sprite.
if(CGRectIntersectsRect([SpriteA BoundingBox], [SpriteB boundingBox]))
But when i Rotate any sprite than collision detection is not perfect..
I know to use pixel perfect Collision but i have no idea about it.
Please anyone help me for how to detect collision, Give me any block of code if any.
You can use box2d to make it detect all collisions for you
In two ways you can do.
Use box2D body for your sprite. Example: CLICK HERE
Use CGMutablePathRef, and use CGPathContainsPoint() instead of CGRectIntersectsRect.
Example: CLICK HERE
You can also refere the Ray Wenderlich Tutorial for the detection of the Collision between any 2 Box2D bodies.
it's possible! try with CGPath.
I had the same problem. I've resolved with this tutorial: http://bobueland.com/cocos2d/2011/the-magic-of-cgpaths/
for rotate the path try this method, it rotated the path round the center of the boudingBox:
-(CGPathRef) rotateCGPath:(CGPathRef)path corner:(CGFloat)radians
{
CGRect bounds = CGPathGetBoundingBox(path);
CGPoint center = CGPointMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds));
CGAffineTransform transf = CGAffineTransformIdentity;
transf = CGAffineTransformTranslate(transf, center.x, center.y);
transf = CGAffineTransformRotate(transf, -radians);
transf = CGAffineTransformTranslate(transf, -center.x, -center.y);
return CGPathCreateCopyByTransformingPath(path, &transf);
}
after this you detect the collision simple with:
if (CGPathContainsPoint(Collisionpath, NULL, collisionPoint, NO))
{ //is inside the path }
good luck!
How can my sprite will jump and come back to original place??
I am using box2d physics engine in iphone apps.
I am using impulse but cant work properly.
Is any one know the logic or code than tell me.
-(void)jump
{
b2Vec2 pos=ballbody->GetPosition();
// float vel=ballbody->GetAngularVelocity();
double radian=atan2(pos.x+10, pos.y+10);
float angle=CC_RADIANS_TO_DEGREES(radian);
NSLog(#"Angle: %f",angle);
float impulseFactor = 1.0;
float force=ballbody->GetMass()*10;
//force/=6.0;
//b2Vec2 force=b2Vec2(0,50.0f);
// float apply=force*JUMP_IMPULSE*impulseFactor;
ballbody->ApplyLinearImpulse(b2Vec2(angle,force), ballbody->GetWorldCenter());
// [self applyLinearImpulse:b2Vec2(0,[self mass]*JUMP_IMPULSE*impulseFactor) point:[self worldCenter]];
}
Thanks
please check whether gravity has been set
if not set gravity upon the particular angle you have put the force.
third case is note down that position... get the current position... get angle.... set linear velocity to that angle.... keep on checking the position and as soon as it reaches that position set linear velocity zero..... (this sounds confusing but i didn't understood your problem fully so as much as i did understood i can help only this much)
Please refer to the video at
http://www.youtube.com/watch?v=_DyzwZJaDfM
The "brown" body is controlled with mouse and when mouse is pressed I calculate force using Hookes law (refereed to http://www.box2d.org/forum/viewtopic.php?f=4&t=116 ) and the "blue" body should attract to the "brown" body.
But as seen in the video,"blue" body keep orbiting around and doesn't come stop.What I wanted to implement is "elastic rope" like thing.
First I tried using DistanceJoint ,but I cannot give a static distance to the joint.
here is my implementation for hookes law -
-(void)applyHookesLaw:(b2Body*)bodyA:(b2Body*)bodyB:(float) k:(float) friction:(float)desiredDist
{
b2Vec2 pA=bodyA->GetPosition();
b2Vec2 pB=bodyB->GetPosition();
b2Vec2 diff=pB- pA;
b2Vec2 vA=bodyA->GetLinearVelocity();
b2Vec2 vB=bodyB->GetLinearVelocity();
b2Vec2 vdiff=vB-vA;
float dx=diff.Normalize();
float vrel=vdiff.x * diff.x + vdiff.y * diff.y;
float forceMag= -k*(dx-desiredDist);//-friction*vrel;
diff*=forceMag;
bodyA->ApplyForce(-1*diff,bodyB->GetPosition());
//bodyA->wakeUp()
}
Any tips please?
PS - gravity of the world is 0.0
Hooke's law when incorporated into Newton's Second law is a second order differential equation: m d^2 x/dt^2 = - k x, where x is is a vector. As Beta points out in the comments, you can just add friction. Absent a friction term, orbits like you observe are common, and they will continue indefinitely. The usual way add friction is to add a term that is proportional to velocity, and like the Hookean term (-k*x), it is also negative, i.e. it opposes the motion.
If I'm reading your code correctly, you already have something like that term in the comments following setting forceMag. But, I don't understand your calculation of vrel, it looks like the dot product between the relative velocity and the vector joining the two bodies. vdiff is already the correct form for this. Also, unlike the spring force, this force is directed along the relative velocity (vdiff). So, to implement it I'd change the line where you call ApplyForce on bodyA to
bodyA->ApplyForce(-1*diff - friction*vdiff,bodyB->GetPosition());