PixiJS超级详细教程【从入门到入土-上】

PixiJS

来自GitHub教程 GitHub - Zainking/LearningPixi: ⚡️Pixi教程中文版

PixiJS超级详细教程【从入门到入土-下】地址【https://blog.csdn.net/qq_61672548/article/details/127289093】

一、入门

1. 安装Pixi

下载地址

Releases · pixijs/pixijs (github.com)

2. 引入Pixi

<script src="./js/Pixi.min.js"> </script>

3. 创建Pixi应用和舞台

第一步就是去创建一个可以显示图片的矩形显示区。Pixi拥有一个Pixi应用对象来帮助你创建它。它会自动创建一个<canvas>HTML标签并且计算出怎么去让你的图片在这个标签中显示。你现在需要创建一个特殊的Pixi容器对象,他被称作舞台。正如你所见,这个舞台对象将会被当作根容器而使用,它将包裹所有你想用Pixi显示的东西。

<div id="stage"></div>

<script>
    //创建pixi应用
    const app = new PIXI.Application(
        {
            width: 256,         // default: 800
            height: 256,        // default: 600
            antialias: true,    // default: false
            transparent: false, // default: false
            resolution: 1       // default: 1
        }
    )
//pixi将自动把画布添加到html文档中(‘#stage’)
document.querySelector('#stage').appendChild(app.view)
</script>

PIXI.Application(options)参数是一个options对象

去这里查看详细PIXI.Application

这些设置做了些什么呢? antialias使得字体的边界和几何图形更加圆滑(WebGL的anti-aliasing不是在所有平台都可用,所以你需要在你的游戏的目标平台上测试他们)。transparent将整个Canvas标签的透明度进行了设置。resolution让Pixi在不同的分辨率和像素密度的平台上运行变得简单。设置分辨率对于这个教程而言有些超纲了,到那时你可以看Mat Grove’sexplanation之中是如何使用resolution的所有细节的。但是平常,只要保持resolution是1,就可以应付大多数工程了

4. 修改画布

  • 修改颜色
app.renderer.backgroundColor = 0xcccccc
  • 修改大小

使用画布resize方法可以改变canvas的大小,提供任何新的widthheight变量给他都行。但是为了确认宽高的格式正确,将autoResize设置为true

app.renderer.view.width = 300
app.renderer.view.height = 300

app.renderer.autoResize = true;
app.renderer.resize(512, 512);

如果你想让canvas占据整个窗口,你可以将这些CSS代码放在文档中,并且刷新你浏览器窗口的大小。

app.renderer.view.style.position = "absolute";
app.renderer.view.style.display = "block";
app.renderer.autoResize = true;
app.renderer.resize(window.innerWidth, window.innerHeight);

但是,如果你这么做了,要记得把padding和margin都设置成0:

<style>* {padding: 0; margin: 0}</style>
  • 修改样式

如果有需要 console.log(app.renderer.view.style) 可以看到view.style有哪些属性

app.renderer.view.style.position = "absolute";
app.renderer.view.style.display = "block";

二、提升

1. 舞台

现在你就有了一个画布,可以开始往上面放图像了。所有你想在画布上显示的东西必须被加进一个被称作 舞台的Pixi对象中。你能够像这样使用舞台对象

app.stage

这个舞台是一个Pixi 容器对象。你能把它理解成一种将放进去的东西分组并存储的空箱子。 舞台对象是在你的场景中所有可见对象的根容器。所有你放进去的东西都会被渲染到canvas中。现在舞台是空的,但是很快我们就会放进去一点东西。 (你可以从这了解关于Pixi容器对象的更多信息here).

>>>我自己的浅显理解:PIXI.Application 和 app.stage都是容器对象,app.stage是PIXI.Application的一部分,一个功能分区(专门管canvas)

2. 精灵 (Sprite)

所以你可以放些什么到舞台上呢?那就是被称作 精灵 的特殊图像对象。精灵是你能用代码控制图像的基础。

