1

2D-トップダウンゲームを構築しようとしていますが、プレイヤー(skspritenode)があり、サムスティックを使用するときに彼を動かしたいと考えています。私はこのコードを使用します:

ゲームパッド GCExtendedGamepad

if gamepad.leftThumbstick.xAxis.value > 0.1 || gamepad.leftThumbstick.xAxis.value < -0.1 || gamepad.leftThumbstick.yAxis.value > 0.1 || gamepad.leftThumbstick.yAxis.value < -0.1
{
    self.player.moveAndRotate(gamepad.leftThumbstick.xAxis.value, yValue: gamepad.leftThumbstick.yAxis.value)
}

moveAndRotate - 関数

func moveAndRotate(xValue: Float, yValue: Float)
{
    zRotation = CGFloat(-atan2(xValue, yValue))

    physicsBody!.velocity = CGVectorMake(0, 0)
    physicsBody!.applyImpulse(CGVectorMake(CGFloat(xValue) * moveSpeed, CGFloat(yValue) * moveSpeed))
}

ただし、プレイヤーが斜めに移動すると、通常の速度よりも速度が速くなります。誰でも私を助けることができますか?

4

1 に答える 1

1

あなたの三角関数は逆だと確信しています

これは、ゲームで斜めに移動するために使用するコードのスニペットです。

let angle: CGFloat = atan2f(dest.y - self.position.y, dest.x - self.position.x)

y 値が x 値の前に来ます

Raywenderlich.com より引用

この特定の問題については、atan() を使用する代わりに、関数 atan2() を使用する方が簡単です。この関数は、x 成分と y 成分を個別のパラメーターとして取り、全体の回転角度を正しく決定します。

angle = atan2(opposite, adjacent)

let angle = atan2(playerVelocity.dy, playerVelocity.dx)
playerSprite.zRotation = angle

Y 座標が最初になることに注意してください。よくある間違いは atan(x, y) と書くことですが、それは間違った方法です。最初のパラメーターは反対側であることを思い出してください。この場合、Y 座標は測定しようとしている角度の反対側にあります。

新しい 問題を再現できましたが、コードを以下のように変更することで、斜めに上下と同じ速度で移動することができました

if ((!isDPad && dirPad.up.value > 0.2) || (isDPad && dirPad.up.pressed == true)) { self.upValue = 1 //upValue = gamepad.leftThumbstick.up.value }

    if ((!isDPad && dirPad.down.value > 0.2) || (isDPad && dirPad.down.pressed == true)) {
        self.downValue = 1
    }

    if ((!isDPad && dirPad.right.value > 0.2) || (isDPad && dirPad.right.pressed == true)) {
        self.rightValue = 1
    }

    if ((!isDPad && dirPad.left.value > 0.2) || (isDPad && dirPad.left.pressed == true)) {
        self.leftValue = 1
    }

    let speed: Float = 300.0
    let xValue = self.rightValue - self.leftValue
    let yValue = self.upValue - self.downValue

    let length = hypotf(xValue, yValue)

    var moveDirection: CGVector?

    if length > 0.0 {
        let inverseLength = 1 / length
        moveDirection = CGVector(dx: CGFloat(xValue * inverseLength * speed), dy: CGFloat(yValue * inverseLength * speed))
    }
    else {
        moveDirection = CGVector(dx: 0, dy: 0)
    }

    testObject.physicsBody!.velocity = CGVectorMake(0, 0)
    testObject.physicsBody!.applyImpulse(direction)
于 2016-06-17T14:21:20.353 に答える