2013-09-28 3 views
5

Я пытаюсь сделать простой вечно прыгающий мяч с новым комплектом спрайтов КСН 7. я установил силу тяжести:мяч с новым Sprite комплектом

scene.physicsWorld.gravity=CGVectorMake(0, -9); 

И для шарового тела я установил:

ball.physicsBody=[SKPhysicsBody bodyWithCircleOfRadius:17]; 
ball.physicsBody.mass=1; 
ball.physicsBody.restitution=1; 
ball.physicsBody.linearDamping=0; 
ball.physicsBody.angularDamping=0; 

Бал вот только SKSpriteNode. , но у меня есть одна проблема: каждый раз, когда она возвращается назад, ее позиция становится немного выше и выше. И через несколько минут мяч почти в верхней части экрана. Может ли кто-нибудь помочь в решении этой проблемы. Я просто хочу, чтобы мяч возвращался обратно в ту же позицию каждый раз (например, на середине экрана). Спасибо.

+0

Try делая вектор (0,9) вместо (0, -9) и скажите мне, что происходит – erdekhayser

+0

та же проблема, но мяч теперь отскакивает от верхней части экрана (например, если земля сверху) – Gabriel

+0

Это то, что я думал. Вы говорите, что каждый отскок, мяч отскакивает выше? – erdekhayser

ответ

15

Есть, вероятно, две проблемы в игре здесь:

  1. Два тела участвуют в столкновении, когда мяч отскакивает - мяч и петля края, что он отскакивает от. Чтобы не потерять энергию при столкновении, вы, вероятно, хотите получить нулевое трение и реституцию на обоих телах.

  2. Даже если вы это сделаете, многие физические двигатели (включая SpriteKit's) могут столкнуться с ситуациями, подобными этому, из-за floating point rounding errors. Я обнаружил, что, когда я хочу, чтобы тело сохраняло постоянную скорость после столкновения, лучше всего заставить его использовать обработчик didEndContact: или didSimulatePhysics, чтобы сбросить скорость движущегося тела, так что она идет той же скоростью, что и до столкновения (но в противоположном направлении).

Если вы просто шар подпрыгивая вверх и вниз, что сброс скорости легко: просто свести на нет вертикальной составляющей вектора скорости:

ball.physicsBody.velocity = CGVectorMake(0, -ball.physicsBody.velocity.dy); 

Если вы отскакивая наклонную поверхность , это немного сложнее: нормализовать вектор скорости (т. е. масштабировать его так, чтобы его величина составляла 1,0), чтобы получить направление после столкновения, а затем масштабировать его, чтобы сделать его необходимой скоростью. Когда я делаю что-то вектор математики, я хотел бы преобразовать векторы в GLKVector2, так что я могу использовать быстрые математические функции из рамок GLKit:

GLKVector2 velocity = GLKVector2Make(ball.physicsBody.velocity.dx, ball.physicsBody.velocity.dy); 
GLKVector2 direction = GLKVector2Normalize(velocity); 
GLKVector2 newVelocity = GLKVector2MultiplyScalar(direction, newSpeed); 
ball.physicsBody.velocity = CGVectorMake(newVelocity.x, newVelocity.y); 
+0

спасибо! Теперь я также думаю, что многие физические двигатели имеют одинаковую проблему из-за ошибок округления с плавающей запятой, как вы упомянули. – Gabriel

+0

Итак, в первый раз я попытался сделать ограничение на мяч в методе didSimulatePhysics, например, если мяч имеет y позицию выше 305, я изменил ее на 300, но я думаю, что это неправильный способ сделать. Поэтому я решил следить за вашими советами и просто повышать скорость движения мяча после столкновения до отрицательного, но с тем же значением, что и раньше, и он работает. – Gabriel

+0

На самом деле, для меня работала реституция, установленная на 1 на мяче и до 0 на весле. – Mariusz

0

это странно, но если я установить:

ball.physicsBody.linearDamping=0.02f; 

кажется, что мяч не изменить его высоту отскока.

+0

Если вы запустите его в течение длительного времени, посмотрите, замедляется ли он. Любое линейное демпфирование, вероятно, приведет к его замедлению. – erdekhayser

+0

Я знаю это, но он не теряет своей «энергии», я ждал долгое время, около 30-40 минут. – Gabriel

+0

Думаю, в этот момент это не имеет никакого значения? – erdekhayser