Похоже, это работа для SupermSKConstraint
. Ограничения оцениваются и применяются после запуска физической симуляции для каждого кадра, поэтому их можно использовать для таких задач, как направление узла в определенном направлении независимо от того, что с ним делает физика. Для этого вам понадобится ограничение zRotation
.
Но это еще не все. Если вы установите ограничение на нулевое вращение мяча:
// Swift
let constraint = SKConstraint.zRotation(SKRange(constantValue: 0))
ball.constraints = [constraint]
Вы обнаружите, что SpriteKit сбрасывает преобразование физического тела в каждом кадре из-за ограничения, так что он ведет себя только как будто катится. Вероятно, это не то, что вы хотите. (Чтобы лучше понять, что здесь происходит, попробуйте добавить ограничение нулевого поворота к прямоугольному физическому телу в мире без гравитации, применить к нему угловой импульс и посмотреть, как оно попытается вращаться в представлении с включенным showsPhysics
. Вы увидите, как спрайт и его физическое тело рассинхронизируются и немного трясутся — вероятно, из-за накопленных ошибок округления, когда физический движок и движок ограничений борются друг с другом.)
Вместо этого вы можете сделать что-то из того, что указано в ответе 0x141E, но использовать ограничения, чтобы уменьшить количество кода (и работать более эффективно):
- Придайте шаровому узлу круглое физическое тело. (И, возможно, без текстуры, если единственное изображение, которое вам нужно для шара, — это невращающийся спрайт.)
- Добавьте узел стрелки в качестве дочернего элемента узла шара. (Ему не нужно собственное физическое тело.)
- Наложите на стрелку ограничение нулевого поворота.
Подождите, это не работает — я сказал стрелке не вращаться, но она все еще вращается?! Помните, что дочерние узлы позиционируются (а также поворачиваются и масштабируются) относительно своего родительского узла. Так что не стрелка крутится относительно мяча, а мяч крутится. Не волнуйтесь, вы все равно можете решить это с ограничением:
- Укажите ограничение, чтобы оно работало относительно узла, содержащего мяч (вероятно, сцены).
Теперь ограничение будет удерживать стрелку на месте, позволяя мячу вращаться так, как этого требует симуляция физики.
Вот некоторый тестовый код для иллюстрации:
// Step 1: A rectangular spinner so we can see the rotation
// more easily than with a ball
let spinner = SKSpriteNode(color: SKColor.redColor(), size: CGSize(width: 300, height: 20))
spinner.position.x = scene.frame.midX
spinner.position.y = scene.frame.midY
spinner.physicsBody = SKPhysicsBody(rectangleOfSize: spinner.size)
scene.addChild(spinner)
spinner.physicsBody?.applyAngularImpulse(0.1) // wheeeeee
// Step 2: Make the arrow a child of the spinner
let arrow = SKSpriteNode(color: SKColor.greenColor(), size: CGSize(width: 20, height: 50))
spinner.addChild(arrow)
// Step 3: Constrain the arrow's rotation...
let constraint = SKConstraint.zRotation(SKRange(constantValue: 0))
arrow.constraints = [constraint]
// Step 4: ...relative to the scene, instead of to its parent
constraint.referenceNode = scene
person
rickster
schedule
09.11.2014