1

I use the code listed below as an experiment of SpriteKit. What I do is applying the same amount of force as a gravity effects to it but with anti-parallel vector (mass of body is set to 1.0). The function is executed on each frame via update function. I expect the object not to move at all as applyForce and gravity compensate each other.

-(void)didMoveToView:(SKView *)view {

  self.anchorPoint = CGPointMake(0.5, 0.5);

  SKShapeNode *node = [SKShapeNode shapeNodeWithRect:CGRectMake(0,0,WIDTH, HEIGHT)];
  node.position = CGPointMake(30, 280);
  node.strokeColor = [SKColor whiteColor];
  node.fillColor = [SKColor purpleColor];
  node.name = @"node";

  CGSize sz = node.frame.size;
  node.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:sz center:[GameScene Center]];
  node.physicsBody.restitution = 0.3;
  node.physicsBody.mass = 1.0;
  node.physicsBody.affectedByGravity = YES;

  self.figure = node;

  [self addChild:node];

  self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];
}


-(void)update:(CFTimeInterval)currentTime {

  [self.figure.physicsBody applyForce:CGVectorMake(
                                                 - self.physicsWorld.gravity.dx,
                                                 - self.physicsWorld.gravity.dy)];

However, the object falls down like it's effected by gravity only. I've checked the mass with a log it's always exactly 1.0

After some experiments, I've found out there is some magic number about it. It is 150. If use next update method the object is rested:

-(void)update:(CFTimeInterval)currentTime {

[self.figure.physicsBody applyForce:CGVectorMake(
                                                 - self.physicsWorld.gravity.dx,
                                                 -150 * self.physicsWorld.gravity.dy)];

And, another moment here, the mass is automatically calculated to be 1.0 if the body has dimensions 150*150. Anyway that wouldn't help. The behavior is same as we directly set the mass equal one.

If anyone knows what's going on here, please help!

Andrey Lyubimov
  • 663
  • 6
  • 22

2 Answers2

2

Let's say, there is 150 to 1 ratio of points to meters in SpriteKit. If we create a body of size 150*150 then the mass would be exactly one. Ok, that's good, we have a body of mass equals 1.0, we don't change it ourselves. BUT, next we again apply the force opposite to gravity and with the same magnitude. In this case the body will fall again. No good.

Alright, 150 / 1 is point-to-meter, and we need to multiply the force by 150 to balance the forces. We might start thinking "Hmm, there must be some clue in it". May be the gravity vector (0, -9.8) affects not kilos not meters but points! Alright then, let us have body of 150*150 points. To balance the forces we'll need (theoretically):

on one hand the force of gravity: 9.8 Newtons (kilo * meter) / sec ^ 2)

on another hand we applyForce: (1.0 kilo) * 9.8 * (150 points) / (sec^2)

So, here we miss the 150. Anyway,this seems to be little bit stupid, but applyForce is measured in ((points * kilo) / sec ^ 2), but the gravity acceleration is in Newtons ((kilo * meter)/ sec ^ 2) (despite the fact it's described as meters per second in documentation. Meters per second! Acceleration!). Multiply it by mass and get the force.

Knight0fDragon
  • 16,609
  • 2
  • 23
  • 44
Andrey Lyubimov
  • 663
  • 6
  • 22
  • 1
    I think it might be the other way around. applyForce is with pixels and gravity in meters. To get the applyForce: value you are multiplying by the pixel over meter ratio (150) so 150(pixel) / meter * (meter / sec^2) = 150 *pixel / sec^2 = applyForce value – MaxKargin Aug 07 '15 at 13:56
  • @M321K yes, perhaps you're right. In these terms gravity is more powerful, so it's acceleration needs to be greater. However, there are bad documentations given by Apple and applyForce: is not in Newtons (meter/sec^2) – Andrey Lyubimov Aug 07 '15 at 15:17
  • This is not bad documentation, this is a bug, report it to apple since it is still this way. – Knight0fDragon Jan 26 '17 at 15:38
1

You found the magic number :D

150 is the "pixel-to-meter" ratio in Sprite-kit. A particularly good explanation can be found here: look at the second answer by mitchellallison. When you access the gravity vector in your update: method you have keep this ratio in mind.

Community
  • 1
  • 1
MaxKargin
  • 1,560
  • 11
  • 13
  • I understand that. Logically, it should be used in node's area calculation only. But we don't care about the pixels and meters in case if set the body's mass to 1.0. The gravity is said to be meter / sec^2, applyForce is in Newtons - kilo * meter / sec^2. So, in case mass equals one the forces should coincide. They MUST coincide – Andrey Lyubimov Aug 07 '15 at 01:05
  • Yeah I know what you mean, thats what I thought as well. It turns out the documentation is a little off. – MaxKargin Aug 07 '15 at 13:50