首页 > 解决方案 > Swift with Spritekit - 带旋钮的操纵杆教程

问题描述

这些天我正在使用 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)
}}

这是教程中的图片:

在此处输入图像描述

但现在我想做一些不同的事情。

我希望旋钮只能像十字一样在 X 和 Y 轴上移动 - 就像在轨道上的上、下、左、右一样。

在此处输入图像描述

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

有人能告诉我如何在轨道上的十字内移动旋钮吗?

标签: iossprite-kitskspritenodetouchesmoved

解决方案


为了使您的角度保持在十字准线上,您需要将角度四舍五入到 pi/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)
}

推荐阅读