I have a question that is killing me...
I'm using LevelHelper to make a level in Box2d. So I have a triangular sprite attached to a triangular body.
Now the problem is that I want to rotate that body to a position, and rotate the attached sprite too.
Here you have some code:
//Detecting my actor and my sprite
if (b->GetType() == b2_dynamicBody && myActor == [loader spriteWithUniqueName:#"radar."]){
radar = b;
radarSprite = myActor;
}
Just wanted to try with 20 degrees, but it's not rotating.
//trying to rotate inside TICK: Method
float32 b2Angle = -1 * CC_DEGREES_TO_RADIANS(20);
radar->SetTransform(radar->GetPosition(), b2Angle);
radarSprite.position = ccp(radar->GetPosition().x,radar->GetPosition().y);
Any tips?
Thank you very much in advance!!
you have an error, you rotate only the physic body, levelhelper have a method in the LHSprite called tranformRotation, so you need do this:
this method rotate the body and the sprite (if the body attach to sprite):
//radarSprite is a LHSprite
float32 b2Angle = -1 * CC_DEGREES_TO_RADIANS(20);
[radarSprite transformRotation:b2Angle];
[radarSprite transformPosition:ccp(radar->GetPosition().x,radar->GetPosition().y)];
if you have the body separate from sprite you can do this:
//radarSprite is a LHSprite
float32 b2Angle = -1 * CC_DEGREES_TO_RADIANS(20);
radar->SetTransform(radar->GetPosition(), b2Angle);
[radarSprite transformRotation:b2Angle];
[radarSprite transformPosition:ccp(radar->GetPosition().x,radar->GetPosition().y)];
EDIT:
the method spriteWithUniqueName return a LHSprite, but if you use CCSprite you can do this:
//radarSprite is a CCSprite
float32 b2Angle = -1 * CC_DEGREES_TO_RADIANS(20);
radar->SetTransform(radar->GetPosition(), b2Angle);
[radarSprite setRotation:b2Angle];
[radarSprite setPosition:ccp(radar->GetPosition().x,radar->GetPosition().y)];
Related
I have a box2d object that is being moved down the screen via gravity
int32 velocityIterations = 6;
int32 positionIterations = 2;
self.world->Step(dt, velocityIterations, positionIterations);
self.world->ClearForces();
for(b2Body *b = self.world->GetBodyList(); b; b=b->GetNext()) {
if (b->GetUserData() != NULL) {
id object = (id)b->GetUserData();
if([object isKindOfClass:[FallingObject class]])
{
CCSprite *sprite = (CCSprite *)b->GetUserData();
sprite.position = CGPointMake(b->GetPosition().x * PTM_RATIO, b->GetPosition().y * PTM_RATIO);
sprite.rotation = -1 * CC_RADIANS_TO_DEGREES(b->GetAngle());
}
}
}
When the user moves their finger across the screen either left or right i want to move the box2d object left or right while the object is still moving down the screen.
Can anyone suggest the best way to do this. I have tried applying linear velocity but it just seems to shoot of screen.
Any suggestions
Thanks
There some ways to do this, and you need to try the best for your case.
You can apply forces, impulse, or change the body velocity manually just for X parameter:
// x axis force
b2Vec2 xAxisForce = b2Vec2(10, 0);
// Try one of these
b->ApplyForce(xAxisForce, b->GetWorldCenter());
b->ApplyForceToCenter(xAxisForce);
b->ApplyLinearImpulse(xAxisForce, b->GetWorldCenter());
// Or change the body velocity manually
b->SetLinearVelocity(b2Vec2(10, b->GetLinearVelocity().y));
I'm trying to make a tank in cocos2d-x with box2d. Everything works fine but when i draw the tank, the barrel is in the middle as you can see in the picture.
To draw the tank i set the position to the center of the screen, after the tank body is drawn i want to draw the barrel and i give it the center of the screen + the same offset of the joint (the joint is on the right position).
Both anchor points, the tank and barrel are on (0.5, 0.5) and because i use the same offset as the joint i expected the barrel was drawn at the right place but it's not.
My code:
// Create sprite and add it to the layer
CCSprite *tank = CCSprite::create();
//tank->initWithFile("Tanks/001/tank.png");
tank->setPosition(pos);
tank->setTag(1);
this->addChild(tank);
// Create ball body
b2BodyDef tankBodyDef;
tankBodyDef.type = b2_dynamicBody;
tankBodyDef.position = toMeters(&pos);
tankBodyDef.userData = tank;
b2Body *tankBody = _world->CreateBody(&tankBodyDef);
// Create shape definition and add body
shapeCache->addFixturesToBody(tankBody, "001/tank");
// Create sprite and add it to the layer
CCSprite *barrel = CCSprite::create();
//barrel->initWithFile("Tanks/001/barrel.png");
barrel->setPosition(CCPointMake(pos.x + 77, pos.y+117));
barrel->setTag(2);
this->addChild(barrel);
// Create barrel body
barrelBodyDef.type = b2_dynamicBody;
barrelBodyDef.userData = barrel;
barrelBodyDef.position = b2Vec2(tankBodyDef.position.x + 2.40625, tankBodyDef.position.y + 3.65625); // = same offset as joint!?!?!
b2Body *barrelBody = _world->CreateBody(&barrelBodyDef);
// Create shape definition and add body
shapeCache->addFixturesToBody(barrelBody, "001/barrel");
// Create a joint
//
b2RevoluteJointDef armJointDef;
//armJointDef.Initialize(tankBody, barrelBody, b2Vec2(400.0f/PTM_RATIO, 450/PTM_RATIO));
armJointDef.bodyA = tankBody;
armJointDef.bodyB = barrelBody;
armJointDef.localAnchorA.Set(2.40625, 3.65625);
armJointDef.localAnchorB.Set(-2.90625, -0.125);
armJointDef.enableMotor = true;
armJointDef.enableLimit = true;
armJointDef.motorSpeed = 10;
armJointDef.referenceAngle = CC_DEGREES_TO_RADIANS(0); // begin graden
armJointDef.lowerAngle = CC_DEGREES_TO_RADIANS(-50); // max graden naar beneden
armJointDef.upperAngle = CC_DEGREES_TO_RADIANS(00); // max graden naar boven
armJointDef.maxMotorTorque = 48;
armJoint = (b2RevoluteJoint*)_world->CreateJoint(&armJointDef);
I hope somebody got an answer :)
Problem solved :), i had to add the offset of the barrel anchor too, now it's on the right position.
using cocos2d and box2d i am taking a body and put a sprite that follow him, now i would like to see not only the sprite but the whole world bodies shapes(boxs,and circles) to understand better my world physics.
the sprite follow a body with :
world->Step(dt,10,10);
for(b2Body *b=world->GetBodyList(); b; b=b->GetNext()) // b is the list of all bodys in the world and we running on them
{
if(b->GetUserData() !=NULL )
{
CCSprite *sprite=(CCSprite *) b->GetUserData();//every b of the world will be update his position
sprite.position=ccp( b->GetPosition().x * PTM_RATIO, b->GetPosition().y * PTM_RATIO ) ;
sprite.rotation=-1*CC_RADIANS_TO_DEGREES(b->GetAngle());
}
}
how would i do that? is it require a big code ?
thanks a lot.
Use b2DebugDraw. Here is the code how do it:
http://www.ccsprite.com/box2d/debugdraw-box2d-cocos2d.html
That will automatically draw your b2World.
Hi I have finally made a working joystick in cocos2d. I am able to rotate a sprite to the exact angle that the joystick thumb, or cap, is 'pointing'. However, I am unable to move the sprite in that same direction. Is there an easy way to move the sprite with the way I have the rotating code set up? Also is there a way to keep it moving if your thumb is still pressed, but not moving the joystick?. PS this code is all within the TouchesMoved method. PPS. the cap is the thumb, the pad is the joystick background, and the Sprite2 is the sprite that I want to move. (95, 95) is the center of the pad sprite.
if(capSprite.position.x>=padSprite.position.x){
id a3 = [CCFlipX actionWithFlipX:NO];
[sprite2 runAction:a3];
}
if(capSprite.position.x<=padSprite.position.x){
id a4 = [CCFlipX actionWithFlipX:YES];
[sprite2 runAction:a4];
}
CGPoint pos1 = ccp(95, 95);
CGPoint pos2 = ccp(capSprite.position.x, capSprite.position.y);
int offX = pos2.x-pos1.x;
int offY = pos2.y-pos1.y;
float angleRadians = atanf((float)offY/(float)offX);
float angleDegrees = CC_RADIANS_TO_DEGREES(angleRadians);
float theAngle = -1 * angleDegrees;
sprite2.rotation = theAngle;
I'm not familiar with cocos2d but I had a quick look at the documentation and this sample might be of use to you:
if keys[key.UP]:
self.target.acceleration = (200 * rotation_x, 200 * rotation_y)
I had written a long explanation answering your second question but I believe this "self.target.acceleration" solves that too. You can read more at the cocos2d API documentation.
What I generally do is get the angle, convert it to a CGPoint with ccpForAngle(float) and then multiply the CGPoint by a value:
float angle = whatever;
CGPoint anglePoint = ccpForAngle(angle);
// You will need to play with the mult value
angle = ccpMult(angle, 2.5);
// This also works with box2D or probably Chipmunk.
sprite.position = angle;
I have a working joystick in my cocos2d app but I cannot figure out how to make the 'player' shoot bullets out of it in the direction the joystick is pointing. I have the player moving and rotating. Also the bullets need to disappear when they hit the edges of the screen. Any help would be great. Thanks in advance.
You should get the angle from joystick.
For instance, SneakyInput has a degrees property which enables you to rotate your bullets like this :
_bullet.rotation = -joystick.degrees;
And your update method can be like this :
void update:(ccTime) delta
{
float moveAngle = _bullet.rotation;
CGPoint deltaPos = CGPointMake(cos(moveAngle) * velocity, sin(moveAngle) * velocity);
_bullet.position = ccpAdd(self.position, deltaPos);
}