gpt4 book ai didi

Swift:使用施加的脉冲计算节点的轨迹

转载 作者:可可西里 更新时间:2023-11-01 01:57:00 26 4
gpt4 key购买 nike

我想计算一个 SKSpriteNode 在被施加脉冲后的轨迹。我有 12 个球,我想把它们放在球发射后的位置。我正在使用等式 𝕡(t)=𝕡₀+t(𝕧₀+½Δt𝕒)+½t²𝕒

我对节点施加的冲量基于用户在屏幕上拖动的长度。

这是我试过的:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches{
let location = touch.location(in: self)
startPositionDrag = location
}
}

touchesMoved 中,我更新轨迹节点以显示如果在该位置启动节点将去向的位置。

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches{

movedLocation = touch.location(in: self)

calculateTrajectoryy(velocityY: (startPositionDrag.y - movedLocation.y), velocityX: (startPositionDrag.x - movedLocation.x))

}

这是我使用等式的地方。我有一个 12 个球的数组。我使用 i 作为时间,因为我想将每个球放在 i 秒后节点所在的位置。

func calculateTrajectoryy(velocityY: CGFloat, velocityX: CGFloat){

for i in 0...12{

let time = CGFloat(i)
let accelerationX = CGFloat(0)
let accelerationY = CGFloat(-9.8)
var x = CGFloat()
var y = CGFloat()

// 𝕡(t)=𝕡₀+t(𝕧₀+½Δt𝕒)+½t²𝕒
x = ball.position.x + time * (velocityX + 0.5 * time * accelerationX) + 0.5 * time * time * accelerationX

y = ball.position.y + time * (velocityY + 0.5 * time * accelerationY) + 0.5 * time * time * accelerationY

arrray[i].position = CGPoint(x: x, y: y)

}
}

最后在 touchesEnded 中,当用户松开拖动时,节点将应用一个脉冲,它应该完全遵循创建的球的路径。

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches{
let location = touch.location(in: self)

ball.physicsBody?.applyImpulse(CGVector(dx:(startPositionDrag.x - endPositionDrag.x), dy:(startPositionDrag.y - endPositionDrag.y))

}
}
}

球不遵循球产生的弧线。球射出一点点,而球的弧线又大又长。我认为这可能与单位转换有关。该等式使用每秒米数的速度值,而拖回的位置是 CGFloat。米会比 CGFloat 长,因此预测的轨迹会更长。我如何才能将轨迹转换为与像素或 CGFloat 一起使用?我可以除以像素与米的比率吗?

最佳答案

(从物理学的角度回答,我不是 swift 或 sprite-kit 的专家)

“单位”的选择(以及一个点代表的物理距离)完全由您决定,您在调用 applyImpulse() 之前所拥有的数学与假设 1point = 1米。这可能是您想要的,也可能不是您想要的,但这是一个不错的选择 - 顺便说一句,在您的代码中唯一(某种程度上)将一个点固定到真实世界的仪表的是重力值 9.8,否则您可以只是称它们为点,实际意义没有变化——物理引擎并不关心。

您在代码中放入 array[] 的连续球位置是假设发射的球将在一秒钟内覆盖从 start_of_drag 到 end_of_drag 的距离(因为您只是将距离用作速度值,即, 1m 变为 1m/sec, 2m = 2m/s, 等等)。(注意我不太清楚 12 点预测路径在您的情况下如何正确工作,因为要获得指向拖动方向的矢量,您通常会执行 end_drag - start_drag,而你的代码确实 start - end)

您遇到的问题可能与 applyImpulse 期望以牛顿*秒为单位的值有关(并且速度变化将取决于球的质量:delta-V = impulse/mass ),而您使用相同的“成为速度的距离”单位调用该函数。

如果球在拖动之前总是静止的,并且您希望它立即开始以选定的速度移动到某个地方,那么简单地将它的速度分配给所需的值并让它飞起来可能会更容易,而不是尝试使用 applyImpulse,例如:

(编辑:正如@knight0fdragon 指出的那样,SK 的距离单位是点,但速度是以抽象“米”= 150pt/sec 为单位测量的,所以如果你到目前为止以点和点/秒为单位进行数学计算,您必须在修改 physicsBody 向量之前缩放速度:将其除以 150.0)。

ball.physicsBody?.velocity = CGVector(dx:velocityX, dy:velocityY)

如果球已经有一定的速度并且您想修改它一定量(用速度单位而不是 N*m 表示)并且忽略质量,请将该速度变化添加到球的当前速度。

关于Swift:使用施加的脉冲计算节点的轨迹,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51813905/

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