如何围绕关节旋转精灵

7
我需要让手臂和手围绕钩的中心旋转,如下图所示,而不会分离或改变形状(手臂和手之间的角度不变,只在A处旋转),如下图所示:

enter image description here

我尝试旋转手臂,但这使它们分离并改变形状。您可以查看下面的代码:

let hookCategoryName = "hook"
let leftArmCategoryName = "leftArm"
let rightArmCategoryName = "rightArm"
let leftHandCategoryName = "leftHand"
let rightHandCategoryName = "rightHand"

let hookCategory             : UInt32 = 0x1 << 0
let leftArmCategory            : UInt32 = 0x1 << 1
let rightArmCategory           : UInt32 = 0x1 << 2
let leftHandCategory           : UInt32 = 0x1 << 3
let rightHandCategory          : UInt32 = 0x1 << 4

extension Int {
  var degreesToRadians: Double { return Double(self) * .pi / 180 }
}
extension FloatingPoint {
  var degreesToRadians: Self { return self * .pi / 180 }
  var radiansToDegrees: Self { return self * 180 / .pi }
}

class GameScene: SKScene, SKPhysicsContactDelegate {

var hook = SKSpriteNode(imageNamed: "hook")
var leftArm = SKSpriteNode(imageNamed: "arm")
var rightArm = SKSpriteNode(imageNamed: "arm")
var leftHand = SKSpriteNode(imageNamed: "leftHand")
var rightHand = SKSpriteNode(imageNamed: "rightHand")

override func didMove(to view: SKView) {

    self.physicsWorld.gravity = CGVector(dx: 0, dy: 0)
    self.physicsWorld.contactDelegate = self

    var yellowBg = SKSpriteNode(imageNamed: "yellowBg")
    yellowBg.position = CGPoint(x: frame.midX, y: frame.midY)
    yellowBg.zPosition = 2
    addChild(yellowBg)

    hook.position = CGPoint(x: frame.midX, y: frame.midY + frame.midY/2)
    hook.zPosition = 5
    hook.name = hookCategoryName
    hook.physicsBody = SKPhysicsBody(rectangleOf: hook.frame.size)
    hook.physicsBody?.categoryBitMask = hookCategory
    hook.physicsBody?.isDynamic = false
    addChild(hook)

    rightArm.anchorPoint = CGPoint(x: 0.5, y: 1)
    rightArm.position = hook.position
    rightArm.zPosition = 5
    rightArm.name = rightArmCategoryName
    rightArm.physicsBody = SKPhysicsBody(rectangleOf: rightArm.frame.size)
    rightArm.physicsBody?.categoryBitMask = rightArmCategory

    rightArm.physicsBody!.isDynamic = true
    addChild(rightArm)

    leftArm.anchorPoint = CGPoint(x: 0.5, y: 1)
    leftArm.position = hook.position
    leftArm.zPosition = 5
    leftArm.name = leftArmCategoryName
    leftArm.physicsBody = SKPhysicsBody(rectangleOf: leftArm.frame.size)
    leftArm.physicsBody?.categoryBitMask = leftArmCategory
    leftArm.physicsBody!.isDynamic = true

    addChild(leftArm)

    // leftHand
    leftHand.anchorPoint = CGPoint(x: 0.5, y: 0.5)
    leftHand.position = CGPoint(x: leftArm.frame.minX - 22, y: leftArm.frame.minY + 7) //CGPoint(x: armLeft.position.x, y: armLeft.position.y)
    leftHand.zPosition = 5
    leftHand.name = leftHandCategoryName
    leftHand.physicsBody = SKPhysicsBody(rectangleOf: leftHand.frame.size)
    leftHand.physicsBody?.categoryBitMask = leftHandCategory

    leftHand.zRotation = CGFloat(Double(-30).degreesToRadians)//CGFloat(-Double.pi/6)
    //armLeft.physicsBody?.categoryBitMask = armCategory
    leftHand.physicsBody!.isDynamic = true

    addChild(leftHand)

    // rightHand
    rightHand.anchorPoint = CGPoint(x: 0.5, y: 0.5)
    rightHand.position = CGPoint(x: rightArm.frame.minX + 30, y: rightArm.frame.minY + 7) //CGPoint(x: armLeft.position.x, y: armLeft.position.y)
    rightHand.zPosition = 5
    rightHand.name = rightHandCategoryName

    rightHand.physicsBody = SKPhysicsBody(rectangleOf: rightHand.frame.size)
    rightHand.physicsBody?.categoryBitMask = rightHandCategory
    rightHand.zRotation = CGFloat(Double(30).degreesToRadians)//CGFloat(-Double.pi/6)
    //armLeft.physicsBody?.categoryBitMask = armCategory
    rightHand.physicsBody!.isDynamic = true

    addChild(rightHand)


    leftArm.zRotation = CGFloat(Double(-45).degreesToRadians)
    rightArm.zRotation = CGFloat(Double(45).degreesToRadians)

    rightHand.physicsBody?.contactTestBitMask = rightHandCategory
    leftHand.physicsBody?.contactTestBitMask = leftHandCategory
    rightHand.physicsBody?.collisionBitMask = rightHandCategory
    leftHand.physicsBody?.collisionBitMask = leftHandCategory


    let hookAndRightArmJoint = SKPhysicsJointPin.joint(withBodyA: hook.physicsBody!, bodyB: rightArm.physicsBody!, anchor: CGPoint(x: hook.position.x, y: self.rightArm.frame.maxY))
    self.physicsWorld.add(hookAndRightArmJoint)

    let hookAndLeftArmJoint = SKPhysicsJointPin.joint(withBodyA: hook.physicsBody!, bodyB: leftArm.physicsBody!, anchor: CGPoint(x: hook.position.x, y: self.leftArm.frame.maxY))
    self.physicsWorld.add(hookAndLeftArmJoint)


    let armsFixedJoint = SKPhysicsJointFixed.joint(withBodyA: leftArm.physicsBody!, bodyB: rightArm.physicsBody!, anchor: CGPoint.zero)
    self.physicsWorld.add(armsFixedJoint)

    //left arm and hand joint
    let leftArmAndHandJoint = SKPhysicsJointPin.joint(withBodyA: leftArm.physicsBody!, bodyB: leftHand.physicsBody!, anchor: CGPoint(x: self.leftArm.frame.minX, y: self.leftArm.frame.minY)/*CGPoint(x: armLeft.position.x, y: self.armLeft.frame.minY)*/)
    self.physicsWorld.add(leftArmAndHandJoint)

    //right arm and hand joint
    let rightArmAndHandJoint = SKPhysicsJointPin.joint(withBodyA: rightArm.physicsBody!, bodyB: rightHand.physicsBody!, anchor: CGPoint(x: self.rightArm.frame.maxX, y: self.rightArm.frame.minY)/*CGPoint(x: armLeft.position.x, y: self.armLeft.frame.minY)*/)
    self.physicsWorld.add(rightArmAndHandJoint)
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

    hook.run(SKAction.rotate(byAngle: CGFloat(Double(60).degreesToRadians), duration: 0.5))

}
}  