Pixi拥有一个精灵类来创建游戏精灵。有三种主要的方法来创建它:

  • 用一个单图像文件创建。
  • 用一个 雪碧图 来创建。雪碧图是一个放入了你游戏所需的所有图像的大图。
  • 从一个纹理贴图集中创建。(纹理贴图集就是用JSON定义了图像大小和位置的雪碧图)

因为Pixi用WebGL和GPU去渲染图像,所以图像需要转化成GPU可以处理的版本。可以被GPU处理的图像被称作 纹理 。在你让精灵显示图片之前,需要将普通的图片转化成WebGL纹理。为了让所有工作执行的快速有效率,Pixi使用 纹理缓存 来存储和引用所有你的精灵需要的纹理。纹理的名称字符串就是图像的地址。这意味着如果你有从"images/cat.png"加载的图像,你可以在纹理缓存中这样找到他:

PIXI.utils.TextureCache["images/cat.png"];
2.1 精灵加载方式
方式一:

纹理被以WEBGL兼容的格式存储起来,它可以使Pixi的渲染有效率的进行。你现在可以使用Pixi的精灵类来创建一个新的精灵,让它使用纹理。

let texture = PIXI.utils.TextureCache["images/anySpriteImage.png"];
let sprite = new PIXI.Sprite(texture);
方式二(这种应该比较常用):

Pixi强大的loader对象可以加载任何你需要种类的图像资源。这里展示了怎么加载一个图像并在加载完成时用一个叫做setup的方法来使用它。

PIXI.loader
  .add("images/anyImage.png") //可以穿数组
  .load(setup);

function setup() {
  //这段代码将在加载器完成加载图像时运行
}

如果你使用了Loader,你就应该创建一个精灵来连接loaderresources对象,像下面这样:

let sprite = new PIXI.Sprite(
  PIXI.loader.resources["images/anyImage.png"].texture
);
完整加载代码

这里是一个完整的加载图像的代码。调用setup方法,并为加载的图像创建一个精灵。

更好的方式则是用数组给一个add方法传参,像这样:

<div id="stage"></div>

//创建pixi应用
const app = new PIXI.Application(
    {
        width: 256,
        height: 256,
        resolution: 1
    }
)
//pixi将自动把画布添加到html文档中(‘#stage’)
document.querySelector('#stage').appendChild(app.view)

app.loader
    .add(["./images/ACharDown.png", "./images/ACharUp.png"])
    .load(setup)

//或者 app.loader
//    .add("./images/ACharDown.png")
//    .add("./images/ACharUp.png")
//   .load(setup)

function setup(e) {
    let s1 = new PIXI.Sprite(
        app.loader.resources['./images/ACharDown.png'].texture
    )
    let s2 = new PIXI.Sprite(
        app.loader.resources['./images/ACharUp.png'].texture
    )
    
    app.stage.addChild(s1)
    app.stage.addChild(s2)
}

记住,舞台是用来包裹你所有精灵的主要容器。

重点:你不应该看见任何没被加入舞台的精灵

2.2 移除精灵

如果你想把一个精灵从舞台上挪走,就可以使用removeChild方法:

app.stage.removeChild(anySprite)

但是通常,我们都把精灵的visible属性设置成false来让精灵简单的隐藏。

anySprite.visible = false;

3 使用别名

你可以对你使用频繁的Pixi对象和方法设置一些简略的可读性更强的别名。举个例子,你想给所有的Pixi对象增加PIXI前缀么?如果你这样想,那就创建一个简短的别名给他吧。

<script>
    const app = new PIXI.Application(
        {
            width: 200,
            height: 200
        }
    )
document.body.appendChild(app.view)
let loader = app.loader,
    resources = app.loader.resources,
    Sprite = PIXI.Sprite

loader.add('./images/ACharDown.png').load(setup)

function setup() {

    //Create the cat sprite
    let s = new Sprite(resources["./images/ACharDown.png"].texture);

    //Add the cat to the stage
    app.stage.addChild(s);
}
</script>

>>>这里在https://github.com/Zainking/learningPixi的教程上定义别名的方式我尝试的时候报错,可能是因为和教程版本不一致?没有深入,不清楚,我版本是pixi.js - v6.5.5。教程上别名可以这样let loader = app.loader ,在我这里只能loader = app.loader,需要先把app实例出来,然后Sprite = PIXI.Sprite必须这样报错如下:

