当多个精灵相互移动时如何处理它们的 zPositions?

How to handle multiple sprites' zPositions as they move around each other?

我是 Swift 的编程新手。我正在尝试创建一个游戏,其中有一堆精灵在屏幕上随机移动。假设我有一堆简单的 2D 图像精灵。当精灵向上移动时(因为在 y 位置增加)我希望它看起来向后移动到其他精灵后面,所以我希望 zPosition 与其他精灵相比减少。游戏如何处理这个问题?如果屏幕上有 100 个随机移动的精灵怎么办?我什至不太清楚这是如何处理的,所以任何帮助将不胜感激。

第二个更高级的概念。因此,假设每个精灵都有多层子精灵,如手臂、腿、衣服、武器等。(我的精灵是高度可定制的。)然后每个精灵随机四处走动,并且在它们移动到其他精灵后面时需要出现在正确的 zPosition 中精灵。我如何确保所有的手臂、腿、衣服和其他精灵层都正确地出现在每个其他精灵的前面或后面?如果我有一个有 20 层 sprite 子级的 sprite 并且它需要在其他有 20 个 sprite 子级的 sprite 前后无缝移动怎么办?这可能是错误的方向,但我能否以某种方式将一个精灵及其子层设为一层(或将所有左臂精灵设为一层,将右臂精灵设为另一层)?我看到了处理这个问题的游戏,但是处理这个问题的背后的概念是什么? (我看到的一款游戏就是 Fallout Shelter,每个人都有胳膊、腿、武器等,他们走在其他人的前面或后面,所有精灵都以正确的方式出现,但不像 Fallout庇护我的游戏具有完全平坦的 2D 图像,这就是我希望它保持的方式。)

第三个更高级的概念。如果我想让这些 sprite 像一个 sprite 的手臂抓住另一个 sprite 一样相互作用(所以一只手臂将在第二个 sprite 人的后面,但另一只手臂将完全在另一个 sprite 人的前面)怎么办?如何处理图层以显示在正确的 zPosition 中?也许这是不可能的?好的,我完成了。抱歉将一百万个问题放在一个 post 中。我正在寻找这些问题背后的概念,以便我可以开始规划和编程。谢谢你的帮助。

1) As a sprite move upwards (as in y position is increasing) I want it to appear to move further back behind other sprites, so I want the zPosition to decrease in comparison to the other sprites. How do games handle this?

这可以简单地通过创建自定义 class(我不建议扩展它)并将 zPosition 覆盖为 Y

的倒数来完成

例如

class Player : SKSpriteNode
{

    override var zPosition : CGFloat
    {
        get
        { 
             //Yes it looks weird to be setting zPosition on get, but we want to ensure the variable storing zPosition is also changed in case any property reads it
             super.zPosition = -super.position.y
             return super.zPosition
        }
        set
        {
            //do nothing
        }
    }
}

2)What if I have 100 sprites on the screen that are all moving around randomly?

覆盖这将处理屏幕上的每个精灵(在我的例子中是 'Player' 类型)y 位置决定 zPosition

3)How would I make sure all the arms, legs, clothes, and other layers of sprites appear correctly in front or behind every other sprite? Now this gets a little tricky. zPosition is relative to its parent, so you would need to account for how many layers deep your sprite can get zPosition wise, and plan accordingly. Say we have a sprite with shirt pants and a belt.

如果我们像这样构建精灵:
正文
->衬衫
->裤子
->腰带

然后我们可以将这些子节点的所有 zPosition 设置为 0,因为渲染顺序将使用 zPosition 后跟树顺序,并且不会发生任何变化:

但是如果我们这样构造它: 正文
->衬衫
->裤子
--->腰带

并且我们想要赋予衬衫在裤子和腰带之间的效果,那么我们需要通过将衬衫和腰带的 zPosition 设置为 1 来进行补偿。

4)What if I have a sprite with 20 layers of sprite children and it needs to move seamlessly in front and behind other sprites with 20 sprite children? Now we have a problem with battling other sprites, so we need to apply some math to our zPosition on the Player to fix it. class Player : SKSpriteNode {

    override var zPosition : CGFloat
    {
        get
        { 
             //Yes it looks weird to be setting zPosition on get, but we want to ensure the variable storing zPosition is also changed in case any property reads it
             super.zPosition = -super.position.y * 2 //(We need at least 2 zPosition slots reserved for every sprite)
             return super.zPosition
        }
        set
        {
            //do nothing
        }
    }
}

5)But can I somehow make one sprite and its children layers into 1 layer (or make all the left arm sprites into 1 layer and the right arm sprites into another layer)? 6) I see games that handle this, but what's the concept behind how this is handled? Yes, you can use view.texture(from:) to convert any node to a texture, then create a new sprite out of the texture.

7)What if I wanted these sprites to interact like one sprite's arms grab around another sprite (so one arm will be behind a second sprite person, but the opposite arm will be completely in front of the other sprite person 8)How are the layers handled to appear in the correct zPosition 9)Maybe this is not possible?

这部分现在变得棘手了,我们需要改变每个节点的 zPosition,而不是进行乘法运算。

我们还需要计算每个精灵的绝对位置,以了解我们在 y 轴上的位置

为此,我们至少有 3 个选择,
a) 我们可以为我们放置在场景中的每个节点制作自定义协议 + 自定义 classes b) 可以为我们放置在场景中的节点类型(例如 SKSpriteNode 和 SKShapeNode)编写扩展,但 SKNode 除外,因为它是基本节点 class c) 我们可以做一些叫做 Key Value Observation 的事情,我们需要监听 sprite 上的 position 何时发生变化。我们需要做 KVO 的原因是因为你的 sprite 可能是在你有 SKNodes 的地方构建的,我们不能覆盖它的位置。

所有这三种方法都需要大量的工作,并且需要针对您的游戏环境进行独特的优化,以有效 运行,我不打算详细介绍如何做到这一点。