我有一个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)
}