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)

它仅检测路径上的点,而不检测内部的点。

如何使这成为可能?

谢谢

4

2 回答 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 开始,并且您的形状具有负值。

为了显示我的菱形,我可以简单地将场景锚点更改为:

 self.anchorPoint = CGPointMake(0.5,0.5)

这将场景的原点居中在视图的中间(Apple docs),您可以看到您的图块:

在此处输入图像描述

现在假设您想知道一个点是否在您的形状内:

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

在此处输入图像描述

现在我们可以检查这个点是否在菱形内部:

let isometricPathRef = isometricPath as CGPathRef
print(CGPathContainsPoint(isometricPathRef, nil, locationInNode, true))

输出

在此处输入图像描述

于 2016-08-29T12:35:35.927 回答
0

感谢您的详细回答亚历山德罗奥纳诺。场景的起源是一个很好的提示。问题出在我程序的另一部分没有发布。我的场景中有几个等距图块重叠,我试图找出触摸点落在哪一个上。我的意图是遍历所有触摸元素touches: Set<UITouchtouchesEnded测试每个元素是否触摸落在等距路径内。

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 位置最高的元素进行测试,但由于瓷砖非常小,对我来说它看起来只会测试路径的笔划(非常混乱)。

所以无论如何,我尝试获取所有触摸瓷砖的元素的方式有问题。所以你的答案是对的,第一次发布的代码没有错。

于 2016-08-29T13:44:47.310 回答