Swift Spritekit isometric map touch location

好久不见. 提交于 2019-12-03 07:32:51
Heyfara

I had a similar issue with isometric map.

The problem is that the node you click on is bigger than displayed (it has transparent parts). See my question here for a better explanation of the issue.

Here is how I solved it (sorry code is in Objective-C) :

1.Create a CGPathRef following the edges of the tile (tileSize being the size of the texture). This code is for regular isometric tiles, not hexagonal but the idea is the same.

// ObjC
-(CGPathRef)createTextureFrame:(CGSize)tileSize
{
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathMoveToPoint(path, NULL, 0, -(self.tileSize.height / 2));
    CGPathAddLineToPoint(path, NULL, (self.tileSize.width / 2), 0);
    CGPathAddLineToPoint(path, NULL, 0, (self.tileSize.height / 2));
    CGPathAddLineToPoint(path, NULL, -(self.tileSize.width / 2), 0);
    CGPathCloseSubpath(path);
    return path;
}

// Swift
func createTextureFrame(tileSize:CGSize) -> CGPathRef {
    CGMutablePathRef path = CGPathCreateMutable()
    CGPathMoveToPoint(path, nil, 0, -(self.tileSize.height / 2))
    CGPathAddLineToPoint(path, nil, (self.tileSize.width / 2), 0)
    CGPathAddLineToPoint(path, nil, 0, (self.tileSize.height / 2))
    CGPathAddLineToPoint(path, nil, -(self.tileSize.width / 2), 0)
    CGPathCloseSubpath(path)
    return path
}

2.Create a function that checks if a given point is inside the CGPathRef (textureFrame).

// ObjC
-(BOOL)isPointOnNode:(CGPoint)point
{
    return CGPathContainsPoint(textureFrame, NULL, point, YES);
}

// Swift
func isPointOnNode(point:CGPoint) -> Bool {
    return CGPathContainsPoint(textureFrame, nil, point, YES)
}

3.For each touched nodes, check which textureFrame we're in.

// ObjC
UITouch *touch = [touches anyObject];
NSArray *nodes = [self nodesAtPoint:[touch locationInNode:self]];
for (SKNode *node in nodes)
{
    CGPoint locationInNode = [touch locationInNode:node];
    if ([node isPointOnNode:locationInNode])
    {
        node.hidden = YES;
    }
}

// Swift
var touch = touches.anyObject() as UITouch
var nodes = self.nodesAtPoint(touch.locationInNode(self))
for node in nodes as [SKNode] {
    var locationInNode = touch.locationInNode(node)

    if node.isPointOnNode() {
        node.hidden = true
    }
}

I do not know if it's the best solution but it works great. I hope it helps :)

Edit : Added Swift version of the code

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!