使用多点触控解决冲突的触摸

时间:2018-04-21 05:18:26

标签: ios swift sprite-kit touch multi-touch

我有两个精灵朝向触摸点旋转。在touchesBegan中,我使用if语句来检查触摸点是否在两个X点范围中的任何一个范围内,以便分离两个精灵的旋转。例如,如果触摸点在左侧范围内,则左侧子画面朝向触摸点旋转。我使用touchesMoved来更新精灵的旋转。然后我使用touchesEnded将精灵返回到原始位置。

我面临的问题是,如果我将手指从左向右拖动,因此从左侧范围跨越到右侧范围,则touchesEnded不会将第一个精灵返回到其原始位置。我知道这是因为触摸在另一个范围内结束,然后只纠正其他精灵。我试图通过在touchesMoved中添加if语句来解决这个问题,以便在触摸移动到一个范围之外并进入另一个范围时更正位置。

直到我使用两个手指才能工作,屏幕两侧各有一个手指同时以不同的方式旋转两个精灵。然后精灵们从他们当前的旋转状态来回跳跃到他们不可控制的原始位置。解决这个问题的最佳方法是什么?

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    for touch: AnyObject in touches {
        location = touch.location(in: self)
        let DegreesToRadians = Pi / 180

        let rightDeltaX = location.x - rightSprite.position.x
        let rightDeltaY = location.y - rightSprite.position.y
        let rightAngle = atan2(rightDeltaY, rightDeltaX)

        let leftDeltaX = location.x - leftSprite.position.x
        let leftDeltaY = location.y - leftSprite.position.y
        let leftAngle = atan2(leftDeltaY, leftDeltaX)

            if 0...768 ~= location.x {
                leftSprite.zRotation = leftAngle - 90 * DegreesToRadians
            }
            if 769...1536 ~= location.x {
                rightSprite.zRotation = rightAngle - 90 * DegreesToRadians
            }
    }
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    for touch: AnyObject in touches {
        location = touch.location(in: self)
        let DegreesToRadians = Pi / 180

        let rightDeltaX = location.x - rightSprite.position.x
        let rightDeltaY = location.y - rightSprite.position.y
        let rightAngle = atan2(rightDeltaY, rightDeltaX)

        let leftDeltaX = location.x - leftSprite.position.x
        let leftDeltaY = location.y - leftSprite.position.y
        let leftAngle = atan2(leftDeltaY, leftDeltaX)

            if 0...768 ~= location.x {
                leftSprite.zRotation = leftAngle - 90 * DegreesToRadians

                if !(769...1536 ~= location.x) {
                    rightSprite.zRotation = 0
                }
            }
            if 769...1536 ~= location.x {
                rightSprite.zRotation = rightAngle - 90 * DegreesToRadians

                if !(0...768 ~= location.x) {
                    leftSprite.zRotation = 0
                }
            }
    }
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    for touch: AnyObject in touches {
        location = touch.location(in: self)

            if 0...768 ~= location.x {
                leftSprite.zRotation = 0
            }
            if 769...1536 ~= location.x {
                rightSprite.zRotation = 0
            }
    }
}

1 个答案:

答案 0 :(得分:0)

传递给该功能的UITouch Set中的每个“触摸”都是一个独特的触摸事件。当同时使用多个触摸时,每个手指将在该组中用单独的“触摸”表示。请记住,这是一个无序的集合。

在您提供的代码中,您可以检索单个触摸事件的位置。您检查触摸位置的x值是否高,然后在该条件下,您还检查它是否为低。但是你要检查相同的位置,相同的x值。如果x值为768或更低,则总是为“!(x> 769)”。如果是769或以上,总是是“不是768或以下”。

因此,对于“移动”功能期间的每个触摸事件,无论它在哪一侧,另一侧都被重置。如果您在相对的两侧同时有两个触摸事件,则它们都会不断地设置侧面并重置另一侧。如你所说,由此产​​生的行为将是“无法控制的”。

解决方案

您需要跟踪UI的状态。具体而言,您需要跟踪您的触摸位置。

touchesBegan()期间,您可以将位置添加到跟踪的触摸设置中。在touchesEnded()期间,您可以从跟踪触摸集中删除该位置。在touchesMoved()期间,您可以确定哪个跟踪触摸最接近移动的触摸对象,并相应地进行更新。

每次更新设置时,您都会解析跟踪的触摸设置并相应地更新节点的旋转。如果某个节点没有旋转它的触摸,则会重置该节点。在for touch in touches循环之后,最好调用此函数。