I am using box2d and cocos2d for my jump based game. I need to jump the character on platforms as they come.
Any ideas of how to do it using box2d ?
You try this:
//OBSTACLE_1:
{
CCSprite *sprite = [CCSprite spriteWithFile:#"hungObstacle1_C2H18.png"];
sprite.position = ccp(1568,704);
sprite.tag = 4;
[self addChild:sprite];
//SHAPE :
{
b2BodyDef bodyDefinition;
bodyDefinition.type = b2_dynamicBody;
bodyDefinition.position.Set(1568/PTM_RATIO, 704/PTM_RATIO);
bodyDefinition.userData = sprite;
body = world->CreateBody(&bodyDefinition);//body is a b2Body
// Create body shape
b2PolygonShape bodyShape;
//row 1, col 1
int num = 8;
b2Vec2 verts[] = {
b2Vec2(14.5f / PTM_RATIO, -27.0f / PTM_RATIO),
b2Vec2(19.5f / PTM_RATIO, -11.0f / PTM_RATIO),
b2Vec2(19.5f / PTM_RATIO, 11.0f / PTM_RATIO),
b2Vec2(16.5f / PTM_RATIO, 24.0f / PTM_RATIO),
b2Vec2(-14.5f / PTM_RATIO, 24.0f / PTM_RATIO),
b2Vec2(-19.5f / PTM_RATIO, 16.0f / PTM_RATIO),
b2Vec2(-19.5f / PTM_RATIO, -13.0f / PTM_RATIO),
b2Vec2(-12.5f / PTM_RATIO, -26.0f / PTM_RATIO)
};
bodyShape.Set(verts, num);
// Create shape definition and add to body
b2FixtureDef bodyFixtureDefinition;
bodyFixtureDefinition.shape = &bodyShape;
bodyFixtureDefinition.density = 5000.0f;
bodyFixtureDefinition.friction = 1.0f;
bodyFixtureDefinition.restitution = 1.0f;//*
fixture=body->CreateFixture(&bodyFixtureDefinition);
}
}
*NOTE:by setting restitution to 1 body will keep jumping all the time just need little force
To simulate jumping, you can use the cpBodyApplyImpulse method and apply a force in a straight up direction. Assuming you've got gravity enabled, this should provide an accuracte simulation, although you may need to tweak it. For example, here is a line from a recent project of mine.
cpBodyApplyImpulse(charBody, cpv(0.0, -25 * scale), charBody->p);
This is making the sprite represented by the charBody jump.
Related
i have a ball which is a box2d body and moves around the screen... i want to create multiple balls of similar type and they should also collide among them self..
the code i am using now is
ballcount = [[levelData objectForKey:#"ballcount"]intValue] ;
ballarray = [[NSMutableArray arrayWithCapacity:ballcount]init] ;
for (int j=0; j<ballcount; j++) {
ball = [CCSprite spriteWithFile:#"ball.png"];
[ballarray insertObject:ball atIndex:j];
[self createBallBoundingBox:(CCSprite *)[ballarray objectAtIndex:j]];
[[ballarray objectAtIndex:j]setPosition:ccp(arc4random() % 480 , arc4random() % 320)];
[self addChild:[ballarray objectAtIndex:j]];
}
There is only one sprite appearing on the screen when i run it ? any suggestions what am i doing wrong ... it works perfectly when only one ball is there
Thanks
ok i have got the above code to work but now i am having a problem with the movement in the tick method .. the box2d shapes are moving but the CCSprite shapes are not getting attached to the box2d bodies here is my code
world->Step(dt, 10, 10);
for(b2Body *b = world->GetBodyList(); b; b=b->GetNext()) {
if (b->GetUserData() != NULL) {
CCSprite *sprite = (CCSprite *)b->GetUserData();
if ([sprite isKindOfClass:[Ball class]])
{
b2Vec2 Vel = b->GetLinearVelocity();
float32 angle = atan2(Vel.y, Vel.x);
angle += -M_PI/2;
b->SetTransform(b->GetPosition(),angle);
sprite.position = ccp(b->GetPosition().x * PTM_RATIO,
b->GetPosition().y * PTM_RATIO);
sprite.rotation = -1 * CC_RADIANS_TO_DEGREES(b->GetAngle());
}
Ok guys here is my createBoundingBox definition
-(void)createBallBoundingBox:(Ball *)ballSprite{
b2BodyDef BallBodyDef;
ballBodyDef.type = b2_dynamicBody;
ballBodyDef.position.Set(ballSprite.position.x/PTM_RATIO, ballSprite.position.y/PTM_RATIO);
ballBodyDef.userData = ballSprite;
ballBody = world->CreateBody(&ballBodyDef);
/// test circle shape on ballbody
b2CircleShape BallCircleShape;
BallCircleShape.m_radius = 10/PTM_RATIO;
// Create shape
/*
b2PolygonShape ballShape;
int num = 7;
b2Vec2 verts[] = {
b2Vec2(0.0f / PTM_RATIO, 19.2f / PTM_RATIO),
b2Vec2(-10.7f / PTM_RATIO, 15.2f / PTM_RATIO),
b2Vec2(-6.7f / PTM_RATIO, -3.2f / PTM_RATIO),
b2Vec2(-1.7f / PTM_RATIO, -18.0f / PTM_RATIO),
b2Vec2(7.7f / PTM_RATIO, 0.5f / PTM_RATIO),
b2Vec2(10.5f / PTM_RATIO, 14.7f / PTM_RATIO),
b2Vec2(0.2f / PTM_RATIO, 19.0f / PTM_RATIO)
};
ballShape.Set(verts,num);
*/
// Create shape definition and add to body
b2FixtureDef ballFixtureDef;
ballFixtureDef.shape = &ballCircleShape;
ballFixtureDef.density = 1.0f;
ballFixtureDef.friction = 0.0f;
ballFixtureDef.restitution = 1.0f;
ballFixture = ballBody->CreateFixture(&ballFixtureDef);
b2Vec2 direction(5,2);
direction.Normalize();
float force = 1.0f;
b2Vec2 position = ballBody->GetPosition();
//Apply linear velocity
ballBody->ApplyLinearImpulse(force*direction,ballBody->GetPosition());
b2Vec2 Vel = ballBody->GetLinearVelocity();
float32 angle = atan2(Vel.y, Vel.x);
angle += -M_PI/2;
ballBody->SetTransform(ballBody->GetPosition(),angle);
}
any ideas ? Let me know
Thanks a lot guys
inside your method
[self createBallBoundingBox:(CCSprite *)[ballarray objectAtIndex:j]];
//OR NOW
[self createMiceBoundingBox:tempmice];
did you forgot to attach the Ball as UserData to your b2Body
- (void) createMiceBoundingBox: (Ball*) ball
{
//...
b2Body body = ...
body.SetUserData(ball);
//..
}
if not show us the code of the method
EDIT: if you use Mice instead of Ball make sure you update tick method to
if ([sprite isKindOfClass:[Mice class]])
float mcount=0;
mcount += 0.3;
CGAffineTransform transform = CGAffineTransformMakeRotation(mcount);
Clock.transform = transform;
i want GET Degree!
how to get rotation(degree) of this Object ? for exampke 90 degree.
i have Action Script 3 example :
myInt = clock_mc.rotation;
i need this method on Cocoa Touch
If I'm understanding your question correctly then a bit of mathematics can help here:
angleInRadians = angleInDegrees * M_PI / 180.0
To get the reverse, you reverse your equation. So first moving the division by 180 on the right to the left results in multiplying by 180.0
angleInRadians * 180.0 = angleInDegrees * M_PI
Now move the multiply by M_PI (the value of PI which is something like 3.1415962...) to the left, you reverse the operation:
(angleInRadians * 180.0) / M_PI = angleInDegrees
Now to make it nice for the program to use, we write it like so:
angleInDegrees = (angleInRadians * 180.0) / M_PI
So in your program, you could write your code like this:
var angleInDegrees = 0;
...
angleInDegrees = mcount * 180.0 / M_PI;
If you want to use a function then:
-(float) getAngleInDegrees:(float) radians
{
float angleInDegrees = 0;
angleInDegrees = radians * 180.0 / M_PI;
return angleInDegrees;
}
I think you want how to convert degrees into radians:-
for this you can use this formula:-
static inline double radians (double degrees) { return degrees * M_PI/180; }
UPDATED!
Do you want to get result rotation angle of Clock object?! If so, use this:
double rotationInRadians = atan2(Clock.transform.b, Clock.transform.a);
int rotationInDegrees = (int)round(rotationInRadians * 180 / M_PI);
Read this for details & explanation.
I'm having a heck of a time calculating points on a circle in Objective-C. Even after reading TONS of other code samples my circle is still way off center. (And that's taking into consideration "center" vs "origin" and adjusting for the size of the UIView, in this case a UIButton.)
Here's the code I'm using. The circle is formed correctly, it's just off center. I'm not sure if this is a radians vs degrees problem or something else. This is a helper function in a ViewController that programmatically creates the UIButtons and adds them to the view:
- (CGPoint)pointOnCircle:(int)thisPoint withTotalPointCount:(int)totalPoints {
CGPoint centerPoint = CGPointMake(self.view.frame.size.width / 2, self.view.frame.size.height / 2);
float radius = 100.0;
float angle = ( 2 * M_PI / (float)totalPoints ) * (float)thisPoint;
CGPoint newPoint;
newPoint.x = (centerPoint.x / 2) + (radius * cosf(angle));
newPoint.y = (centerPoint.y / 2) + (radius * sinf(angle));
return newPoint;
}
Thanks for the help!
The center of your buttons (i.e. points on the circle) is
newPoint.x = (centerPoint.x) + (radius * cosf(angle)); // <= removed / 2
newPoint.y = (centerPoint.y) + (radius * sinf(angle)); // <= removed / 2
Please note that if you place buttons (i.e. rectangles) on these points you have to make sure that their center lies at this point (i.e. subtract buttonWidth/2 from newPoint.x and buttonHeight/2 from newPoint.y to get the top left corner).
Not sure why you divide by 2 a second time newPoint coordinates...
What about this:
newPoint.x = centerPoint.x + (radius * cosf(angle));
newPoint.y = centerPoint.y + (radius * sinf(angle));
return newPoint;
I am new in Box2D....
I have ball image in CCSprite. I want to move ball in whole screen using accelerometer...
tell me
How to use accelerometer in box2d??
Thanks...in advance
The standard cocos2d-box2d template file moves boxes using the accelerometer by applying gravity relative to the accelerometer value.
- (void)accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration
{
static float prevX=0, prevY=0;
//#define kFilterFactor 0.05f
#define kFilterFactor 1.0f // don't use filter. the code is here just as an example
float accelX = (float) acceleration.x * kFilterFactor + (1- kFilterFactor)*prevX;
float accelY = (float) acceleration.y * kFilterFactor + (1- kFilterFactor)*prevY;
prevX = accelX;
prevY = accelY;
// accelerometer values are in "Portrait" mode. Change them to Landscape left
// multiply the gravity by 10
b2Vec2 gravity( -accelY * 10, accelX * 10);
world->SetGravity( gravity );
}
You need to be more specific on what you want the ball to do dependent on how you move the phone. Your question is difficult to answer in its current form.
Get the accelerometer measurements and say Force = coefficient*measurements. The apply this force to your b2Body
Let your Ball Sprite having tag is 1.
Replace this code with your Accelerometer delegate,
I test it on device, its working.
and your ball will move with accelerometer.
-(void)accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration
{
#define kFilterFactor 0.75
accelerometer.updateInterval = 1.0f/60.0f;
static UIAccelerationValue rollingX = 0, rollingY = 0;
for (b2Body *b = world->GetBodyList(); b; b = b->GetNext())
{
if (b->GetUserData() != NULL)
{
CCSprite *sprite = (CCSprite*)b->GetUserData();
if (sprite.tag == 1) {
rollingX = (acceleration.x * kFilterFactor) + (rollingX * 0.25);
rollingY = (acceleration.y * kFilterFactor) + (rollingY * 0.25);
float accelX = rollingX;
float accelY = rollingY;
CGPoint moveNewPosition = sprite.position;
if (accelX > 0.1) {
moveNewPosition.y += 2;
} if (accelX < 0.1) {
moveNewPosition.y -= 2;
}
if (accelY > 0.1) {
moveNewPosition.x -= 2;
} if (accelY < -0.1) {
moveNewPosition.x += 2;
}
b->SetLinearVelocity(b2Vec2(2,2));
sprite.position = ccp(moveNewPosition.x , moveNewPosition.y );
sprite.rotation = -1 * CC_RADIANS_TO_DEGREES(b->GetAngle());
}
}
}
}
I hope it'll work.
I have an image which shows which way is north on a map. This image is updated by CoreLocation if a new heading is found. It is also placed at the correct position, I use the following code:
locateMeView.transform = CGAffineTransformMakeRotation(([CoreLocationController sharedInstance].heading - 45) * M_PI / 180);
CGRect frame = locateMeView.frame;
CGPoint pos = [MapClass vectorForLocation:[CoreLocationController sharedInstance].location mapCenter:curLocation zoom:curZoom];
frame.origin.x = (int)(self.view.bounds.size.width/2 + pos.x - frame.size.width / 2);
frame.origin.y = (int)(self.view.bounds.size.height/2 + pos.y - frame.size.height / 2);
frame.size.width = 24;
frame.size.height = 24;
locateMeView.frame = frame;
CoreLocationController is a class which stores the updates of the normal CoreLocation. The MapClass transforms lat/lng coordinates to x/y coordinates on my map. The position of the image is correct, but the rotation is causing strange effects. For 0 en M_PI the image is correct but between these the image is stretched as if it is also rotated around the z-axis and at M_PI/2 and 3 * M_PI/2, it disappears altogether. Can someone explain what is happening and what I am doing wrong?
I found out what was wrong (more or less anyway). When using the transform property you are not allowed (for whatever reason) to change the position by changing the frame, you have to use the center property. So the code in the end was:
CGPoint pos = [MapClass vectorForLocation:[CoreLocationController sharedInstance].location mapCenter:curLocation zoom:curZoom];
locateMeView.transform = CGAffineTransformMakeRotation(([CoreLocationController sharedInstance].heading - 45) * M_PI / 180);
locateMeView.center = CGPointMake(int)(self.view.bounds.size.width/2 + pos.x), (int)(self.view.bounds.size.height/2 + pos.y));
Hope that someone with the same problem will find my answer.
Another solution:
Set transform to identity
Change the frame
Set transform
In your situation it should be:
locateMeView.transform = CGAffineTransformIdentity;
CGRect frame = locateMeView.frame;
CGPoint pos = [MapClass vectorForLocation:[CoreLocationController sharedInstance].location mapCenter:curLocation zoom:curZoom];
frame.origin.x = (int)(self.view.bounds.size.width/2 + pos.x - frame.size.width / 2);
frame.origin.y = (int)(self.view.bounds.size.height/2 + pos.y - frame.size.height / 2);
frame.size.width = 24;
frame.size.height = 24;
locateMeView.frame = frame;
locateMeView.transform = CGAffineTransformMakeRotation(([CoreLocationController sharedInstance].heading - 45) * M_PI / 180);
Try setting the transform after the resizing? Order can matter with transforms.