Pixi.js的基本使用(2)--操作与快速创建

1,108 阅读4分钟

操作精灵

  • 上一章讲述了如何创建和显示精灵,现在来看看如何定位和调整它们的大小,并且使用贴图集快速创建精灵

定位

  • 通过更改精灵的 xy 属性值来更改猫的位置
 mySprite.x = 100; // 向右移动100个像素
 mySprite.y = 100; // 向下移动96个像素

image-20230203162101873.png

  • 精灵的左上角(左耳)代表它的 xy 锚点

    • 若使精灵向右移动,需增加其 x属性的值
    • 若使猫向下移动,请增加其 y 属性的值
  • 可以组合设置精灵的 xy 属性

 mySprite.position.set(100, 100);

大小和缩放

  • 通过设置精灵的 widthheight 属性来改变大小
 mySprite.width = 200;
 mySprite.height = 200;

image-20230203165749035.png

  • 通过 scale.xscale.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 让精灵旋转

    • 精灵默认是绕着左上角的 xy 位置旋转,这个点叫锚点
 mySprite.rotation = 1;

image-20230203175413266.png

  • 可以改变精灵的锚点 anchor.xanchor.y ,使其位于精灵的中心

    • anchor.xanchor.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
    • 原点 改变了精灵的原点,使用的像素值
    • 如果改变精灵的原点,也就改变了它的坐标

使用雪碧图

  • 通过定义与要提取的子图像大小和位置相同的矩形区域来从雪碧图捕获子图像

1675501831271.png

  • 首先使用 PIXILoader 加载器加载此雪碧图
 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); // 将精灵添加到舞台

1675503593765.png

使用纹理贴图集

  • 如果需要快速利用雪碧图创建精灵,则可以使用 纹理贴图集

  • 纹理贴图集是一个 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),就可以进行操作

加载纹理贴图集

  • 加载纹理贴图集,需要使用 Pixiloader 把纹理贴图集导入进来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 个时,会将第一个删掉,导致页面显示不正常
  • 最后当所以精灵创建并初始化,如下图所示

image-20230210162511396.png