Масштабирование объектов с физическими суставами в Sprite-Kit
У меня есть персонаж в сцене спрайтекита, который я хотел бы масштабировать, когда он получает определенное повышение.
Простой пример, где я мог бы увеличить / уменьшить:
hero.run (SKAction.repeatForever(
SKAction.sequence([
SKAction.scale(to: 1.5, duration: 1),
SKAction.scale(to: 1, duration: 1)
])
))
Пока все достаточно просто. Проблема в том, что масштабирование выглядит ужасно, потому что у героя есть части тела, которые прикреплены к суставам. Мне кажется, что физические узлы для деталей правильно масштабируются, а суставы - нет.
Вот пример быстрой игровой площадки, которая иллюстрирует проблему. Он просто добавляет несколько цветовых узлов в грубую форму автомобиля. Я добавил соединения к переднему колесу и бамперу, но не заднему колесу.
import SpriteKit
import PlaygroundSupport
let sceneView = SKView(frame: CGRect(x: 0, y: 0, width: 640,
height: 480))
let scene = SKScene(size: CGSize(width: 160, height: 120))
sceneView.showsFPS = true
sceneView.showsPhysics = true
sceneView.presentScene(scene)
PlaygroundPage.current.needsIndefiniteExecution = true
PlaygroundPage.current.liveView = sceneView
scene.physicsWorld.gravity = CGVector(dx:0,dy:0)
let body = SKSpriteNode(color: UIColor.red, size: CGSize(width:70,height:15))
body.position = CGPoint(x:scene.size.width/2,y:scene.size.height/2)
scene.addChild(body)
let front = SKSpriteNode(color:UIColor.blue, size: CGSize(width:10,height:10))
front.position = CGPoint(x:-25,y:-12.5)
body.addChild(front)
let rear = SKSpriteNode(color:UIColor.blue, size: CGSize(width:10,height:10))
rear.position = CGPoint(x:25,y:-12.5)
body.addChild(rear)
let bumper = SKSpriteNode(color:UIColor.brown, size: CGSize(width:5,height:5))
bumper.anchorPoint = CGPoint(x:0,y:0)
bumper.position = CGPoint(x:35,y:-7.5)
body.addChild(bumper)
body.physicsBody = SKPhysicsBody(rectangleOf:body.size)
front.physicsBody = SKPhysicsBody(rectangleOf:front.size)
bumper.physicsBody = SKPhysicsBody(rectangleOf:bumper.size, center:CGPoint(x:2.5,y:2.5))
let axel = SKPhysicsJointPin.joint(withBodyA:body.physicsBody!, bodyB:front.physicsBody!, anchor: body.convert(front.position, to: scene))
scene.physicsWorld.add(axel)
let bodyJoint = SKPhysicsJointFixed.joint(withBodyA: body.physicsBody!, bodyB: bumper.physicsBody!, anchor: body.convert(bumper.position, to:scene))
scene.physicsWorld.add(bodyJoint)
body.run (SKAction.repeatForever(
SKAction.sequence([
SKAction.scale(to: 1.5, duration: 3),
SKAction.scale(to: 1, duration: 3)
])
))
Предварительно масштабированный вывод:
Масштабированный вывод:
Вы можете видеть, что все узлы правильно масштабируются. Только заднее колесо без шарнира поддерживает правильное положение в автомобиле. Положение суставов бампера и переднего колеса не изменяется при масштабировании узла, поэтому, когда узлы становятся больше, они искажают форму композита.
У кого-нибудь есть способ обойти это? Я экспериментировал с различными решениями, такими как, возможно, добавление скрытых дочерних узлов или другие подобные хаки / обходные пути, но на самом деле ничто не мешает. Лучшее, что у меня есть, это то, что если вы измените точку привязки двух узлов в соответствии с тем местом, в котором вы хотите, чтобы суставы происходили, а затем поместили соединение точно на якорь, то вы можете затем масштабировать узлы и получить надлежащий эффект, поскольку узлы масштабировать вокруг их соответствующих опорных точек. Проблема в том, что это работает только тогда, когда есть только одно соединение на узел. В случае выше, где, например, есть два колеса, я не могу придумать.