@godel9提供了一个好的解决方案,但在我的测试中,对于预期之外的行为所给出的解释是不正确的。
根据SKPhysicsBody类的参考文献:
力量仅在单个模拟步骤(一帧)中应用。
回到SKScene Class Reference关于-update方法的部分:
只有当场景被呈现在视图中而且没有暂停时,它才会被调用一次。
因此,我们可以假设在SKScene的-update方法中调用-applyForce:不应该会导致问题。但是,观察到即使施加比重力大得多的向上力(400牛顿与9.81相比),力也没有超过重力。
我创建了一个测试项目,其中包含两个节点,一个自然下落,将affectedByGravity设置为TRUE,另一个使用相同预期的重力矢量(x方向为0牛顿,y方向为-9.81)调用-applyForce。然后,我计算了每个节点在一个时间步长内的速度差以及时间步长的长度。然后,我记录了加速度(速度变化/时间变化)。
这是我SKScene子类的一部分代码:
- (id)initWithSize:(CGSize)size
{
if (self = [super initWithSize:size])
{
self.backgroundColor = [UIColor purpleColor];
SKShapeNode *node = [[SKShapeNode alloc] init];
node.path = CGPathCreateWithEllipseInRect(CGRectMake(0, 0, 10, 10), nil);
node.name = @"n";
node.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:5];
node.position = CGPointMake(0, 450);
node.physicsBody.linearDamping = 0;
node.physicsBody.affectedByGravity = NO;
[self addChild:node];
node = [[SKShapeNode alloc] init];
node.path = CGPathCreateWithEllipseInRect(CGRectMake(0, 0, 10, 10), nil);
node.name = @"n2";
node.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:5];
node.position = CGPointMake(20, 450);
node.physicsBody.linearDamping = 0;
[self addChild:node];
}
return self;
}
- (void)update:(NSTimeInterval)currentTime
{
SKNode *node = [self childNodeWithName:@"n"];
SKNode *node2 = [self childNodeWithName:@"n2"];
CGFloat acc1 = (node.physicsBody.velocity.dy - self.previousVelocity) / (currentTime - self.previousTime);
CGFloat acc2 = (node2.physicsBody.velocity.dy - self.previousVelocity2) / (currentTime - self.previousTime);
[node2.physicsBody applyForce:CGVectorMake(0, node.physicsBody.mass * -150 * self.physicsWorld.gravity.dy)];
NSLog(@"x:%f, y:%f, acc1:%f, acc2:%f", node.position.x, node.position.y, acc1, acc2);
self.previousVelocity = node.physicsBody.velocity.dy;
self.previousTime = currentTime;
self.previousVelocity2 = node2.physicsBody.velocity.dy;
}
结果很不寻常。在模拟中受到重力影响的节点加速度与手动施加力的节点相比,其加速度始终乘以150倍。我已尝试使用不同大小和密度的节点进行实验,但是相同的标量乘数存在。
由此我必须推断出SpriteKit内部具有默认的“像素对米”比率。也就是说,每个“米”等于正好150个像素。这有时很有用,否则场景通常太大,意味着力反应缓慢(想象一下从地面观看飞机,它行驶得非常快,但似乎移动得很慢)。
Sprite Kit文档经常建议不要进行精确的物理计算(在“Fudging the Numbers”一节中特别提到),但这种不一致性让我花了很长时间才找到。希望这可以帮助你!
restitution
属性控制节点的“弹性”。 - Matt