Мяч SpriteKit теряет всю энергию, ударяя стену, реституция = 1

Если я применяю импульс 1 в направлении y, мяч отскакивает назад и вперед, не теряя при этом никакой энергии. Однако, если начальный импульс равен 0,5 или ниже, мяч мгновенно теряет всю энергию, когда он попадает в стену. Почему это происходит? У меня довольно хорошее представление о свойствах класса SKPhysicsBody. Попробуйте этот код, чтобы узнать, не на вашем компьютере.

-(id)initWithSize:(CGSize)size {
if (self = [super initWithSize:size]) {
    /* Setup your scene here */
    self.physicsWorld.gravity = CGVectorMake(0.0f, 0.0f);
    SKPhysicsBody* borderBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];
    self.physicsBody = borderBody;
    self.physicsBody.friction = 0.0f;
    self.backgroundColor = [SKColor colorWithRed:0.7 green:0.7 blue:0.7 alpha:1.0];

    SKShapeNode *ball = [SKShapeNode node];
    CGMutablePathRef pathToDraw = CGPathCreateMutable();
    [ball setStrokeColor:[UIColor blackColor]];
    CGPathMoveToPoint(pathToDraw, NULL, 0, 0);
    CGPathAddEllipseInRect(pathToDraw, NULL, CGRectMake(-16, -16, 32, 32));
    ball.path = pathToDraw;

    ball.position = CGPointMake(size.width / 2, size.height / 2);
    ball.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:ball.frame.size.width/2];
    ball.physicsBody.friction = 0.0f;
    ball.physicsBody.restitution = 1.0f;
    ball.physicsBody.linearDamping = 0.0f;
    ball.physicsBody.allowsRotation = NO;

    [self addChild:ball];

    [ball.physicsBody applyImpulse:CGVectorMake(0, 0.5)];
}
return self;
}

Ответ 1

Когда скорость столкновения достаточно мала (например, ваш CGVector of (0, 0.5)), Box2d, лежащий в основе физического движка Sprite Kit, вычислит столкновение как неупругое (т.е. как если бы restitution равнялось 0, удаляя любое оживление), а node не будет отскакивать.

Это означает, что в документации Box2d для предотвращения джиттера.

В исходном коде Box2d у вас даже есть эта строка:

/// A velocity threshold for elastic collisions. Any collision with a relative linear
/// velocity below this threshold will be treated as inelastic.
#define b2_velocityThreshold            

Ваш импульс должен быть выше этого порога для уважения реституции.