上から下に投げる box2d オブジェクトがあり、その速度を一定に設定しましたが、実行すると、そのオブジェクトの速度が異なる場合があり、このオブジェクトをよりスムーズにするにはどうすればよいですか。
以下は、box2d ワールドと box2d ボディ オブジェクトをどのように作成したかを示すいくつかの方法です。
#pragma -mark Box2D World
-(void)createWorld
{
// Define the gravity vector.
b2Vec2 b_gravity;
b_gravity.Set(0.0f, -9.8f);
// Do we want to let bodies sleep?
// This will speed up the physics simulation
bool doSleep = true;
// Construct a world object, which will hold and simulate the rigid bodies.
world = new b2World(b_gravity);
world->SetAllowSleeping(doSleep);
world->SetContinuousPhysics(true);
}
-(void) createWeb
{
freeBodySprite = [CCSprite spriteWithFile:@"web1.png"];//web_ani_6_1
//freeBodySprite.position = ccp(100, 300);
[self addChild:freeBodySprite z:2 tag:6];
CGPoint startPos = CGPointMake(100, 320/1.25);
bodyDef.type = b2_staticBody;
bodyDef.position = [self toMeters:startPos];
bodyDef.userData = freeBodySprite;
float radiusInMeters = ((freeBodySprite.contentSize.width * freeBodySprite.scale/PTM_RATIO) * 0.5f);
shape.m_radius = radiusInMeters;
fixtureDef.shape = &shape;
fixtureDef.density = 0.07f;
fixtureDef.friction = 0.1f;
fixtureDef.restitution = 0.1f;
circularObstacleBody = world->CreateBody(&bodyDef);
stoneFixture = circularObstacleBody->CreateFixture(&fixtureDef);
freeBody = circularObstacleBody;
}
-(b2Vec2) toMeters:(CGPoint)point
{
return b2Vec2(point.x / PTM_RATIO, point.y / PTM_RATIO);
}
-(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;
}
-(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/
int32 velocityIterations = 8;
int32 positionIterations = 3;
// 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 world
for (b2Body* b = world->GetBodyList(); b; b = b->GetNext())
{
if (b->GetUserData() != NULL) {
//Synchronize the AtlasSprites position and rotation with the corresponding body
CCSprite *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)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
//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];
//CCLOG(@"Start -> %0.f || End -> %0.f",startPoint.x,location.x);
if (freeBody) {
//[self calcAngleAndRotateObjectStartingAtPoint:startPoint endingAtPoint:location];
self.isTouchEnabled = NO;
freeBody->SetType(b2_dynamicBody);
//this is the maximum force that can be applied
const CGFloat maxForce = 20;
//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;
//if (distance>maxForce)
distance = maxForce;
//else
// distance = 10;
//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;
}
}
これは私が投げるために使用しているコードですが、速度が速くなったり遅くなったりすることがあります.maxForce = 20を一定の速度に設定しています.