在这里插入图片描述

教程代码如下:

//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);
}

4一些关于加载的其他知识

你可以使用BaseTexture.fromCanvas从任何已经存在canvas标签中创建纹理:

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

如果你想改变已经显示的精灵的纹理,使用texture属性,可以设置任何Texture对象,像下面这样:

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

你可以使用这个技巧在游戏发生一些重大变化时交互式的改变精灵的纹理。

4.1 给加载的文件设置别名

你可以给任何你加载的源文件分配一个独一无二的别名。你只需要在add方法中第一个参数位置传进去这个别名就行了,举例来说,下面实现了怎么给这个猫的图片重命名为catImage

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

这种操作在loader.resources中创建了一个叫做catImage的对象。 这意味着你可以创建一个引用了catImage对象的精灵,像这样:

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

然而,我建议你永远别用这个操作!因为你将不得不记住你所有加载文件的别名,而且必须确信你只用了它们一次,使用路径命名,我们将将这些事情处理的更简单和更少错误。

4.2 监视加载进程(在显示加载进度有很大作用)

Pixi的加载器有一个特殊的progress事件,它将会调用一个可以定制的函数,这个函数将在每次文件加载时调用。progress事件将会被loaderon方法调用,像是这样:

loader.add(['./images/ACharDown.png', './images/1.png', './images/2.png', './images/3.png'])
loader.onProgress.add(showProgress)
loader.load(setup)

function showProgress(loader, resource) {
    console.log(loader)
    console.log(resource)
}

这实在太酷了!因为你能用这个玩意做个进度条出来。 (注意:还有一些额外的resource对象属性, resource.error会告诉你有哪些加载时候的错误,resource.data将会给你文件的原始二进制数据。)

>>>教程中是这样写的

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

