我有一条应该具有等距瓷砖形状的路径:
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)
它仅在路径上检测点,但不在内部。
如何做到这一点?
由于
答案 0 :(得分: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)
这会将场景的原点置于视图中间(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))
<强>输出强>:
答案 1 :(得分:0)
感谢您详细解答Alessandro Ornano。场景的起源是一个很好的暗示。问题出在我的程序的另一部分没有发布。我的场景中有几个等距的瓷砖重叠,我试图弄清楚哪一个触摸着陆。我的目的是迭代touches: Set<UITouch
中的所有触摸元素touchesEnded
并测试每个元素,如果触摸是否在等距路径内。
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的元素的方式有问题。所以你的回答是对的,第一个发布的代码没有任何问题。