0

我正在尝试解决我在使用 SKPhysicsContactDelegate 碰撞检测时遇到的问题。我有两个节点,nodeA 和 nodeB,nodeA 在屏幕上是静止的,而 nodeB 可以通过用户的手指在屏幕上拖动。nodeA 需要能够检测 nodeB 是否与它重叠。didBeginContact 和 didEndContact 方法被多次调用,通过研究我发现这是一种预期的行为。为了解决这个问题,我只需将一个整数变量设置为 0,并在每次有联系时将其递增,并在每次联系结束时将其递减。如果该值大于 0,则两个节点重叠,如果该值等于 0,则它们不重叠。这工作正常,直到用户将 nodeB 拖到 nodeA 上的速度太快。发生这种情况时,联系方法的调用次数并不总是正确的。例如,可能检测到 3 个接触,但只有两个末端接触(甚至没有),这使得程序认为两个节点仍然重叠,即使它们没有重叠。我假设发生这种情况是因为用户拖动节点的速度超过了程序可以更新的速度。我能做些什么来解决这个问题吗?基本上我只需要确切地知道两个节点何时重叠以及何时不重叠。另请注意,节点是凸形。以下是我的联系方式:我假设发生这种情况是因为用户拖动节点的速度超过了程序可以更新的速度。我能做些什么来解决这个问题吗?基本上我只需要确切地知道两个节点何时重叠以及何时不重叠。另请注意,节点是凸形。以下是我的联系方式:我假设发生这种情况是因为用户拖动节点的速度超过了程序可以更新的速度。我能做些什么来解决这个问题吗?基本上我只需要确切地知道两个节点何时重叠以及何时不重叠。另请注意,节点是凸形。以下是我的联系方式:

func didBeginContact(contact: SKPhysicsContact)
{
    let contactMask = contact.bodyA.categoryBitMask + contact.bodyB.categoryBitMask

    if contactMask == 3
    {
        startContact++
        timerStart = true
    }
}

func didEndContact(contact: SKPhysicsContact)
{
    let contactMask = contact.bodyA.categoryBitMask + contact.bodyB.categoryBitMask

    if contactMask == 3
    {
        startContact--
        if startContact == 0
        {
            timerStart = false
        }
    }
} 
4

1 回答 1

1

您可以使用intersectsNode:方法检查一个节点是否与另一个节点相交。从有关此方法的文档中:

返回一个布尔值,指示此节点是否与指定节点相交。

另外要记住的重要部分是:

如果两个节点的框架相交,则认为这两个节点相交。在这个测试中,两个节点的子节点都被忽略了。

import SpriteKit

class GameScene: SKScene {


    var stationaryNode :SKSpriteNode = SKSpriteNode(color: SKColor.grayColor(), size: CGSize(width: 100, height: 100))

    var moveableNode   :SKSpriteNode = SKSpriteNode(color: SKColor.purpleColor(), size: CGSize(width: 100, height: 100))

    let debugLabel     :SKLabelNode  = SKLabelNode(fontNamed: "ArialMT")

    override func didMoveToView(view: SKView) {


        setupScene()

    }

    func setupScene(){

        stationaryNode.name = "stationaryNode"
        stationaryNode.zRotation = 0.2
        stationaryNode.zPosition = 1
        stationaryNode.position = CGPoint(x: CGRectGetMidX(frame), y: CGRectGetMidY(frame))
        addChild(stationaryNode)

        moveableNode.name = "moveableNode"
        moveableNode.zRotation = 0.4
        moveableNode.zPosition = 2
        moveableNode.position = CGPoint(x: CGRectGetMidX(frame), y: CGRectGetMidY(frame)-200)
        addChild(moveableNode)

        debugLabel.fontSize = 18
        debugLabel.fontColor = SKColor.yellowColor()
        debugLabel.position = CGPoint(x: CGRectGetMidX(frame), y: CGRectGetMidY(frame)+200)
        addChild(debugLabel)
        updateDebugLabel()


    }

    func updateDebugLabel(){

        let intersectionDetected:String = stationaryNode.intersectsNode(moveableNode) ? "YES" : "NO"

        debugLabel.text = "Overlapping : " + intersectionDetected

    }

    override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {


        for touch in touches {

            let location = touch.locationInNode(self)

            let previousPosition = touch.previousLocationInNode(self)

            let node: SKNode? = nodeAtPoint(location)

            if let nodeName = node?.name{

                if nodeName == "moveableNode" {

                    let translation = CGPoint(x: location.x - previousPosition.x , y: location.y - previousPosition.y )

                    node!.position = CGPoint(x: node!.position.x + translation.x, y: node!.position.y + translation.y)

                }
            }

        }
    }

    override func update(currentTime: CFTimeInterval) {
        /* Called before each frame is rendered */


        updateDebugLabel()

    }
}

我想这个解决方案比使用物理引擎来检测如此快速移动的物体的接触要好一些。尽管如此,极快地移动物体可能会产生不可预知的结果。

于 2015-12-14T00:06:13.450 回答