我知道 Box2d 世界中快速移动的物体会引起隧道效应并相互穿过。解决方案是将实体定义为子弹。我这样做了,但身体有时仍然相互交叉,特别是如果遇到点不完全朝向中间并且身体在交叉时部分重叠。有什么解决办法吗?
这就是我制作所有身体的方式:
redBall = [CCSprite spriteWithFile:@"red-ball" rect:CGRectMake(0, 0, 34, 34)];
redBall.tag = 1;
[self addChild:redBall];
ballBodyDef.type = b2_dynamicBody;
ballBodyDef.position.Set((winSize.width/2)/PTM_RATIO, redBall.position.y/PTM_RATIO);
ballBodyDef.userData = redBall;
ballBodyDef.bullet = true;
_ballBody = _world->CreateBody(&ballBodyDef);
// Create circle shape
b2CircleShape circle;
circle.m_radius = 17.0/PTM_RATIO;
// Create shape definition and add to body
b2FixtureDef ballShapeDef;
ballShapeDef.shape = &circle;
ballShapeDef.density = 0.2f;
ballShapeDef.friction = 0.0f;
ballShapeDef.restitution = 1.0f;
_ballFixture = _ballBody->CreateFixture(&ballShapeDef);
我在 TouchesEnd 中将这个球移动为:
- (void) ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *myTouch = [touches anyObject];
CGPoint location = [myTouch locationInView:[myTouch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
CGPoint shootVector = ccpSub(location, striker.position);
CGFloat shootAngle = ccpToAngle(shootVector);
CGPoint normalizeShootVector = ccpNormalize(shootVector);
float x1 = - cos(shootAngle);
float y1 = - sin(shootAngle);
int power = 0;
float dist =ccpDistance(location, redBall.position);
if (dist >= 200)
power = 20;
else if (dist >= 100)
power = 10;
else if (dist >=75)
power = 7;
else if (dist >= 60)
power = 4;
else if (dist >= 50)
power = 3;
else if (dist >= 35)
power = 2;
else
power = 1;
b2Vec2 force = b2Vec2(x1*power, y1*power);
_ballBody->ApplyLinearImpulse(force,ballBodyDef.position);
}
就是简单地计算触球点到球的距离,根据距离找到对球施加的力量,然后将球向触球方向移动。这个球与任何其他进入它的球相撞。