Swift - 如何填充一个路径(不透明路径)

3

我有一个路径,应该呈等角瓷砖形状:

                let isometricPath = CGPathCreateMutable()
                CGPathMoveToPoint(isometricPath, nil, 0, -(tileSize.height / 2))
                CGPathAddLineToPoint(isometricPath, nil, (tileSize.width / 2), 0)
                CGPathAddLineToPoint(isometricPath, nil, 0, (tileSize.height / 2))
                CGPathAddLineToPoint(isometricPath, nil, -(tileSize.width / 2), 0)
                CGPathCloseSubpath(isometricPath)

我尝试使用以下代码将其变为不透明路径:

let isometricPathRef = isometricPath as CGPathRef

但如果我想要检查一个CGPoint是否在该路径内,可以使用以下代码:
CGPathContainsPoint(isometricPathRef, nil, locationInNode, true)

它只能检测到路径上的点而无法检测到内部的点。

如何实现这一点?

谢谢。

2个回答

2
您的代码是正确的,但您应该查看场景的起源。您确定您能看到您的形状吗?
默认情况下,场景的原点位于视图的左下角。因此,默认场景初始化高度为1024,宽度为768,原点(0,0)位于左下角,(1024,768)坐标位于右上角。frame属性保持(0,0)-(1024,768)。
假设您使用您的问题代码的以下示例:
let tileSize = CGSizeMake(150.0,150.0)
// Your code:
let isometricPath = CGPathCreateMutable()
CGPathMoveToPoint(isometricPath, nil, 0, -(tileSize.height / 2))
CGPathAddLineToPoint(isometricPath, nil, (tileSize.width / 2), 0)
CGPathAddLineToPoint(isometricPath, nil, 0, (tileSize.height / 2))
CGPathAddLineToPoint(isometricPath, nil, -(tileSize.width / 2), 0)
CGPathCloseSubpath(isometricPath)

这条路径代表了一个菱形的形状。
现在,如果我想画出这个形状,我可以这样做:
let shape = SKShapeNode.init(path: isometricPath)
shape.strokeColor = SKColor.yellowColor()
shape.fillColor = SKColor.blueColor()
self.addChild(shape)

但是没有任何东西显示出来,因为我的场景原点从0.0开始,而你的形状有负值。
要显示我的菱形,我只需将场景的anchorPoint更改为:
 self.anchorPoint = CGPointMake(0.5,0.5)

这将场景的原点置于视图中心(苹果文档),您可以看到您的瓦片:

enter image description here

现在假设您想知道一个点是否在您的形状内:
let locationInNode = CGPointMake(tileSize.width/15,tileSize.height/15)
// this point is definitely inside the rhombus

我想简单地展示这个点以进行调试:
let circle = SKShapeNode.init(circleOfRadius: 5)
circle.strokeColor = SKColor.whiteColor()
circle.fillColor = SKColor.whiteColor()
self.addChild(circle)
circle.position = locationInNode

enter image description here

现在我们可以检查这个点是否在菱形内:
let isometricPathRef = isometricPath as CGPathRef
print(CGPathContainsPoint(isometricPathRef, nil, locationInNode, true))

Output:

enter image description here


好主意Alessandro Ornano。在我的问题中,我没有清楚地表明等角路径不是在场景的某个地方,而是通过创建一个类似于等角瓷砖的路径来检查触摸位置是否落在等角瓷砖内部。该瓷砖的锚点为(0.5,0.5),恰好位于Sprite的中心。这是我的错误,抱歉:( - frankibanki

0

感谢您详细的回答,Alessandro Ornano。场景的起源是一个很好的提示。问题出现在我的程序的另一个部分,这一点我没有发布。我的场景中有几个等距瓷砖重叠在一起,我试图找出触摸落在哪一个上面。我的意图是在touchesEnded中遍历所有的触摸元素touches: Set<UITouch,并测试每个元素是否在等距路径内或外。

for actualTouch in touches
        {
            let SKnode = self.nodeAtPoint(actualTouch.locationInNode(self))
            let spriteNode = SKnode as! SKSpriteNode
            if spriteNode.name != nil{
                let tileSize = CGSizeMake(75, 38)
                let locationInNode = actualTouch.locationInNode(SKnode)

                let isometricPath = CGPathCreateMutable()
                CGPathMoveToPoint(isometricPath, nil, 0, -(tileSize.height / 2))
                CGPathAddLineToPoint(isometricPath, nil, (tileSize.width / 2), 0)
                CGPathAddLineToPoint(isometricPath, nil, 0, (tileSize.height / 2))
                CGPathAddLineToPoint(isometricPath, nil, -(tileSize.width / 2), 0)
                CGPathCloseSubpath(isometricPath)
                let isometricPathRef = isometricPath as CGPathRef



                if CGPathContainsPoint(isometricPathRef, nil, locationInNode, true) == true
                {
                    print("touchedTile:\(spriteNode.name!)")
                    spriteNode.alpha = 1
                }

            }
        }

问题在于:它只获取测试中具有最高z位置的元素,但由于瓷砖非常小,对我来说看起来只会测试路径的笔画(非常令人困惑)。
所以无论如何,我尝试获取所有触摸瓷砖的元素的方式存在问题。因此,您的答案是正确的,第一个发布的代码没有任何问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接