当运行上述代码时,如下图所示,旋转钩子对手臂和手部没有影响:

enter image description here

如何获得图像中的旋转角度?
1个回答

0
你可以将手臂和手的节点作为一个共同的父节点的子节点。你可以像下面这样创建一个空的SKNode来实现这个目的:
let armsParent = SKNode()

然后,不要直接将手臂和手添加为场景的子项,而是将它们作为armsParent的子项添加,如下所示:

armsParent.addChild(leftArm)
armsParent.addChild(rightArm) // same for hands...

然后,您可以使用SKAction简单地旋转armsParent以实现您想要的效果。

或者,为了更加简单,您可以直接将arms和hands作为子节点添加到hook中,像这样:

hook.addChild(leftArm) // same for other arm and hands...

由于手臂和手是“hook”或“armParent”的子级,它们的位置现在将相对于其父级确定。因此,您可能需要更改所有的.position =初始化代码以适应这一点。


我现在应该如何创建和添加关节?在我提问的代码中,我是这样做的:let hookAndRightArmJoint = SKPhysicsJointPin.joint(withBodyA: hook.physicsBody!, bodyB: rightArm.physicsBody!, anchor: CGPoint(x: hook.position.x, y: rightArm.frame.maxY)) self.physicsWorld.add(hookAndRightArmJoint) 。但现在我不确定应该怎样做了。 - Containment
我按照以下方式添加了 armsParentvar armsParent = SKNode() armsParent.position = hook.position armsParent.zPosition = 10 addChild(armsParent),并在其上运行了以下SKAction:armsParent.run(SKAction.rotate(byAngle: CGFloat(Double(60).degreesToRadians), duration: 0.5)),但它没有旋转。 - Containment
3
我最终让它起作用了,通过创建一个新的sprite并将手臂和手添加为子节点。但这带来了另一个问题,现在手无法在两个方向上独立旋转。我一开始是使用以下代码打开手的,但现在不起作用了。rightHand.run(SKAction.rotate(byAngle: CGFloat(Double(30).degreesToRadians), duration: 0.5)) leftHand.run(SKAction.rotate(byAngle: CGFloat(Double(-30).degreesToRadians), duration: 0.5)) - Containment
请查看我对一个可疑相似问题的回答[此处](https://dev59.com/flcP5IYBdhLWcg3wiqdr#44297857)。看起来你们可能正在做同一节课的项目!但是我写的“rotatePendulum...”函数可能恰好是你所需要的。 - mogelbuster

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接