# sprites(精灵)stage(舞台)

现在您已经有了一个渲染器,可以开始向其中添加图像了。任何你想要在渲染器中可见的东西都必须添加到一个特殊的Pixi对象中,这个对象叫做stage(舞台)。您可以像这样访问这个特殊的stage(舞台)对象:

app.stage
1

stage(舞台)是Pixi的Container(容器)对象。你可以把一个Container(容器)想象成一种空盒子,它会把你放进去的东西组合在一起并储存起来。stage(舞台)对象是场景中所有可见事物的根容器。你在stage(舞台)里放的任何东西都会在canvas画面上渲染出来。现在stage(舞台)是空的,但很快我们就会开始把东西放进去。(您可以在这里阅读关于Pixi的Container(容器)对象的更多信息)。

(重要:因为stage(舞台)是一个PixiContainer(容器),所以它具有与任何其他Container(容器)对象相同的属性和方法。但是,尽管stage(舞台)具有widthheight属性,它们并不涉及呈现窗口的大小。舞台的有widthheight属性只是告诉你它的面积!)

sprite(精灵)是一种的特殊图像对象。您可以控制它们的位置、大小和其他属性。学习制作和控制sprite(精灵)非常重要。如果你知道如何制作sprite(精灵)并将它们添加到舞台上,你离开始制作游戏就只有一小步了。

你需要使用Pixi的Sprite类来创建精灵。创建方法有三种:

  • 通过单个图像文件。
  • 通过雪碧图
  • 通过纹理贴图

在您学习创建它们之前,您需要了解下面的内容。

# 加载图像到纹理缓存

因为Pixi使用WebGL在GPU上渲染图像,图像需要转换为GPU可以处理的东西,这个东西被称为texture(纹理)。为保证快速高效,Pixi使用texture cache(纹理缓存)来存储和引用你的精灵需要的所有纹理。texture(纹理)的名称就是引用图像的文件的路径。这意味着,如果您有一个从“images/cat.png”加载的纹理,那么你可以通过下面的方式找到它:

PIXI.utils.TextureCache["images/cat.png"];
1

texture(纹理)以WebGL兼容的格式存储,这对于Pixi渲染器来说也是有效的。你可以利用这个texture(纹理),使用Pixi的Sprite类创建精灵。

let texture = PIXI.utils.TextureCache["images/anySpriteImage.png"];
let sprite = new PIXI.Sprite(texture);
1
2

但是如何加载图像文件并将其转换为纹理呢?使用Pixi的内置loader(加载器)对象。

Pixi强大的loader(加载器)对象可以加载任何类型的图像。下面介绍如何使用它来加载图像,以及加载完成时调用一个名为setup的函数:

PIXI.loader
  .add("images/anyImage.png")
  .load(setup);

function setup() {
  //This code will run when the loader has finished loading the image
}
1
2
3
4
5
6
7

Pixi的开发团队建议,如果你使用loader(加载器),你应该通过引用loaderresources对象中的纹理来创建精灵,就像这样:

let sprite = new PIXI.Sprite(
  PIXI.loader.resources["images/anyImage.png"].texture
);
1
2
3

下面是一些完整的代码示例,您可以编写这些代码来加载图像、调用setup函数并从加载的图像创建精灵:

PIXI.loader
  .add("images/anyImage.png")
  .load(setup);

function setup() {
  let sprite = new PIXI.Sprite(
    PIXI.loader.resources["images/anyImage.png"].texture
  );
}
1
2
3
4
5
6
7
8
9

这是我们将在本教程中使用的加载图像和创建精灵的一般格式。

你通过链接调用add方法加载多张图片:

PIXI.loader
  .add("images/imageOne.png")
  .add("images/imageTwo.png")
  .add("images/imageThree.png")
  .load(setup);
1
2
3
4
5

更好的方法是,调用一个add方法来加载数组中的图片:

PIXI.loader
  .add([
    "images/imageOne.png",
    "images/imageTwo.png",
    "images/imageThree.png"
  ])
  .load(setup);
1
2
3
4
5
6
7

loader(加载器)还允许您加载JSON文件。

# 显示精灵

加载图像并使用它创建精灵之后,需要使用Pixi的stage.addChild方法把它添加到PIXI的stage中:

app.stage.addChild(cat);
1

记住,stage是容纳所有精灵的主要容器。

重要提示

你不会看到未添加进state(舞台)上的精灵

