当前位置: 首页 > 面试题库 >

拖动绕固定点旋转节点

锺离德运
2023-03-14
问题内容

我试图在这个问题中创建一个类似于“奖杯轮”的可旋转节点。到目前为止,我具有甩尾功能,可以使用效果很好的UIPanGestureRecognizer在物理物体上添加角度脉冲。我也可以通过触摸停止旋转。

现在,我试图通过拖动或滑动手势来微调方向盘,这样,如果玩家对最终的效果不满意,就可以手动旋转/拖动/旋转它所喜欢的旋转方式。

目前,我将触摸的位置保存在touchesBegan中,并尝试在更新循环中增加节点的zRotation。

旋转不跟随我的手指,而且很生涩。我不确定我的手指运动是否获得足够准确的读数,或者手指的变化位置是否没有准确地转换为弧度。我怀疑先检测触摸然后在更新中处理它不是一个很好的解决方案。

这是我的代码。

    override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent?) {
    if let touch = touches.first as? UITouch {
        var location = touch.locationInView(self.view)
        location = self.convertPointFromView(location)

        mostRecentTouchLocation = location

        let node = nodeAtPoint(location)
        if node.name == Optional("left") && node.physicsBody?.angularVelocity != 0
        {
            node.physicsBody = SKPhysicsBody(circleOfRadius:150)
            node.physicsBody?.applyAngularImpulse(0)
            node.physicsBody?.pinned = true
        }
    }
}

    override func update(currentTime: CFTimeInterval) {
        /* Called before each frame is rendered */
        if mostRecentTouchLocation != CGPointZero{
        let node = nodeAtPoint(mostRecentTouchLocation)
        if node.name == Optional("left")
        {
            var positionInScene:CGPoint = mostRecentTouchLocation
            let deltaX:Float = Float(positionInScene.x) - Float(node.position.x)
            let deltaY:Float = Float(positionInScene.y) - Float(node.position.y)
            let angle:CGFloat = CGFloat(atan2f(deltaY, deltaX))
            let maths:CGFloat = angle - (CGFloat(90) * (CGFloat(M_PI) / 180.0))
            node.zRotation += maths
            mostRecentTouchLocation = CGPointZero
        }
    }
}

我在更新中将一些数学计算分散在多行中,以使调试更加容易。

如果需要,我可以添加PanGestureRecognizer代码,但现在我将尽量使其简短。

编辑
这是基于GilderMan推荐的最新代码。我认为它的效果更好,但是旋转远非平稳。它以较大的幅度跳跃并且没有很好地跟随手指。这是否意味着我的角度计算有问题?

    override func didSimulatePhysics() {
    if mostRecentTouchLocation != CGPointZero {
        let node = nodeAtPoint(mostRecentTouchLocation)
        if node.name == Optional("left")
        {
            var positionInScene:CGPoint = mostRecentTouchLocation
            let deltaX:Float = Float(positionInScene.x) - Float(node.position.x)
            let deltaY:Float = Float(positionInScene.y) - Float(node.position.y)
            let angle:CGFloat = CGFloat(atan2f(deltaY, deltaX))
            node.zRotation += angle
            println(angle)
            mostRecentTouchLocation = CGPointZero
        }
    }
}

问题答案:

以下代码模拟了根据触摸旋转的奖轮。当用户的手指移动时,轮子会与手指的速度成比例地旋转。当用户在方向盘上滑动时,方向盘将与滑动速度成比例地旋转。您可以更改angularDamping物理物体的属性以减慢或增加砂轮停止的速度。

class GameScene: SKScene {
    var startingAngle:CGFloat?
    var startingTime:TimeInterval?

