画布层

Viewport(视窗)和 Canvas Item(画布项)

CanvasItem 是所有 2D 节点的基类,无论是 Node2D 等普通 2D 节点,还是 Control 控件节点。它们都继承自 CanvasItem。你可以把画布项组织成树。每个项目都会继承父节点的变换:父节点移动,子项也会移动。

CanvasItem 节点和继承他们的节点,都是 Viewport 的直接或间接子节点,并将通过它来显示。

Viewport 具有属性 Viewport.canvas_transform, 它允许对它所包含的 CanvasItem 层级施加一个自定义的 Transform2D 变换。Camera2D 等节点的工作原理就是修改这个变换。

像滚动这样的效果最好是通过操纵画布的变换(transform)属性来实现。这种方法比移动根画布项和整个场景更有效。

通常情况下,我们并不希望游戏或应用程序中的所有东西都受到画布变换的约束。比如:

  • 视差背景:比场景其他部分移动得慢的背景。

  • UI:想想看,用户界面(UI)或平视显示系统(HUD)叠加在我们游戏世界的视图上。我们希望生命计数器、分数显示和其他元素能够保持其屏幕位置,即使我们在游戏世界的视角发生变化。

  • 转场:我们应该希望用于转场的效果(淡入淡出、混合)也保持在固定的位置。

如何在单个场景树中解决这些问题?

CanvasLayer

答案是画布层 CanvasLayer,它是一个节点,可以为所有子代和孙代添加一个单独的 2D 渲染层。Viewport 的子节点默认在图层“0”处绘制,而 CanvasLayer 将在任何数字层处绘制。数字较大的图层将绘制在数字较小的图层之上。CanvasLayer 也有自己的变换,不受其他层的影响。这使得当我们对游戏世界的观察发生变化时,UI 可以固定在屏幕空间中。

一个例子是创建视差背景(Parallax Background)。这可以通过层为“-1”的 CanvasLayer 完成。带有分数、生命计数器和暂停按钮的屏幕也可以创建在编号为“1”的层中。

下面是它的图示:

../../_images/canvaslayers.png

CanvasLayer 独立于树顺序, 它们仅依赖于它们的层数, 因此可以只在需要时让它们实例化.

备注

控制节点的绘制顺序并不一定要用 CanvasLayer。确保节点被正确绘制在“前面”或“后面”的标准方法是操作场景面板中节点的顺序。也许违反直觉,但在视口中,场景面板中较上面的节点会被画在较下面的节点的后面。2D 节点也有控制其绘图顺序的属性(请参阅 Node2D.z_index)。