首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >快速使用Spritekit - Joystick有旋钮教程

快速使用Spritekit - Joystick有旋钮教程
EN

Stack Overflow用户
提问于 2018-05-04 15:20:06
回答 2查看 2K关注 0票数 1

这些天,我正在用Swift编写一个SpriteKit教程。

我用一个旋钮编程了“欢乐棒”,它可以在操纵杆圈内的任何地方移动。

下面是相关的代码片段:

代码语言:javascript
复制
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轴上移动,就像交叉向上,向下,左,右在栏杆上。

我真的理解代码--我认为这更像是一个数学题:)

有人能告诉我如何在横梁内移动旋钮吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-05-04 15:43:47

为了使你的角度保持在十字线上,你需要把角度旋转到π/2的间隔。

要做到这一点,只需:

代码语言:javascript
复制
angle = (angle * 2 / CGFloat.pi).rounded() * (CGFloat.pi / 2)

下面,我修改了您的代码,使其工作得更好,并允许您避免分支。

我使用的是基本半径,而不是旋钮半径,这样你就永远不能超过基础。

代码语言:javascript
复制
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)
}

如果你想把旋钮保持在底部,减去旋钮半径。(这假设两个半径都是正的,否则使用半径的绝对值)

代码语言:javascript
复制
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)
}
票数 1
EN

Stack Overflow用户

发布于 2018-05-04 15:32:12

因此,您希望将angle限制为.pi / 2的倍数(90度)。atan2函数在范围-.pi ... +.pi中返回一个值。将其从弧度转换为四分之一转弯(直角)的单位,旋转为整数,然后再转换为弧度。

代码语言:javascript
复制
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

代码语言:javascript
复制
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
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50178251

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档