@godel9 有一个很好的建议解决方案,尽管在我自己的测试中,对意外行为的解释是不正确的。
从SKPhysicsBody 类参考:
该力应用于单个模拟步骤(一帧)。
参考SKScene 类参考中关于 -update 方法的部分:
...它每帧只调用一次,只要场景在视图中呈现并且没有暂停。
所以我们可以假设在 SKScene 的 -update 方法中调用 -applyForce: 不会导致问题。但正如所观察到的,尽管施加的向上力远大于重力(400 牛顿对 9.81),但该力并未超过重力。
我创建了一个测试项目,该项目将创建两个节点,一个自然下落,将affectedByGravity 设置为TRUE,另一个调用-applyForce,具有相同的预期重力矢量(x 方向为0 牛顿,y 方向为-9.81)。然后我计算了一个时间步中每个节点的速度差异,以及时间步长。然后,我记录了加速度(速度变化/时间变化)。
这是我的 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 文档经常建议不建议进行精确的物理计算(具体见“捏造数字”部分),但这种不一致让我花了很长时间才确定。希望这可以帮助!