Ios 在Sprite纹理中检测触摸,而不是整个帧?

Ios 在Sprite纹理中检测触摸,而不是整个帧?,ios,swift,sprite-kit,skspritenode,Ios,Swift,Sprite Kit,Skspritenode,我现在正在使用SpriteKit,我遇到了一个看似简单的问题,但我在互联网上找不到任何东西。我有三个按钮,形状像平行四边形,彼此叠在一起,看起来像这样: let button=SKSpriteNode(图像名为:“播放按钮”) 让leaderButton=SKSpriteNode(图像名为:“leaderButton”) 让homeButton=SKSpriteNode(图像名为:“homeButton”) button.position=CGPoint(x:size.width/2,y:si

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

let button=SKSpriteNode(图像名为:“播放按钮”)
让leaderButton=SKSpriteNode(图像名为:“leaderButton”)
让homeButton=SKSpriteNode(图像名为:“homeButton”)
button.position=CGPoint(x:size.width/2,y:size.height/2)
addChild(按钮)
leaderButton.position=CGPoint(x:size.width/2,y:size.height/2-按钮.size.height/2)
addChild(引线按钮)
homeButton.position=CGPoint(x:size.width/2,y:size.height/2-button.size.height)
addChild(主页按钮)
覆盖功能触摸开始(触摸:设置,withEvent事件:UIEvent?){
用于触摸:触摸中的任何对象{
let location=touch.locationInNode(自)
if按钮。containsPoint(位置){
button.runAction(SKAction.scaleTo(0.8,持续时间:0.1))
}
否则,如果引线按钮包含点(位置){
leaderButton.runAction(SKAction.scaleTo(0.8,持续时间:0.1))
}
如果homeButton.containsPoint(位置),则为else{
homeButton.runAction(SKAction.scaleTo(0.8,持续时间: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))
        }
    }
}
button.position=CGPoint(x:size.width/2,y:size.height/2)
button.physicsBody=SKPhysicsBody(纹理:SKTexture(ImageName:“playbutton”),大小:button.size)
按钮.physicsBody?.dynamic=false
addChild(按钮)
leaderButton.position=CGPoint(x:size.width/2,y:size.height/2-按钮.size.height/2)
leaderButton.physicsBody=SKPhysicsBody(纹理:SKTexture(图像名称:“leaderButton”),大小:leaderButton.size)
引线按钮.physicsBody?.dynamic=false
addChild(引线按钮)
homeButton.position=CGPoint(x:size.width/2,y:size.height/2-button.size.height)
homeButton.physicsBody=SKPhysicsBody(纹理:SKTexture(图像名称:“homeButton”),大小:homeButton.size)
homeButton.physicsBody?.dynamic=false
addChild(主页按钮)
覆盖功能触摸开始(触摸:设置,withEvent事件:UIEvent?){
用于触摸:触摸中的任何对象{
let location=touch.locationInNode(自)
如果physicsWorld.bodyAtPoint(位置)?.node==按钮{
button.runAction(SKAction.scaleTo(0.8,持续时间:0.1))
打印(“播放”)
}
如果physicsWorld.bodyAtPoint(位置)?.node==引线按钮{
leaderButton.runAction(SKAction.scaleTo(0.8,持续时间:0.1))
打印(“领导”)
}
如果physicsWorld.bodyAtPoint(位置)?.node==homeButton{
homeButton.runAction(SKAction.scaleTo(0.8,持续时间:0.1))
}
}
}

它仍然记录了整个画面,而不仅仅是物理体。查看链接以查看按钮及其坐标的相交方式。

如果将物理实体连接到每个按钮,则可以检测您的触摸碰到的物理实体

您可以使用
SKPhysicsBody(纹理:大小:)
SKPhysicsBody(纹理:alphaThreshold:size:)
从按钮的纹理(假设按钮是
SKSpriteNode
)生成物理实体,或者您可以创建描述按钮形状的
CGPath
,并使用
SKPhysicsBody(polygonFromPath:)
。将主体指定给按钮的
physicsBody
属性。假设您实际上不希望物理模拟器移动按钮,请将每个实体的
动态属性设置为
false

然后,您可以使用
physicsWorld.bodyAtPoint(:)
来获取一个触控对象(其中
physicsWorld
是您的
SKScene
的属性)。使用主体的
节点
属性返回按钮节点。如果实体重叠,
bodyAtPoint
返回任意实体

如果需要触摸所接触到的所有实体,可以使用
physicsWorld.EnumerateSboideStatPoint(\uU:usingBlock:)

如果您可以创建一个描述按钮形状的
CGPath
,则完全不同的方法是使用
SKScene.convertPointFromView(:)
,然后使用
SKNode.convertPoint(:fromNode:)
将点转换为按钮的坐标系,然后使用
CGPathContainsPoint
(一个全局函数)检测点是否位于描述按钮形状的路径中。

(我看不到您的imgur链接,但我想我对您所描述的内容有很好的了解。)

有,但这些需要相当多的开销,只是“我碰到了一个平行四边形吗”?尤其是在按钮上添加alpha效果时

你可以在位置上做任何你想要的逻辑-你有一个包含位置的CGPoint,你知道你的按钮的大小和形状

编写一个函数来测试一个点是否位于平行四边形按钮内应该非常简单。由于平行四边形基本上是在“内”矩形两端各有三角形的矩形,如果您知道“内”矩形的大小,您可以很容易地通过以下方式确定触摸是否在您想要的位置:

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

  • 检查它是否在“内部”矩形内——平行四边形的两端有三角形“截断”的部分。如果是的话,那么哟
        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))
            }
        }
    }