    override func didMove(to view: SKView) {
        let wheel = SKSpriteNode(imageNamed: "Spaceship")
        wheel.name = "wheel"
        wheel.setScale(0.5)
        wheel.physicsBody = SKPhysicsBody(circleOfRadius: wheel.size.width/2)
        // Change this property as needed (increase it to slow faster)
        wheel.physicsBody!.angularDamping = 0.25
        wheel.physicsBody?.pinned = true
        wheel.physicsBody?.affectedByGravity = false
        addChild(wheel)
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        for touch in touches {
            let location = touch.location(in:self)
            let node = atPoint(location)
            if node.name == "wheel" {
                let dx = location.x - node.position.x
                let dy = location.y - node.position.y
                // Store angle and current time
                startingAngle = atan2(dy, dx)
                startingTime = touch.timestamp
                node.physicsBody?.angularVelocity = 0
            }
        }
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        for touch in touches{
            let location = touch.location(in:self)
            let node = atPoint(location)
            if node.name == "wheel" {
                let dx = location.x - node.position.x
                let dy = location.y - node.position.y

                let angle = atan2(dy, dx)
                // Calculate angular velocity; handle wrap at pi/-pi
                var deltaAngle = angle - startingAngle!
                if abs(deltaAngle) > CGFloat.pi {
                    if (deltaAngle > 0) {
                        deltaAngle = deltaAngle - CGFloat.pi * 2
                    }
                    else {
                        deltaAngle = deltaAngle + CGFloat.pi * 2
                    }
                }
                let dt = CGFloat(touch.timestamp - startingTime!)
                let velocity = deltaAngle / dt

                node.physicsBody?.angularVelocity = velocity

                // Update angle and time
                startingAngle = angle
                startingTime = touch.timestamp
            }
        }
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        startingAngle = nil
        startingTime = nil
    }
}


 类似资料:
  • 在JavaFX中,我试图通过单击并拖动节点来移动它。如果节点不旋转,它工作得很好,但是当我旋转它时,它开始表现得很奇怪。 在45°左右,当我移动它时,它开始抖动,在60°时,它剧烈地来回抖动。在90°时,只要我开始移动节点,它就会飞离屏幕。 下面是我用来旋转和移动节点的代码。它来自连接到节点的鼠标侦听器。 编辑:这是一些示例输出,以及显示不同节点的图片。 未旋转且缓慢向左移动时的输出: 旋转时缓慢

  • 问题内容: 我已经在这个问题上进行了很多搜索,但是我找不到真正合适的答案。 我需要围绕给定点(例如0,0,0)旋转圆柱体,但是默认情况下会给出圆柱体的枢轴。我该如何改变? 为了更好地说明我想做什么,我将显示3张图像。 imageshack.us/photo/my-images/259/aintgood.jpg imageshack.us/photo/my-images/840/whatineed.

  • 嗨,我正在尝试实现一个带有旋转的opengl程序 以下代码仅供参考:

  • 下面是java中的一个代码段,用于将坐标为a(10,10),B(20,10),C(20,20),D(10,20)的顶点围绕正方形的中心点旋转一个角度。正方形的边是10分。旋转角度为90度。理想情况下,旋转后A必须变成B,B必须变成C,C必须变成D,D必须变成A。 所取得的结果是不正确的 > 点A(10,10)旋转到(20,10)---正确 点B(20,10)旋转到(30,10)----不正确 nu

  • 当我尝试使用旋转图像视图时,我现在开始学习JavaFX 它绕着它的中轴线旋转,但是当我尝试使用 它随机旋转,我不知道它的旋转轴是一样的

  • 我目前正在尝试绕世界x轴旋转一个位置向量(0,0,1),然后将其旋转回其原始位置(只是尝试使其工作)。我阅读了旋转矩阵,并使它工作(排序),但我现在相当卡住了。 如图和代码所示,我在起点(0,0,1)处创建了一个立方体,并将其向下旋转30度。但顺时针旋转时,它的旋转角度似乎超过30度。但是,当我逆时针(30度)旋转它时,它确实旋转了适当的量。这导致它没有在它应该(0,0,1)的起点处结束。 我想知