gpt4 book ai didi

swift - 如何限制两条锚定线的运动,使它们像钟摆一样不断摆动

转载 作者:IT王子 更新时间:2023-10-29 05:16:02 24 4
gpt4 key购买 nike

我创建了两条锚定到 Sprite 的线,它们相隔 30˚。我希望两条线像钟摆一样左右摆动,始终从头到尾摆动(这样它们就可以从初始位置左右摆动 45°)。请查看下图,了解我要实现的目标:

enter image description here

下面是我能够实现的代码:

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 anchorSprite = SKSpriteNode(imageNamed: "swingPin")
var armLeft = SKSpriteNode(imageNamed: "swingArm")
var armRight = SKSpriteNode(imageNamed: "swingArm")

override func didMove(to view: SKView) {


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

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

anchorSprite.position = CGPoint(x: frame.midX, y: frame.midY + frame.midY/2)
anchorSprite.zPosition = 20

anchorSprite.physicsBody = SKPhysicsBody(rectangleOf: anchorSprite.frame.size)
anchorSprite.physicsBody?.categoryBitMask = pinCategory
anchorSprite.physicsBody?.isDynamic = false
addChild(anchorSprite)

armRight.anchorPoint = CGPoint(x: 0.5, y: 1)
armRight.position = anchorSprite.position
armRight.zPosition = 20
armRight.physicsBody = SKPhysicsBody(rectangleOf: armRight.frame.size)
armRight.zRotation = CGFloat(Double(15).degreesToRadians)//CGFloat(Double.pi/6)
armRight.physicsBody!.isDynamic = true

addChild(armRight)

armLeft.anchorPoint = CGPoint(x: 0.5, y: 1)
armLeft.position = anchorSprite.position
armLeft.zPosition = 20
armLeft.physicsBody = SKPhysicsBody(rectangleOf: armRight.frame.size)
armLeft.zRotation = CGFloat(Double(-15).degreesToRadians)//CGFloat(-Double.pi/6)
armLeft.physicsBody!.isDynamic = true
addChild(armLeft)

// Create joint between two objects
//Pin joint
var pinAndRightArmJoint = SKPhysicsJointPin.joint(withBodyA: anchorSprite.physicsBody!, bodyB: armRight.physicsBody!, anchor: CGPoint(x: anchorSprite.position.x, y: self.armRight.frame.maxY))
self.physicsWorld.add(pinAndRightArmJoint)

var pinAndLeftArmJoint = SKPhysicsJointPin.joint(withBodyA: anchorSprite.physicsBody!, bodyB: armLeft.physicsBody!, anchor: CGPoint(x: anchorSprite.position.x, y: self.armLeft.frame.maxY))
self.physicsWorld.add(pinAndLeftArmJoint)

var fixArms = SKPhysicsJointFixed.joint(withBodyA: armLeft.physicsBody!, bodyB: armRight.physicsBody!, anchor: CGPoint.zero)
self.physicsWorld.add(fixArms)

pinAndRightArmJoint.shouldEnableLimits = true
pinAndRightArmJoint.lowerAngleLimit = CGFloat(Double(-60).degreesToRadians)
pinAndRightArmJoint.upperAngleLimit = CGFloat(Double(60).degreesToRadians)

}


override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
//armRight.physicsBody?.angularVelocity = -100.0

let seq = SKAction.sequence([
SKAction.rotate(byAngle: CGFloat(Double(45).degreesToRadians), duration: 0.5),
SKAction.rotate(byAngle: CGFloat(Double(-45).degreesToRadians), duration: 1.0),
SKAction.rotate(byAngle: CGFloat(Double(45).degreesToRadians), duration: 1.0),
SKAction.rotate(byAngle: CGFloat(Double(-45).degreesToRadians), duration: 1.0),
SKAction.rotate(byAngle: CGFloat(Double(45).degreesToRadians), duration: 1.0),
SKAction.rotate(byAngle: CGFloat(Double(-45).degreesToRadians), duration: 1.0)
])
armRight.run(seq)
}

根据上面的代码,我设置了下限和上限角度限制并尝试运行一个 Action ,但这只会让线条以一种非常不切实际的方式向侧面倾斜一点。我还尝试在物理体上应用角速度,但这只会使其以不一致的速度短暂摆动(我需要它从一端到另一端始终如一地摆动)。

注意

由于我每次都需要它从头到尾摆动,所以我需要摆动周期每次都一致,不一定是恒定的。当线向中心移动时,一个周期通常会摆动得更快,而当从一个方向改变到另一个方向时,周期会稍微慢一些。这就是我想要的运动感觉。

最佳答案

这是实际的答案:

addChild(armRight) 替换为 anchorSprite.addChild(armRight)。将 addChild(armLeft) 替换为 anchorSprite.addChild(armLeft)。删除armRight.position = anchorSprite.position 和删除armLeft.position = anchorSprite.position。此外,除非您在代码中将物理关节用于其他运动,否则请将其全部删除,因为我的解决方案不需要关节。

现在您的 ARM 是 anchorSprite 的子项并服从于它的坐标系。如果你想同时向同一个方向旋转双臂,你可以在 anchorSprite 上运行一个旋转 Action 。如果你想让 ARM 向不同的方向旋转,你必须分别在每只 ARM 上运行旋转 Action 。对于任何一种情况,您都可以使用我为这个问题制作的这个方便的功能:-P

func runPendulumRotationOnNode(_ node:SKNode, withAngle angle:CGFloat, period:TimeInterval, key:String) {
let initialRotate = SKAction.rotate(byAngle: angle/2, duration: period/2)
initialRotate.timingMode = .easeOut
let rotate = SKAction.rotate(byAngle: angle, duration: period)
rotate.timingMode = .easeInEaseOut
let rotateForever = SKAction.repeatForever(SKAction.sequence([rotate.reversed(), rotate]))
let rotateSequence = SKAction.sequence([initialRotate, rotateForever])
node.run(rotateSequence, withKey:key)
}

我已经测试过了,效果很好!你可以这样调用它来一起旋转双臂:

runPendulumRotationOnNode(anchorSprite, withAngle:CGFloat.pi/2, period:0.5, key:"")

或者让 ARM 向相反的方向旋转,你可以这样使用:

runPendulumRotationOnNode(armRight, withAngle:CGFloat.pi/2, period:0.5, key:"")
runPendulumRotationOnNode(armLeft, withAngle:-CGFloat.pi/2, period:0.5, key:"")

一些小的注意事项,请注意我如何使用 CGFloat.pi,这是 π 的一个简单常数。此函数还假定钟摆从其旋转的中点开始,因此 π/2(90 度)将使摆臂在任一方向上旋转 π/4(45 度)。

关于swift - 如何限制两条锚定线的运动,使它们像钟摆一样不断摆动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44241484/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com