这样写我会报错,在我6.5.5这个版本这里无法使用链式编程
在这里插入图片描述
(注意:如果你需要重新加载一批文件,调用加载器的reset方法:PIXI.loader.reset();

4.3 add() 可略过

Pixi的加载器有很多可以设置的功能,让我速览一下

add 方法有四个基础参数:

add(name, url, optionObject, callbackFunction)

这里有文档里面对这些参数的描述:

name (string): 加载源文件的别名,如果没设置,url就会被放在这.
url (string): 源文件的地址,是加载器 baseUrl的相对地址.
options (object literal): 加载设置.
options.crossOrigin (Boolean): 源文件请求跨域不?默认是自动设定的。
options.loadType: 源文件是怎么加载进来的?默认是Resource.LOAD_TYPE.XHRoptions.xhrType: 用XHR的时候该怎么处理数据? 默认是Resource.XHR_RESPONSE_TYPE.DEFAULT
callbackFunction: 当这个特定的资源加载完后,这个函数将会被执行。

只有url必填(你总得加载个文件吧。)

这里有点用了add方法加载文件的例子。第一个就是文档里所谓的“正常语法”:

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

这些就是所谓“对象语法”啦:

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

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

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

.add({
  url: 'https://...',
  onComplete: function () {},
  crossOrigin: true
})

你也可以给add方法传一个对象的数组,或者既使用对象数组,又使用链式加载:

.add([
  {name: 'key4', url: 'http://...', onComplete: function () {} },
  {url: 'http://...', onComplete: function () {} },
  'http://...'
]);

(注意:如果你需要重新加载一批文件,调用加载器的reset方法:PIXI.loader.reset();

Pixi的加载器还有许多其他的高级特性,包括可以让你加载和解析所有类型二进制文件的选项。这些并非你每天都要做的,也超出了这个教程的范围,所以从GitHub项目中获取更多信息吧!

三、精灵位置、大小、旋转、锚点

3.1 位置

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B82xp0sv-1665411293625)(https://github.com/Zainking/LearningPixi/raw/master/examples/images/screenshots/04.png)]

cat.x = 96;
cat.y = 96;

你可以一句话设置精灵的xy:

sprite.position.set(x, y)
3.2 大小

你能够通过精灵的widthheight属性来改变它的大小。这是怎么把width调整成80像素,height调整成120像素的例子:

cat.width = 80;
cat.height = 120;

Scale的值是从0到1之间的数字的时候,代表了它对于原来精灵大小的百分比。1意味着100%(原来的大小),所以0.5意味着50%(一半大小)。你可以把这个值改为2,这就意味着让精灵的大小成倍增长。像这样:

cat.scale.x = 2;
cat.scale.y = 2;

Pixi可以用一行代码缩放你的精灵,那要用到scale.set方法。

cat.scale.set(0.5, 0.5);
3.3 旋转

你可以通过对一个精灵的rotation设定一个角度来旋转它。

cat.rotation = 0.5;

>>>觉得使用Math.PI 更佳 s.rotation = Math.PI / 2

3.4 锚点

像是positionscale属性一样,你也可以在一行内像这样设置锚点的位置:

cat.anchor.set(x, y)

精灵也提供和anchor差不多的pivot属性来设置精灵的原点。如果你改变了它的值之后旋转精灵,它将会围绕着你设置的原点来旋转。举个例子,下面的代码将精灵的pivot.xpivot.y设置为了32。

cat.pivot.set(32, 32)

假设精灵图是64x64像素,它将绕着它的中心点旋转。但是记住:你如果改变了精灵的pivot属性,你也就改变了它的原点位置。

anchor()取值0-1 pivot()取值为多少px

四、雪碧图的使用

Pixi内置了一个通用的Rectangle对象 (PIXI.Rectangle),他是一个用于定义矩形形状的通用对象。他需要一些参数,前两个参数定义了xy轴坐标位置,后两个参数定义了矩形的widthheight,下面是新建一个Rectangle对象的格式。

let rectangle = new PIXI.Rectangle(x, y, width, height);

这个矩形对象仅仅是一个 数据对象,如何使用它完全取决于你。在我们的例子里,我们用它来定义子图像在雪碧图中的位置和大小。Pixi的纹理中有一个叫做frame的很有用的属性,它可以被设置成任何的Rectangle对象。frame将纹理映射到Rectangle的维度。下面是怎么用frame来定义火箭的大小和位置。

let rectangle = new Rectangle(192, 128, 64, 64);
texture.frame = rectangle;

你现在可以用它裁切纹理来创建精灵了:

let rocket = new Sprite(texture);

例如:

function setup() {

  //Create the `tileset` sprite from the texture
  let texture = TextureCache["images/tileset.png"];

  //Create a rectangle object that defines the position and
  //size of the sub-image you want to extract from the texture
  //(`Rectangle` is an alias for `PIXI.Rectangle`)
  let rectangle = new Rectangle(192, 128, 64, 64);

  //Tell the texture to use that rectangular section
  texture.frame = rectangle;

  //Create the sprite from the texture
  let rocket = new Sprite(texture);

  //Position the rocket sprite on the canvas
  rocket.x = 32;
  rocket.y = 32;

  //Add the rocket to the stage
  app.stage.addChild(rocket);

  //Render the stage   
  renderer.render(stage);
}

五、纹理贴图集的使用(重点,学会使用会带来大的方便)

如果你正在处理一个很大的,很复杂的游戏,你想要找到一种快速有效的方式来从雪碧图创建精灵。纹理贴图集 就会显得很有用处,一个纹理贴图集就是一个JSON数据文件,它包含了匹配的PNG雪碧图的子图像的大小和位置。如果你使用了纹理贴图集,那么想要显示一个子图像只需要知道它的名字就行了。你可以任意的排序你的排版,JSON文件会保持他们的大小和位置不变。这非常方便,因为这意味着图片的位置和大小不必写在你的代码里。如果你想要改变纹理贴图集的排版,类似增加图片,修改图片大小和删除图片这些操作,只需要修改那个JSON数据文件就行了,你的游戏会自动给程序内的所有数据应用新的纹理贴图集。你没必要在所有用到它代码的地方修改它。

Pixi兼容著名软件Texture Packer输出的标准纹理贴图集格式。Texture Packer的基本功能是免费的。让我们来学习怎么用它来制作一个纹理贴图集,并把它加载进Pixi吧!(你也不是非得用它,还有一些类似的工具输出的纹理贴图集Pixi也是兼容的,例如:Shoeboxspritesheet.js。)

首先,从你要用在游戏的图片文件们开始。

在这里插入图片描述

在这个章节所有的图片都是被Lanea Zimmerman创作的。你能在他的艺术工作室里面找到更多类似的东西:这里,谢谢你,Lanea!

下面,打开Texture Packer,选择 JSON Hash 框架类型。把你的图片放进Texture Packer的工作区。(你也可以把Texture Packer放进包含你图片的文件夹里面去。)他将自动的把你的图片们生成单个图片文件,并且将他们的原始名称命名为纹理贴图集中的图片名称。

图片文件

如果你正在用免费版的Texture Packer,把 Algorithm 选项设为Basic,把 Trim mode 选项设为None,把 Extrude 选项设为0,把 Size constraints 选项设为 Any size ,把 PNG Opt Level 中所有的东西都滑到左边的 0位置。这就可以使得Texture Packer正常的输出你的纹理贴图集。

如果你做完了,点击 Publish 按钮。选择输出文件名和存储地址,把生成文件保存起来。你将会获得两个文件:一个叫做treasureHunter.json,另外一个就是treasureHunter.png。为了让目录干净些,我们把他俩都放到一个叫做images的文件夹里面去。(你可以认为那个json文件是图片文件的延伸,所以把他们放进一个文件夹是很有意义的。)那个JSON文件里面写清楚了每一个子图像的名字,大小和位置。下面描述了“泡泡怪”这个怪物的子图像的信息。

"blob.png":
{
	"frame": {"x":55,"y":2,"w":32,"h":24},
	"rotated": false,
	"trimmed": false,
	"spriteSourceSize": {"x":0,"y":0,"w":32,"h":24},
	"sourceSize": {"w":32,"h":24},
	"pivot": {"x":0.5,"y":0.5}
},

treasureHunter.json里面也包含了“dungeon.png”, “door.png”, “exit.png”, 和 "explorer.png"的数据信息,并以和上面类似的信息记录。这些子图像每一个都被叫做 ,有了这些数据你就不用去记每一个图片的大小和位置了,你唯一要做的就只是确定精灵的 帧ID 即可。帧ID就是那些图片的原始名称,类似"blob.png"或者 "explorer.png"这样。

使用纹理贴图集的巨大优势之一就是你可以很轻易的给每一个图像增加两个像素的内边距。Texture Packer默认这么做。这对于保护图像的 出血(译者:出血是排版和图片处理方面的专有名词,指在主要内容周围留空以便印刷或裁切)来说很重要。出血对于防止两个图片相邻而相互影响来说很重要。这种情况往往发生于你的GPU渲染某些图片的时候。把边上的一两个像素加上去还是不要?这对于每一个GPU来说都有不同的做法。所以对每一个图像空出一两个像素对于显示来说是最好的兼容。

(注意:如果你真的在每个图像的周围留了两个像素的出血,你必须时时刻刻注意Pixi显示时候“丢了一个像素”的情况。尝试着去改变纹理的规模模式来重新计算它。texture.baseTexture.scaleMode = PIXI.SCALE_MODES.NEAREST;,这往往发生于你的GPU浮点运算凑整失败的时候。)

现在你明白了怎么创建一个纹理贴图集,来学习怎么把他加载进你的游戏之中吧。

2022.10.10 22:06 笔记来自于github,是我看过了文档,然后把代码敲了一遍,再我觉得对我开发实用的部分复制了上来,承认大部分是复制,删减了部分,加了部分我实操中遇到教程中代码不能运行怎么解决的办法(前提我能解决。可能是和教程版本不一样引起的问题?没有深入,不清楚),这大概有1/3吧,过两天继续更新。

PixiJS超级详细教程【从入门到入土-下】地址【https://blog.csdn.net/qq_61672548/article/details/127289093】

教程原文地址 GitHub - Zainking/LearningPixi: ⚡️Pixi教程中文版


  • 8
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NoBug.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值