在Swift SpriteKit中不会停止摆动的摆动梁

时间:2016-05-21 15:46:01

标签: swift sprite-kit skphysicsbody

我有一个ios 9 spritekit游戏。我正在添加一个工字梁或一个破坏球,它应该像一个像钟摆一样的连接绳索摆动。我的游戏需要重力,我希望光束能够对重力和精灵做出反应,这些重力和精灵会从光束上跳跃或从下方射出光束。当我使用下面的代码时,光束最终会减速并在没有与其他精灵交互的情况下休息。连接节点中的顶部节点是固定的(即,建模连接到起重机或建筑物)。我通过在连接节点中的底部节点上施加脉冲来启动光束摆动。我将摩擦力,线性阻尼和角度阻尼设置为0。

在与任何精灵交互之前,我需要光束做的是来回摆动,其中左侧摆动和右侧摆动的最大高度在整个时间内几乎相同。我希望横梁或破坏球的作用就像它从无摩擦的枢轴摆动一样。光束或球没有整圆,所以我不能使用恒定的角速度。

我尝试过类似的东西: Constant speed orbit around point with SKNode但是在初始脉冲之后,线性或角速度都不是恒定的,因为光束或球将向上弧形,减速,停在弧的顶部,然后在另一个方向上回转。

  let (actionSceneObjectNode, jointArray) = ActionSceneObject.createActionJointedSceneObjectAtPosition(CGPoint(x: positionX, y: positionY), ofType: actionSceneObject.type!, withImage: actionSceneObject.imageName, withActionDirection: actionSceneObject.imageDirection)
     foregroundNode.addChild(actionSceneObjectNode)
     if let bottomNode = actionSceneObjectNode.childNodeWithName("bottomObject") {
     bottomNode.physicsBody?.applyImpulse(CGVector(dx: 50000.0, dy: 0))
  }

  // add the joints
  for joint in jointArray {
     self.physicsWorld.addJoint(joint)
  }

功能

  class func createActionJointedSceneObjectAtPosition(position: CGPoint, ofType type: ActionSceneObjectType, withImage imageName: String, withActionDirection actionDirection: DirectionValue) -> (ActionSceneObjectNode, [SKPhysicsJoint]) {
    let node = ActionSceneObjectNode()
    node.position = position
    node.name = SceneObjectType.Action.rawValue
    node.actionType = type
    node.actionDirection = actionDirection

    var jointArray = [SKPhysicsJoint]()

    var sprite: SKSpriteNode

    ////////
    // adapted from https://stackoverflow.com/questions/20811931/how-to-create-a-rope-in-spritekit

    let countJointElements:Int = 3

    let texture = SKTexture(imageNamed: "Rope.png")
    //let textureSize = CGSize(width: texture.size().width*SceneObjectSizeScale.ActionSceneObject, height: texture.size().height*SceneObjectSizeScale.ActionSceneObject)

    let topAnchor = SKSpriteNode(texture: texture, size: texture.size())
    topAnchor.name = "topAnchor"
    //topAnchor.position = CGPointMake(position.x, position.y) // the node holds the joint start position
    topAnchor.physicsBody = SKPhysicsBody(rectangleOfSize: texture.size())
    topAnchor.physicsBody?.categoryBitMask = PhysicsCategoryBitmask.None
    topAnchor.physicsBody?.affectedByGravity = false
    topAnchor.physicsBody?.friction = 0.0
    topAnchor.physicsBody?.restitution = 1.0
    topAnchor.physicsBody?.linearDamping = 0.0
    topAnchor.physicsBody?.angularDamping = 0.0
    topAnchor.physicsBody?.mass = 10.0
    node.addChild(topAnchor)

    // by default, the joints build top to bottom
    for index in 0 ..< countJointElements {

        let item = SKSpriteNode(texture: texture, size: texture.size())
        item.name = "ropeitem_" + String(index)
        item.position = CGPointMake(0, 0 - CGFloat(index+1) * item.size.height)
        item.physicsBody = SKPhysicsBody(rectangleOfSize: texture.size())
        item.physicsBody?.categoryBitMask = PhysicsCategoryBitmask.None
        item.physicsBody?.affectedByGravity = true
        item.physicsBody?.friction = 0.0
        item.physicsBody?.restitution = 1.0
        item.physicsBody?.linearDamping = 0.0
        item.physicsBody?.angularDamping = 0.0
        item.physicsBody?.mass = 10.0
        node.addChild(item)

        var bodyA = SKPhysicsBody()

        if (index == 0)
        {
            bodyA = topAnchor.physicsBody!;
        }
        else
        {
            let nameString = "ropeitem_" + String(index - 1)
            let nodeItem = node.childNodeWithName(nameString) as! SKSpriteNode
            bodyA = nodeItem.physicsBody!
        }

        // needs to in terms of the physics world - the item position in the node is already negative
        let joint = SKPhysicsJointPin.jointWithBodyA(bodyA, bodyB: item.physicsBody!, anchor: CGPointMake(position.x, position.y + item.position.y + item.size.height/2))
        jointArray.append(joint)
    }

    let nameString = NSString(format: "ropeitem_%d", countJointElements - 1)
    let lastLinkItem = node.childNodeWithName(nameString as String)

    let bottomObject = SKSpriteNode(imageNamed: "I-Beam.png")
    bottomObject.name = "bottomObject"
    bottomObject.setScale(SceneObjectSizeScale.Platform)
    bottomObject.position = CGPointMake(0, 0 + lastLinkItem!.position.y - lastLinkItem!.frame.size.height/2.0 - bottomObject.frame.size.height/2.0)
    bottomObject.physicsBody = SKPhysicsBody(rectangleOfSize: bottomObject.size)
    bottomObject.physicsBody?.categoryBitMask = PhysicsCategoryBitmask.Platform
    bottomObject.physicsBody?.affectedByGravity = true
    bottomObject.physicsBody?.friction = 0.0
    //bottomObject.physicsBody?.restitution = 1.0
    bottomObject.physicsBody?.linearDamping = 0.0
    bottomObject.physicsBody?.angularDamping = 0.0
    bottomObject.physicsBody?.mass = 500.0
    node.addChild(bottomObject)

    let jointLast = SKPhysicsJointFixed.jointWithBodyA(lastLinkItem!.physicsBody!, bodyB: bottomObject.physicsBody!, anchor: CGPointMake(position.x, position.y + bottomObject.position.y + bottomObject.frame.size.height/2.0))

    jointArray.append(jointLast)

    ///////
    ///////
    sprite = SKSpriteNode(imageNamed: imageName)
    //sprite.setScale(SceneObjectSizeScale.ActionSceneObject)
    node.sprite = sprite

    //node.addChild(sprite)

    node.physicsBody = SKPhysicsBody(texture: texture, size: sprite.size)
    node.physicsBody!.categoryBitMask = PhysicsCategoryBitmask.None

    switch actionDirection {
    case .Left:
        node.sprite.zRotation = CGFloat(M_PI_2)
    case .Right:
        node.sprite.zRotation = CGFloat(-M_PI_2)
    case .Down:
        node.sprite.zRotation = CGFloat(M_PI)
    case .Up, .Unknown:
        break
    }

    node.physicsBody?.dynamic = true
    node.physicsBody?.restitution = 0.0 // bounciness
    node.physicsBody?.categoryBitMask = PhysicsCategoryBitmask.ActionSceneObject
    node.physicsBody?.collisionBitMask = 0

    return (node, jointArray)
}

0 个答案:

没有答案