【问题标题】:Touch through a node in SpriteKit通过 SpriteKit 中的节点触摸
【发布时间】:2014-04-11 21:34:16
【问题描述】:

所以我正在制作一款塔防游戏,让瓷砖板工作并且能够在一定程度上放置塔楼。

当玩家单击网格上方的按钮时,它将切换塔的位置,并允许玩家将塔放置在网格内的单元格上。然而,每个塔也有一个圆形的 ShapeNode 围绕它来处理对进入射击范围的小兵的检测。一旦我放置了这个形状节点,它就会在塔周围很好地显示出来。

我用来放置塔的逻辑是它找到您触摸的节点(称为“单元格”)并将其替换为塔节点。但是,如果塔节点附加了圆形节点并覆盖了它旁边的单元格,我无法选择圆形下方的单元格节点。

我将如何触摸“穿过”圆圈,或者将其填充空间设置为空,以便我可以访问它下面的单元格?

我仍在学习 sprite-kit,所以如果有更简单的方法,请随时为我指出正确的方向。

【问题讨论】:

  • 您是否将您的圆形节点的 userInteractionEnabled 属性设置为 false?如果您尚未更改此值,则默认情况下应为 false。如果为假,则该节点不应接收触摸。
  • 这可行,因为他们不再能够选择圆形节点,但它也不能解决用户无法在禁用节点下方选择的问题,因为它仍然是一个分层的节点顶部。

标签: ios sprite-kit touch-event skspritenode skshapenode


【解决方案1】:

如果您想在给定点找到一个节点,但不一定是最深的节点,您可以使用 SKNode 上的nodesAtPoint:,包括 SKScene。

这允许您查找场景的所有子节点,或与给定点相交的节点。然后,您可以进一步过滤它以找到您想要的特定节点,也许通过基于节点类或节点名称过滤数组。

如果使用 SKPhysicsWorld 中提供的方法 enumerateBodiesAtPoint:usingBlock: 在特定点寻找物理物体,可以应用类似的方法

值得注意的是,当使用 nodesAtPoint: 时,该点位于调用节点坐标系中,而 enumerateBodiesAtPoint:usingBlock: 将始终位于场景坐标系中。

【讨论】:

  • 这太棒了,就像一个魅力。由于我还是 SpriteKit 的新手,只是想知道一些基准。这是我关于如何创建塔的放置和视图逻辑的第一个想法,但可以看到随着更多东西添加到场景中,它开始稳定地开始滞后。
  • 嗨@nacross,你能看看我的问题吗?我遇到了与 enumarateBodiesAtPoint 类似的问题。赏金将在 4 天内结束。我尝试了所有 enumerateBodiesAt 方法,但都非常不准确,我不知道为什么stackoverflow.com/questions/24851309/…
  • 嗨@lisovaccaro,在我看来有某种错误,我很确定这个功能在过去可以正常工作,但最近尝试在新游戏中使用相同的功能并运行成问题。似乎有很多人遇到了这个问题。你可以在这里看到我的 cmets:devforums.apple.com/message/1003884#1003884
【解决方案2】:

没有看到您的任何相关代码,很难确定,但从您的描述来看,我认为您的问题与形状节点有关。我建议您使用塔的物理体,而不是使用形状节点来处理您的联系人。你仍然可以为你的塔拥有一个圆形的物理体,而无需添加一个全新的节点。删除形状节点也将解决您的交叉触摸干扰。

【讨论】:

  • 我也在想这可能是我正在寻找的解决方案,但我能否让玩家看到物理体,因为我希望他们能够看到半径塔将开火。
  • 为了简单起见,您可以考虑使用几个普通的 SKSpriteNode。每个都可以有不同大小的圆形图像(当然是 alpha 设置)。使 zPosition 足够低,以免干扰任何其他触摸项目。
  • 我喜欢你的想法和帮助,他们大开眼界。我将不得不玩弄在网格上分层的精灵。除非这从一开始就听起来是个坏主意,否则我还在考虑每次用户“选择”塔时创建和销毁圆形精灵节点,因此一次只会在屏幕上显示一个并且不可见,除非你告诉它出现。
  • 你绝对可以做到。这一切都归结为您如何设计代码并希望您的游戏流程/功能。祝你好运,编码愉快!
  • 我也有类似的问题。我有一层瓷砖(SKSpriteNodes)和一层用于调试的形状节点。形状节点层在屏幕外绘制到 SKNode 上,然后转换为纹理。然后将其作为顶部 z 定位节点覆盖在游戏上。考虑到我的情况,你会建议什么解决方案? =]
【解决方案3】:

TouchesBegan 会自动检测该位置的所有节点,您只需遍历它们即可。

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    for (UITouch *touch in touches)
    {
        CGPoint touchPoint = [touch locationInNode:self];
        NSArray *nodes = [self nodesAtPoint:touchPoint];

        if ([nodes count])
        {
            for (SKNode *node in nodes)
            {
                if ([node.name isEqualToString:@"cell"])
                {

                }
                else
                {

                }
            }
        }
    }
}

“self”作为开始接触的节点被调用(很可能是你的场景)。例如,您还可以按父对象对其进行过滤;如果将所有节点添加到名为“background”的父节点,则可以通过将“self”替换为背景节点(尽管这将导致它使用背景节点坐标),仅过滤到背景节点的子节点。

【讨论】:

  • 如果塔的节点是 SKSpriteNode 的子类,这不起作用
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多