从物体前面经过时的 Spritekit 剪影效果

Spritekit silhouette effect when passing in front of object

我正在开发一个 sprite 工具包游戏,并且我正在尝试创建一个特定的剪影照明效果,每当对象经过特定对象(在本例中为红色太阳)的前面时。我希望它前面的任何东西都显示为黑色,而其他所有东西都显示为正常(因此,如果一个物体部分位于前面,则只有该部分应该是黑色的)。 但我不确定如何以有效的方式做到这一点。我试过使用不同的 SKBlendModes,但到目前为止还没有取得太大的成功。主要的挑战似乎是在保持背后太阳的颜色的同时实现效果。

我不确定是否可以使用现有的 SKBlendModes 实现这一点,或者是否需要其他东西。

我附上了一张图表来说明我要做什么以及一张当前最合适的图片。

这个问题对我来说很有趣,所以我想出了一个简单的解决方案。它并不完美,也不能很好地扩展,但我相信它的基础知识可以满足您的需求,并且可以为其他人指明正确的方向。

我没有使用任何特殊的 SKBlendMode。相反,我为在太阳前面移动的物体使用了一个重复的物体。使用 SKCropNode 和太阳的副本作为 maskNode 裁剪这个重复的对象。所以,我的节点树如下:

  • SKSpriteNode(sun)(白太阳)
  • SKSpriteNode (object1)(alpha 0.25的旋转紫色方块)
  • SKCropNode
    • maskNode: SKSpriteNode (sunDuplicate = [sun copy])
    • SKSpriteNode(object1duplicate,大小与object1相同,但有[SKColor blackColor]

在更新方法中,将副本与原始对齐以确保正确转发动画。

- (void)update:(CFTimeInterval)currentTime {
  self.object1duplicate.position = self.object1.position;
  self.object1duplicate.zRotation = self.object1.zRotation;
}

正如我所说,这不能很好地扩展,因为您必须手动添加重复对象并跟踪在太阳对象前面移动的每个对象。也许 SKShader 可以更优雅地使用。

您可以使用 SKCropNode、遮罩节点和背景节点创建剪影效果。 SKCropNode 有选择地屏蔽其节点树中精灵节点的像素。在这里,它将提供 hiding/revealing 部分黑色圆圈的剪影效果。

首先,创建以下对象:

  1. 一个形状节点(黄色圆圈),其 zPosition 设置为 -1
  2. 与黄色相同大小的精灵节点(黑色圆圈)
  3. 裁剪节点(SKCropNode)和遮罩节点(SKNode

接下来,

  1. 在场景中心添加黄色圆圈
  2. 将黑色精灵添加为裁剪节点的子节点
  3. 将mask节点赋给crop节点maskNode属性
  4. 在场景中心添加裁剪节点

由于遮罩节点目前没有子节点,黑色圆圈将被完全隐藏,其下方的整个黄色圆圈将可见。当我们将 sprite 添加到遮罩节点时,与 sprite 相交的黑色圆圈的像素将被取消遮罩(显示为黑色),从而产生剪影效果。

剩下的就是添加一个"presentation"节点,当遮罩节点的精灵在黑色圆圈之外时,该节点将显示。展示节点将镜像遮罩节点精灵的位置和旋转。这应该在 didSimulatePhysics 中完成,以确保在物理和动作更新后呈现和掩码节点精灵同步。

但是等等...如果演示节点移动到黄色圆圈上方,它不会遮住太阳吗?如果我们将其表示节点的 zPosition 设置为 -2.

则不会

下面显示了上面的实现: