# 分组
在你创建游戏场景时,可以给精灵们分组,作为一个整体管理。Pixi有一个名为Container
的对象,它可以把精灵们组合在一起。
假设您要显示三个精灵:一只猫,一只刺猬和一个老虎。创建并设置好它们的坐标——但不要将它们添加到舞台上。
//The cat
let cat = new Sprite(id["cat.png"]);
cat.position.set(16, 16);
//The hedgehog
let hedgehog = new Sprite(id["hedgehog.png"]);
hedgehog.position.set(32, 32);
//The tiger
let tiger = new Sprite(id["tiger.png"]);
tiger.position.set(64, 64);
2
3
4
5
6
7
8
9
10
11
然后,创建一个animals
容器(container)(用来把它们组合起来):
let animals = new PIXI.Container();
然后使用addChild
把它们三个添加到分组(group)
。
animals.addChild(cat);
animals.addChild(hedgehog);
animals.addChild(tiger);
2
3
最后,把这个分组添加到场景中。
app.stage.addChild(animals);
(stage
对象也是一个容器(container)
,它是所有Pixi精灵的根容器)
下面就是这段代码的效果:
如上图所示,您可以将animals
分组视为一个单元。把容器(Container)
视为一种不包含纹理的特殊精灵。
您可以用animals
的children
属性列出它包含的所有精灵。
console.log(animals.children)
//Displays: Array [Object, Object, Object]
2
你可以看到,animals
分组包含3个精灵。
因为animals
分组与精灵类似,所以它拥有精灵所有的属性,因此你可以改变它的x
、y
、alpha
、scale
等值。在父容器上更改的任何属性值都将以一种相对的方式影响子精灵。
因此,如果设置了分组的x
和y
坐标,则所有子精灵将相对于组的左上角重新定位。 请看下面,如果将动物的x
和y
坐标设置为64
,会发生什么?
animals.position.set(64, 64);
整个精灵分组将向右移动64个像素,向下移动64个像素。
animals
分组也有其自己的尺寸,该尺寸基于包含的精灵所占据的面积。 您可以查看它的width
和height
,如下所示:
console.log(animals.width);
//Displays: 112
console.log(animals.height);
//Displays: 112
2
3
4
5
如果改变分组的width
和height
会发生什么?
您可以将尽可能多的容器
嵌套到其他容器
中,以便在需要时创建多层结构。然而,一个可显示对象DisplayObject
(例如一个精灵
或另一个容器
)只能拥有一个父级。如果您使用addChild
使一个精灵成为另一个对象的子对象,Pixi将自动从当前父对象中删除它。
# 局部坐标和全局坐标
当您将一个精灵添加到容器
中时,它的x
和y
坐标相对于分组的左上角。x
和y
就是局部坐标。你知道猫在这幅图中的坐标吗?
让我们看一下:
console.log(cat.x);
//Displays: 16
2
16?是! 那是因为猫从该组的左上角仅偏移了16个像素。 16是猫的局部坐标。
精灵也有一个全局坐标。全局坐标是从舞台左上角到精灵的定位点(通常是精灵的左上角)的距离。你可以在使用toGlobal
方法查看一个精灵的全局坐标:
parentSprite.toGlobal(childSprite.position)
这意味着你可以像这样找到animals
分组中猫的全局坐标。
console.log(animals.toGlobal(cat.position));
//Displays: Object {x: 80, y: 80...};
2
x
和y
坐标是80。这就是猫的全局坐标相对于舞台左上角的坐标。
如果你想要查看一个精灵的全局位置,但又不知道它的父容器是谁,那怎么办呢?别急,每个精灵都有一个叫做parent
的属性,它会告诉你精灵的父容器是谁。如果您直接向舞台
添加一个精灵,那么舞台
将是精灵的父容器。在上面的例子中,猫的父容器是animals
。这意味着您可以通过编写这样的代码来获取猫的全局坐标。
cat.parent.toGlobal(cat.position);
即使你不知道猫的父容器是什么,你也能知道它的全局坐标。
还有一种方法可以计算全局坐标!这会是最好的一种方法,所以听好了!如果您想知道画布左上角到精灵的距离,而不知道或不关心精灵的父容器是什么,那么可以使用getGlobalPosition
方法。下面我们就用它来查看老虎的全局坐标。
tiger.getGlobalPosition().x
tiger.getGlobalPosition().y
2
这这个例子中,x和y值是128。getGlobalPosition
的特别之处在于它是高度精确的:它将在精灵的本地坐标发生变化时立即给出精灵的准确全局坐标。这是我要求Pixi开发团队专门为游戏添加的这一功能,以精确检测碰撞。(感谢Matt和团队的其他成员添加了它!)
如果要将全局坐标转换为本地坐标怎么办? 您可以使用toLocal
方法,如下所示:
sprite.toLocal(sprite.position, anyOtherSprite)
使用toLocal
查看精灵和其他精灵之间的距离。下面我们来看看老虎和刺猬的相对位置。
tiger.toLocal(tiger.position, hedgehog).x
tiger.toLocal(tiger.position, hedgehog).y
2
x
值是32,y
值是32。在示例图像中,可以看到老虎的左上角位于刺猬左上角向右、向下偏移32像素的位置。
# 使用粒子容器ParticleContainer对精灵进行分组
Pixi有另一种高性能的方式来组合精灵,称为粒子容器ParticleContaine
(PIXI.particles.ParticleContainer
)。任何在ParticleContainer
中的精灵渲染速度都比在常规容器中快2到5倍。这对于游戏来说是一个巨大的性能提升。
像这样创建一个ParticleContainer
:
let superFastSprites = new PIXI.particles.ParticleContainer();
然后使用addChild
向它添加精灵,就像使用任何普通容器
一样。
如果您决定使用ParticleContainer
,则必须做出一些妥协。ParticleContainer
中的精灵只有几个基本属性:x
、y
、width
、height
、scale
、pivot
、alpha
、'visible等等。而且,它所包含的精灵包含子元素。一个ParticleContainer
也不能使用Pixi的高级视觉效果,如过滤器和混合模式。每个ParticleContainer
只能使用一个纹理(所以如果你想要不同外观的精灵,你必须使用雪碧图)。但是为了获得巨大的性能提升,这些妥协是随处可见的。
为什么精灵在粒子容器
中的速度如此之快?因为精灵的位置是直接在GPU上计算的。你正在使用的最新版本的Pixi很可能比我在这里描述的有更多的特性丰富的ParticleContainer
。有关详细信息,请参阅当前ParticleContainer文档。
在创建ParticleContainer
的时候,有四个可选参数:size
、properties
、batchSize
和autoResize
。
let superFastSprites = new ParticleContainer(maxSize, properties, batchSize, autoResize);
maxSize
的默认值为1500。因此,如果想要显示更多的sprite,请将其设置为更大的数字。 properties
参数是一个可以设置5个布尔值的对象:scale
, position
, rotation
, uvs
和alphaAndTint
。 position
的默认值为true
,但其他所有值均设置为false
。 这意味着,如果您想在ParticleContainer中更改子画面的rotation
,scale
,tint
或uvs
,则必须将这些属性设置为true
,如下所示:
let superFastSprites = new ParticleContainer(
size,
{
rotation: true,
alphaAndtint: true,
scale: true,
uvs: true
}
);
2
3
4
5
6
7
8
9
但是,如果您认为不需要使用这些属性,请将它们设置为false
可以最大限度地发挥性能。
什么是uv
属性?只有当粒子需要在动画中改变纹理时,才将它设置为true
。(所有的精灵的纹理必须在同一个雪碧图上)
(注意:UV映射
是3D图形显示术语,指的是被映射到3D表面上的纹理(图像)的x
和y
坐标。U
是x
轴,V
是y
轴。WebGL已经使用 x
,y
和z
用来表示3D空间位置,因此选择U
和V
表示2D图像纹理的x
和y
。)