在我们继续之前,让我们来看一个实际示例。使用您刚刚学习的内容来展示一只小猫。在examples/images文件夹下,你需要有一个大小为64*64像素,格式为PNG的小猫咪图片:

下面就是加载图像,创建一个精灵,并显示在Pixi的舞台上所需要的全部的avaScript代码:

//Create a Pixi Application
let app = new PIXI.Application({ 
    width: 256, 
    height: 256,                       
    antialias: true, 
    transparent: false, 
    resolution: 1
  }
);

//Add the canvas that Pixi automatically created for you to the HTML document
document.body.appendChild(app.view);

//load an image and run the `setup` function when it's done
PIXI.loader
  .add("images/cat.png")
  .load(setup);

//This `setup` function will run when the image has loaded
function setup() {

  //Create the cat sprite
  let cat = new PIXI.Sprite(PIXI.loader.resources["images/cat.png"].texture);
  
  //Add the cat to the stage
  app.stage.addChild(cat);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

这段代码运行时,你将会看到:

如果您需要从舞台上删除一个精灵,请使用removeChild方法:

app.stage.removeChild(anySprite)
1

但是通常将精灵的visible属性设置为false是使精灵消失的一种更简单、更有效的方法。

anySprite.visible = false;
1

# 使用别名

通过为您经常使用的Pixi对象和方法创建简短的别名,您可以节省一些输入,并使您的代码更具可读性。下面是如何创建TextureCache对象的别名的一个示例:

let TextureCache = PIXI.utils.TextureCache
1

然后,用这个别名代替原来的别名,就像这样:

let texture = TextureCache["images/cat.png"];
1

让我们重新编写加载和显示图像的代码,使用所有Pixi对象和方法的别名。

//Aliases
let Application = PIXI.Application,
    loader = PIXI.loader,
    resources = PIXI.loader.resources,
    Sprite = PIXI.Sprite;

//Create a Pixi Application
let app = new Application({ 
    width: 256, 
    height: 256,                       
    antialias: true, 
    transparent: false, 
    resolution: 1
  }
);

//Add the canvas that Pixi automatically created for you to the HTML document
document.body.appendChild(app.view);

//load an image and run the `setup` function when it's done
loader
  .add("images/cat.png")
  .load(setup);

//This `setup` function will run when the image has loaded
function setup() {

  //Create the cat sprite
  let cat = new Sprite(resources["images/cat.png"].texture);
  
  //Add the cat to the stage
  app.stage.addChild(cat);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

本教程中的大多数示例都将为遵循相同模型的Pixi对象使用别名。除非另有说明,后面的所有代码示例都使用类似的别名。

上面就是加载图像和创建精灵所需要知道的主要内容。

# 关于加载的额外内容

上面展示的格式是我建议您使用的标准模板,用于加载图像和显示精灵。因此,您可以安全地忽略接下来的几个段落,直接跳到下一节“定位精灵”。但是Pixi的loader对象非常复杂,包括一些您应该注意的特性,即使您不经常使用它们。让我们来看看一些最有用的。

# 从一个普通的JavaScript图像对象或Canvas画布创建一个精灵

为了优化和效率,最好是使用预先加载到纹理缓存中的纹理来创建精灵。但是,如果出于某种原因,您需要从一个普通的JavaScriptImage对象创建一个纹理,您可以使用Pixi的BaseTextureTexture类来实现:

let base = new PIXI.BaseTexture(anyImageObject),
    texture = new PIXI.Texture(base),
    sprite = new PIXI.Sprite(texture);
1
2
3

你也可以使用basetexture.fromcanvas从现有的Canvas画布元素中创建纹理:

let base = new PIXI.BaseTexture.fromCanvas(anyCanvasElement)
1

如果你想使用纹理属性改变精灵显示的纹理,可以将它设置为任意材质对象,就像这样:

anySprite.texture = PIXI.utils.TextureCache["anyTexture.png"];
1

在游戏中,你可以使用这种技术来动态地改变精灵的外观。

# 为加载文件分配一个名称

可以为要加载的每个资源分配一个惟一的名称。只需在add方法中提供名称(字符串)作为第一个参数。下面就是一个把猫咪的图像命名为catImage的实例:

PIXI.loader
  .add("catImage", "images/cat.png")
  .load(setup);
1
2
3

上面在loader.resources中创建一个名为catImage的对象。这意味着您可以通过引用catImage对象来创建一个精灵,就像这样:

let cat = new PIXI.Sprite(PIXI.loader.resources.catImage.texture);
1

但是,我建议您不要使用这个功能!这是因为您必须记住您为每个加载的文件提供的所有名称,并确保您不会意外地多次使用相同的名称。正如我们在前面的示例中所做的那样,使用文件路径名更简单,更不容易出错。

# 监控加载进度

Pixi的加载器有一个特殊的progress事件,它将调用一个自定义函数,该函数将在每次加载文件时运行。progress事件由加载程序的on方法调用,如下所示:

PIXI.loader.on("progress", loadProgressHandler);
1

下面介绍如何在加载链中包含on方法,并在每次加载文件时调用用户定义的loadProgressHandler函数:

PIXI.loader
  .add([
    "images/one.png",
    "images/two.png",
    "images/three.png"
  ])
  .on("progress", loadProgressHandler)
  .load(setup);

function loadProgressHandler() {
  console.log("loading"); 
}

function setup() {
  console.log("setup");
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

每次加载一个文件时,progress事件调用loadProgressHandler来在控制台中显示“loading”。当所有三个文件都已加载,setup函数将运行。下面是控制台中上述代码的输出

loading
loading
loading
setup
1
2
3
4

这很简洁,但它还可以更好。您还可以准确地找到已加载的文件以及当前已加载的文件占总文件的百分比。您可以通过向loadProgressHandler添加可选的loaderresource参数来做到这一点,就像这样:

function loadProgressHandler(loader, resource) { /*...*/ }
1

然后可以使用resource.url来找到当前加载的文件。

(你可以使用resource.name查看定义的别名)然后,您可以使用loader.progress来查找当前已加载的总资源百分比。 下面是执行这些操作的代码。

PIXI.loader
  .add([
    "images/one.png",
    "images/two.png",
    "images/three.png"
  ])
  .on("progress", loadProgressHandler)
  .load(setup);

function loadProgressHandler(loader, resource) {

  //Display the file `url` currently being loaded
  console.log("loading: " + resource.url); 

  //Display the percentage of files currently loaded
  console.log("progress: " + loader.progress + "%"); 

  //If you gave your files names as the first argument 
  //of the `add` method, you can access them like this
  //console.log("loading: " + resource.name);
}

function setup() {
  console.log("All files loaded");
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

这段代码运行时,控制台中会显示如下内容:

loading: images/one.png
progress: 33.333333333333336%
loading: images/two.png
progress: 66.66666666666667%
loading: images/three.png
progress: 100%
All files loaded
1
2
3
4
5
6
7

这真的很酷,你可以用它创建加载进度条。

注意

您可以访问resource对象上的其他属性。resource.error将告诉您尝试加载文件时发生的任何可能的错误。resource.data允许您访问文件的原始二进制数据。

# 关于Pixi加载器的更多知识

Pixi的loader具有丰富的特性和可配置性。让我们来学习一下它的用法。 加载器的链式方法add有4个基本参数:

add(name, url, optionObject, callbackFunction)
1

以下是源代码文档对这些参数的说明: name (string): 要加载的资源的名称。如果未通过,则使用urlis。 url (string): 这个资源的url,相对于baseUrl。 options (object): 加载配置项。 options.crossOrigin (Boolean): 请求是否跨域?默认是自动确定。 options.loadType: 如何加载资源?默认值是Resource.LOAD_TYPE.XHR。 options.xhrType: 在使用XHR时,应该如何解析加载的数据?默认值是Resource.XHR_RESPONSE_TYPE.DEFAULT。 callbackFunction: 资源完成加载时要调用的函数。

唯一需要的参数是url(要加载的文件)。

下面是一些使用add方法加载文件的例子,官方文档说的“正常语法”:

.add('key', 'http://...', function () {})
.add('http://...', function () {})
.add('http://...')
1
2
3

这些是“对象语法”的例子:

.add({
  name: 'key2',
  url: 'http://...'
}, function () {})

.add({
  url: 'http://...'
}, function () {})

.add({
  name: 'key3',
  url: 'http://...'
  onComplete: function () {}
})

.add({
  url: 'https://...',
  onComplete: function () {},
  crossOrigin: true
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

您还可以向add方法传递由数组和url组成的数组。

注意

如果您需要重置loader并加载新的文件,请调用加载程序的reset方法:PIXI.loader.reset()

Pixi的loader有许多更高级的特性,包括允许加载和解析所有类型的二进制文件的选项。这不是您每次都需要做的事情,并且超出了本教程的范围,您可以查看loader的GitHub存储库了解更多

lastUpdate: 2/3/2023, 2:34:54 AM