操作精灵
- 上一章讲述了如何创建和显示精灵,现在来看看如何定位和调整它们的大小,并且使用贴图集快速创建精灵
定位
- 通过更改精灵的
x和y属性值来更改猫的位置
mySprite.x = 100; // 向右移动100个像素
mySprite.y = 100; // 向下移动96个像素
-
精灵的左上角(左耳)代表它的
x和y锚点- 若使精灵向右移动,需增加其
x属性的值 - 若使猫向下移动,请增加其
y属性的值
- 若使精灵向右移动,需增加其
-
可以组合设置精灵的
x和y属性
mySprite.position.set(100, 100);
大小和缩放
- 通过设置精灵的
width和height属性来改变大小
mySprite.width = 200;
mySprite.height = 200;
-
通过
scale.x和scale.y,按比例改变精灵的宽度和高度- 比例值介于
0~1之间,表示精灵大小的百分比 - 可以设置其缩放值大于1来将精灵的放大
- 比例值介于
// 缩小为原来的一半
mySprite.scale.x = 0.5;
mySprite.scale.y = 0.5;
// 放大到原来的两倍
mySprite.scale.x = 2;
mySprite.scale.y = 2;
- 可以组合设置精灵的缩放
mySprite.scale.set(0.5, 0.5);
旋转
-
可以设置为一个弧度值
rotation让精灵旋转- 精灵默认是绕着左上角的
x和y位置旋转,这个点叫锚点
- 精灵默认是绕着左上角的
mySprite.rotation = 1;
-
可以改变精灵的锚点
anchor.x和anchor.y,使其位于精灵的中心anchor.x和anchor.y值表示纹理尺寸的百分比,范围是0~1- 设置其值,点本身的位置不会改变,只会改变纹理的位置
mySprite.anchor.x = 0.5;
mySprite.anchor.y = 0.5;
- 可以使用组合设置其锚点
mySprite.anchor.set(0.5, 0.5);
-
精灵还有类似于锚点的
pivot(轴心点)属性,其设置了精灵的原点- 假设精灵大小是
64x64,设置轴心点为(32,32)则会绕中心旋转
- 假设精灵大小是
mySprite.pivot.set(32, 32);
-
锚点和轴心点的区别:
锚点改变了精灵图片纹理的原理,值的范围是0~1原点改变了精灵的原点,使用的像素值- 如果改变精灵的原点,也就改变了它的坐标
使用雪碧图
- 通过定义与要提取的子图像大小和位置相同的矩形区域来从雪碧图捕获子图像
- 首先使用
PIXI的Loader加载器加载此雪碧图
const imgUrl = require("@/assets/images/sprite-img.png");
const loader = PIXI.Loader.shared;
loader.reset();
loader.add(imgUrl); // 加载图片资源
-
当图像加载后,使用雪碧图的一个矩形区域内容来创建精灵的图像
-
PIXI有一个内置的Rectangle对象,用于定义矩形形状的通用对象,包括四个参数- 矩形的水平位置
x - 矩形的垂直位置
y - 矩形的宽度
width - 矩形的高度
height
- 矩形的水平位置
-
使用
Rectangle对象定义要提取的雪碧图上的子图像的位置和区域
const rectangle = new PIXI.Rectangle(x, y, width, height);
Pixi纹理有一个属性frame可设置为任何Rectangle对象,frame将纹理裁剪为矩形的尺寸
texture.frame = rectangle;
- 可以使用裁剪后的纹理创建精灵
const rocket = new PIXI.Sprite(texture)
- 在雪碧图中显示使用矩形截出小火箭
const { myTexture } = await this.loadResource(); // 加载资源
myTexture.frame = new PIXI.Rectangle(96, 64, 32, 32); // 创建矩形区域
const mySprite = new PIXI.Sprite(myTexture); // 创建精灵
mySprite.position.set(100, 100);
app.stage.addChild(mySprite); // 将精灵添加到舞台
使用纹理贴图集
-
如果需要快速利用雪碧图创建精灵,则可以使用
纹理贴图集 -
纹理贴图集是一个JSON数据文件,其中包含子图像在雪碧图上的位置和大小JSON文件将跟踪子图像的大小和位置,可按任意顺序排列雪碧图- 只要更新
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} }JSON文件中这些子图像都称为帧frame,只需知道精灵的帧id(frame id),就可以进行操作
加载纹理贴图集
- 加载纹理贴图集,需要使用
Pixi的loader把纹理贴图集导入进来,loader将自动解析贴图集上的每一帧数据,并创建纹理
const imgUrl = require("@/assets/treasureHunter.json");
const loader = PIXI.Loader.shared;
loader.reset();
loader.add(imgUrl); // 加载图片资源
- 这样每个图片都被加载到
Pixi缓存里,可以使用子图像名称访问缓存中的每个纹理
创建精灵
- 使用
Spritesheet对象加载精灵图和json文件
let blob, door, dungeon, explorer, treasure; // 初始化blob精灵
const mySprite = new PIXI.Spritesheet(texture, spriteJson);
mySprite.parse((texture) => {
blob = new PIXI.Sprite(texture["blob.png"]); // 创建精灵
door = new PIXI.Sprite(texture["door.png"]);
dungeon = new PIXI.Sprite(texture["dungeon.png"]);
explorer = new PIXI.Sprite(texture["explorer.png"]);
treasure = new PIXI.Sprite(texture["treasure.png"]);
});
- 创建精灵并初始化其位置
dungeon = new PIXI.Sprite(texture["dungeon.png"]);
this.app.stage.addChild(dungeon); // 先创建精灵,占据舞台高度
door = new PIXI.Sprite(texture["door.png"]);
this.app.stage.addChild(door);
// 创建并初始化explore精灵位置
explorer = new PIXI.Sprite(texture["explorer.png"]);
const explorerY = this.app.stage.height / 2 - explorer.height / 2;
explorer.position.set(68, explorerY);
this.app.stage.addChild(explorer);
// 创建并初始化treasure精灵位置
treasure = new PIXI.Sprite(texture["treasure.png"]);
const treasureX = this.app.stage.width - treasure.width - 48;
const treasureY = this.app.stage.height / 2 - treasure.height / 2;
treasure.position.set(treasureX, treasureY);
// 循环创建并初始化多个blob精灵
for (let i = 0; i < 6; i++) {
blob = new PIXI.Sprite(texture["blob.png"]); // 创建精灵
blobX = 48 * i + 150;
blobY = this.randomInt(0, this.app.stage.height - blob.height);
blob.position.set(blobX, blobY);
this.app.stage.addChild(blob);
}
- 注意: 浏览器对单个页面能运行的
WebGL上下文有限制,chrome的限制是 15 个,当创建第 16 个时,会将第一个删掉,导致页面显示不正常 - 最后当所以精灵创建并初始化,如下图所示