检测Sprite纹理内的触摸而不是整个框架iOS Swift SpriteKit?

时间:2015-10-08 05:02:19

标签: ios swift sprite-kit skspritenode

我现在正在使用SpriteKit,我遇到了一个看似简单的问题,但我在互联网上找不到任何东西。我有三个按钮形状像平行四边形堆叠在一起,它看起来像这样: Screenshot of buttons

let button = SKSpriteNode(imageNamed: "playbutton")
let leaderButton = SKSpriteNode(imageNamed: "leaderbutton")
let homeButton = SKSpriteNode(imageNamed: "homebutton")

    button.position = CGPoint(x: size.width/2, y: size.height/2)
    addChild(button)

    leaderButton.position = CGPoint(x: size.width/2, y: size.height/2 - button.size.height/2)
    addChild(leaderButton)

    homeButton.position = CGPoint(x: size.width/2, y: size.height/2 - button.size.height)
    addChild(homeButton)

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    for touch: AnyObject in touches {

        let location = touch.locationInNode(self)

        if button.containsPoint(location) {
            button.runAction(SKAction.scaleTo(0.8, duration: 0.1))
        }
        else if leaderButton.containsPoint(location) {
            leaderButton.runAction(SKAction.scaleTo(0.8, duration: 0.1))
        }
        else if homeButton.containsPoint(location) {
            homeButton.runAction(SKAction.scaleTo(0.8, duration: 0.1))
        }
    }
}

这就是我检测触摸的方式。问题是它们重叠,因为精灵实际上是一个矩形,所以当我尝试点击第二个按钮的左上角时,顶部按钮会检测到它。我想知道有一种方法可以检测纹理中的触摸,就像你可以将物理体设置为纹理一样。 谢谢你能给我的任何帮助!

链接现在可以使用。

所以我尝试了这个:

    button.position = CGPoint(x: size.width/2, y: size.height/2)
    button.physicsBody = SKPhysicsBody(texture: SKTexture(imageNamed: "playbutton"), size: button.size)
    button.physicsBody?.dynamic = false
    addChild(button)

    leaderButton.position = CGPoint(x: size.width/2, y: size.height/2 - button.size.height/2)
    leaderButton.physicsBody = SKPhysicsBody(texture: SKTexture(imageNamed: "leaderbutton"), size: leaderButton.size)
    leaderButton.physicsBody?.dynamic = false
    addChild(leaderButton)

    homeButton.position = CGPoint(x: size.width/2, y: size.height/2 - button.size.height)
    homeButton.physicsBody = SKPhysicsBody(texture: SKTexture(imageNamed: "homebutton"), size: homeButton.size)
    homeButton.physicsBody?.dynamic = false
    addChild(homeButton)

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    for touch: AnyObject in touches {

        let location = touch.locationInNode(self)

        if physicsWorld.bodyAtPoint(location)?.node == button {
            button.runAction(SKAction.scaleTo(0.8, duration: 0.1))
            print("play")
        }
        if physicsWorld.bodyAtPoint(location)?.node == leaderButton {
            leaderButton.runAction(SKAction.scaleTo(0.8, duration: 0.1))
            print("leader")
        }
        if physicsWorld.bodyAtPoint(location)?.node == homeButton {
            homeButton.runAction(SKAction.scaleTo(0.8, duration: 0.1))
        }
    }
}

它仍然记录整个帧而不仅仅是物理体。请参阅链接以查看按钮及其坐标的交叉方式。

2 个答案:

答案 0 :(得分:8)

如果将物理主体附加到每个按钮,则可以检测到触摸所在的物理主体。

您可以使用SKSpriteNodeSKPhysicsBody(texture:size:)从按钮的纹理生成物理主体(假设按钮为SKPhysicsBody(texture:alphaThreshold:size:)),或者您可以创建{{1描述按钮的形状并使用CGPath。将正文分配给按钮的SKPhysicsBody(polygonFromPath:)属性。假设您实际上并不想让物理模拟器移动按钮,请将每个主体的physicsBody属性设置为dynamic

然后,您可以使用false获取触摸所在的身体之一(physicsWorld.bodyAtPoint(_:)physicsWorld的属性)。使用正文的SKScene属性返回按钮节点。如果实体重叠,node将返回任意实体。

如果您需要触摸所有身体,可以使用bodyAtPoint

一种完全不同的方法,如果您可以创建一个描述按钮形状的physicsWorld.enumerateBodiesAtPoint(_:usingBlock:),则使用CGPath然后SKScene.convertPointFromView(_:)将该点转换为按钮&# 39; s坐标系,然后使用SKNode.convertPoint(_:fromNode:_)(一个全局函数)来检测该点是否在描述按钮形状的路径中。

答案 1 :(得分:0)

(我无法看到你的imgur链接,但我想我对你所描述的内容非常了解。)

some discussions on how to read the alpha value of out an SKTexture,但那些需要相当多的开销才能实现&#34;我是否触摸了平行四边形&#34;?特别是如果你为按钮添加alpha效果。

您可以在该位置执行您想要的任何逻辑 - 您有一个包含该位置的CGPoint,并且您知道按钮的大小和形状。

编写一个函数来测试点是否在平行四边形按钮内是非常简单的。由于平行四边形基本上是矩形,在内部&#34;内部的每一端都有三角形。如果你知道那个&#34;内部&#34;的大小。你可以很容易地确定触摸是否在你想要的位置:

  • 检查它是否在整个按钮的矩形中。如果没有,你知道它不在平行四边形中。

  • 检查它是否在&#34;内部&#34;矩形 - 带三角形的平行四边形的一部分&#34;切掉&#34;结局。如果是这样,那么你就知道它在平行四边形中。

  • 检查它是否在其中一个三角形内。您知道包含三角形的矩形中触摸的距离和距离有多远,并且您知道通过其宽度和高度划分该矩形以形成三角形的线的斜率。这使得检查点是否在三角形中是微不足道的 - 只需使用&#34; y = mx + b&#34;一条线的公式,其中m是斜率,b是你需要添加的任何东西,以使线穿过矩形的一角(通常是你的&#34; y截距&#34;)。如果y坐标小于/大于m *(x坐标)+ b,则可以确定触摸是在该三角形的内部还是外部。

拥有该功能后,您可以将其用作检查每个按钮的测试。