Swift - 如何填充路径(不透明路径)
Swift - how to fill a path (opaque path)
我有一条路径,它的形状应该是等距瓷砖:
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)
它只检测路径上的点而不是内部的点。
如何做到这一点?
谢谢
您的代码是正确的,但您可能应该查看场景的来源。你确定你能看到你的形状吗?
默认情况下,场景的原点位于视图的左下角。因此,默认场景初始化为高 1024,宽 768,原点 (0,0) 位于左下角,坐标 (1024,768) 位于右上角。框架 属性 持有 (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)
这使场景的原点在视图中间居中 (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))
输出:
感谢 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 位置最高的元素进行测试,但因为瓷砖非常小,对我来说它看起来只会测试路径的笔画(非常混乱).
所以不管怎样,我尝试获取所有触摸的 Tiles 的元素的方式有问题。所以你的回答是对的,第一次贴的代码没有问题。
我有一条路径,它的形状应该是等距瓷砖:
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)
它只检测路径上的点而不是内部的点。
如何做到这一点?
谢谢
您的代码是正确的,但您可能应该查看场景的来源。你确定你能看到你的形状吗?
默认情况下,场景的原点位于视图的左下角。因此,默认场景初始化为高 1024,宽 768,原点 (0,0) 位于左下角,坐标 (1024,768) 位于右上角。框架 属性 持有 (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)
这使场景的原点在视图中间居中 (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))
输出:
感谢 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 位置最高的元素进行测试,但因为瓷砖非常小,对我来说它看起来只会测试路径的笔画(非常混乱).
所以不管怎样,我尝试获取所有触摸的 Tiles 的元素的方式有问题。所以你的回答是对的,第一次贴的代码没有问题。