检测等距纹理上的单击/触摸

时间:2014-03-22 14:02:28

标签: sprite-kit isometric

我很难在简单的等距Sprite Kit游戏中尝试实现点击处理。

我有一个带有多个Tile对象的地图(SKNode)的游戏场景(SKScene)(SKSpriteNode)。

以下是地图的截图:

enter image description here

我希望能够检测到用户点击的磁贴,因此我在Tile对象上实现了mouseDown。这是我在Tile.m中的mouseDown:

-(void)mouseDown:(NSEvent *)theEvent
{
    [self setColorBlendFactor:0.5];
}

代码似乎工作正常,但有一个小故障:节点重叠,并在节点的透明部分检测到click事件。示例(已添加rects以仅说明问题。它们未在逻辑中使用):

enter image description here

如您所见,如果我点击图块7的左上角,则图块8变为透明。

enter image description here

我试过在点击位置获取所有节点并检查点击是否在CGPath内部没有成功(我认为坐标有问题)。

所以我的问题是如何检测纹理上的点击而不是透明部分?或许我对问题的解决方法是错误的?

任何建议都将不胜感激。

对于我最终使用的解决方案感兴趣的任何人,

修改,请参阅my answer here

3 个答案:

答案 0 :(得分:2)

我现在解决这个问题的方法是:

    在场景中
  • 获取点击该位置的所有节点,即[myScene nodesAtPoint:[theEvent lactionInNode:myScene]]
  • 不要忘记检查您是否未点击场景的根目录 类似的东西:if(![[myScene nodeAtPoint:[theEvent locationInNode:myScene]]。name isEqual:@“MyScene”]) 然后浏览可能的节点数组并检查纹理的alpha(不是myNode.alpha)
  • 如果alpha为0.0f,则转到数组的下一个节点
  • 选择alpha不是0.0f的第一个节点并返回节点名称
  • 通过这种方式,您可以找到您的节点(第一个)并将其保存为您需要的节点,并终止您不再需要的阵列
  • 比你想要的节点
  • btw在搜索其名称后检查您要使用的新节点是否为nil。如果那是真的,那就突破你的moveDown方法

要获得alpha try this

我看起来像那样:

-(void)mouseDown:(NSEvent *)theEvent {
     /* Called when a mouse click occurs */
    if (![[self nodeAtPoint:[theEvent locationInNode:self]].name isEqual: self.name]]) {

        /* find the node you clicked */
        NSArray *clickedNodes = [self nodesAtPoint:[theEvent locationInNode:self]];

        SKNode *clickedNode = [self childNodeWithName:[clickedNodes getClickedCellNode]];

        clickedNodes = nil;

        /* call the mouseDown method of your Node you clicked to to node specific actions */
        if(clickedNode) {
           [clickedNode mouseDown:theEvent];
        }
        /* kill the pointer to your clicked node */
        clickedNode = nil;
    }
}

答案 1 :(得分:0)

我有一些问题,错误SKPhysicsWorld enumerateBodiesAtPoint。 但我找到了我的解决方案,它也适合你。 1.创建平铺路径(您的路径4点) 2抓住触摸并将点转换为您的切片节点 3如果触摸点内部形状节点 - 赢!

CODE:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

selectedBuilding = nil;

NSArray *nodes = [farmWorldNode nodesAtPoint:point];
if (!nodes ||  nodes.count == 0 || nodes.count == 1) {
    return;
}

NSMutableArray *buildingsArray = [NSMutableArray array];

int count = (int)nodes.count;
for (int i = 0; i < count; i++) {

    SKNode *findedBuilding = [nodes objectAtIndex:i];

    if ([findedBuilding isKindOfClass:[FBuildingBaseNode class]]) {
        FBuildingBaseNode *building = (FBuildingBaseNode *)findedBuilding;

        CGPoint pointInsideBuilding = [building convertPoint:point fromNode:farmWorldNode];

        if ([building.colisionBaseNode containsPoint:pointInsideBuilding]) {
            NSLog(@"\n\n Building %@ \n\n ARRAY: %@ \n\n\n", building, findedBuilding);
            [buildingsArray addObject:building];
        }


    }
}

selectedBuilding = (FBuildingBaseNode *)[buildingsArray lastObject];


buildingsArray = nil;

}

答案 2 :(得分:0)

对于像你这样的简单几何图形,一种解决方法是在您的钻石顶部叠加隐形SKShapeNodes,并注意它们的触摸(不适用于skspritenode)。

如果仍然无效,请确保使用“fromPolygon:myNode.path!”创建SKPhysicsBody。选项...