这些天,我正在用Swift编写一个SpriteKit教程。
我用一个旋钮编程了“欢乐棒”,它可以在操纵杆圈内的任何地方移动。
下面是相关的代码片段:
for touch in touches {
let position = touch.location(in: joystick)
let length = sqrt(pow(position.y, 2) + pow(position.x, 2))
let angle = atan2(position.y, position.x)
if knobRadius > length {
joystickKnob.position = position
} else {
joystickKnob.position = CGPoint(x: cos(angle) * knobRadius, y: sin(angle) * knobRadius)
}}下面是本教程中的一张图片:

但现在我想做一些不同的事情。
我希望Knob只能在X和Y轴上移动,就像交叉向上,向下,左,右在栏杆上。

我真的理解代码--我认为这更像是一个数学题:)
有人能告诉我如何在横梁内移动旋钮吗?
发布于 2018-05-04 15:43:47
为了使你的角度保持在十字线上,你需要把角度旋转到π/2的间隔。
要做到这一点,只需:
angle = (angle * 2 / CGFloat.pi).rounded() * (CGFloat.pi / 2)下面,我修改了您的代码,使其工作得更好,并允许您避免分支。
我使用的是基本半径,而不是旋钮半径,这样你就永远不能超过基础。
for touch in touches {
let position = touch.location(in: joystick)
let radius = min(baseRadius,sqrt(pow(position.y, 2) + pow(position.x, 2))
// a nicer way to get radius
//let radius = min(baseRadius,position.distance(to:CGPoint.zero))
let angle = atan2(position.y, position.x)
if crossHairStick
{
angle = (angle * 2 / CGFloat.pi).rounded() * (CGFloat.pi / 2)
}
joystickKnob.position = CGPoint(x: cos(angle) * radius, y: sin(angle) * radius)
}如果你想把旋钮保持在底部,减去旋钮半径。(这假设两个半径都是正的,否则使用半径的绝对值)
for touch in touches {
let position = touch.location(in: joystick)
let radius = min(baseRadius - knobRadius,sqrt(pow(position.y, 2) + pow(position.x, 2))
let angle = atan2(position.y, position.x)
if crossHairStick
{
angle = (angle * 2 / CGFloat.pi).rounded() * (CGFloat.pi / 2)
}
joystickKnob.position = CGPoint(x: cos(angle) * radius, y: sin(angle) * radius)
}发布于 2018-05-04 15:32:12
因此,您希望将angle限制为.pi / 2的倍数(90度)。atan2函数在范围-.pi ... +.pi中返回一个值。将其从弧度转换为四分之一转弯(直角)的单位,旋转为整数,然后再转换为弧度。
let touchAngle = atan2(position.y, position.x) // -.pi ... +.pi
let quarterTurns = touchAngle * 2 / .pi // -2 ... +2
let integralQuarterTurns = quarterTurns.rounded() // -2, -1, 0, +1, or +2
let angle = integralQuarters * .pi / 2或者,查看abs(position.x)和abs(position.y)的哪个更大,并使用它来确定angle
let angle: CGFloat
switch abs(position.x) > abs(position.y) {
case true where position.x > 0: angle = 0
case true where position.x < 0: angle = .pi
case false where position.y > 0: angle = .pi / 2
case false where position.y < 0: angle = .pi / -2
default: angle = 0 // position == .zero so joystick is actually centered
}https://stackoverflow.com/questions/50178251
复制相似问题