PIXI中的概念

  • Container (舞台,场景):Application.stage就是一个Container类型的对象
  • Renderer (渲染器)
  • Ticker (计时器)
  • Loader (资源加载器)
  • Sprite (精灵)
  • Graphics(图画):跟精灵一样,都是可以响应事件的元素。

Container

一个Container可以包含若干个对象,修改Container的属性时会影响它包含的子元素,例如修改位置、透明度等都会影响子元素。

Renderer

Application.renderer是一个Renderer的实例,如果希望重新渲染页面,可以使用这个对象。

// 把画布重新渲染为500*500大小
app.renderer.resize(500, 500);

// 渲染一个容器
const container = new Container();
app.renderer.render(container);

Sprite:精灵

可以根据图片渲染出来

const avatar = new Sprite.from('http://anata.me/img/avatar.jpg');

// 和普通的图形一样可以设置各种属性
avatar.width = 100;
avatar.height = 200;
avatar.position.set(20, 30);
avatar.scale.set(2, 2);

Loader:用于加载网络资源

import { Application, Sprite, Loader } from 'pixi.js';

// Loader.shared内置的单例loader
const loader = Loader.shared;

// 也可以使用自定义的loader
const loader = new Loader();

const app = new Application({
  width: 300,
  height: 300,
  antialias: true,
  transparent: false,
  resolution: 1,
  backgroundColor: 0x1d9ce0
});

document.body.appendChild(app.view);

loader
.add('bili', 'http://pic.deepred5.com/bilibili.jpg')
.add('avatar', 'http://anata.me/img/avatar.jpg')
.load(setup)

// 监听加载事件
loader.onProgress.add((loader) => {
  console.log(loader.progress);
}); 

function setup() {
  const bili = new Sprite(
    loader.resources["bili"].texture
  );
  bili.width = 50;
  bili.height = 50;
  
  const avatar = new Sprite(
    loader.resources["avatar"].texture
  );
  avatar.width = 50;
  avatar.height = 50;
  avatar.position.set(50, 50);

  app.stage.addChild(bili);
  app.stage.addChild(avatar);
}

loader.add(xxx).add(yyy).load(callback) 给loader添加一些需要加载的资源,当加载完成之后调用setup函数。
在加载资源的过程中,可以通过loader.onProgress监听进度条事件,可以制作加载动画。

在游戏制作过程中,经常把多张图片打包成一张图片,称为图集。loader也可以加载图集,图集包括一张大图和一个JSON文件,JSON文件描述了每一个小图片的位置和大小。

import { Application, Container, Sprite, Graphics, Loader, Spritesheet } from 'pixi.js';

// myjson记录了每张图片的相对位置
import myjosn from './assets/treasureHunter.json';

// mypng里面有多张图片
import mypng from './assets/treasureHunter.png';

const loader = Loader.shared;

const app = new Application({
  width: 300,
  height: 300,
  antialias: true,
  transparent: false,
  resolution: 1,
  backgroundColor: 0x1d9ce0
});

document.body.appendChild(app.view);

loader
.add('mypng', mypng)
.load(setup)

function setup() {
  const texture = loader.resources["mypng"].texture.baseTexture;
  const sheet = new Spritesheet(texture, myjosn);
  sheet.parse((textures) => {
    // mypng里面的一张叫treasure.png的图片
    const treasure = new Sprite(textures["treasure.png"]);
    treasure.position.set(0, 0);

    // mypng里面的一张叫blob.png的图片
    const blob = new Sprite(textures["blob.png"]);
    blob.position.set(100, 100);
    
    app.stage.addChild(treasure);
    app.stage.addChild(blob);
  });
}

Ticker:Ticker可以用于制作动画

import { Application, Sprite, Loader } from 'pixi.js';

const loader = Loader.shared;

const app = new Application({
  width: 300,
  height: 300,
  antialias: true,
  transparent: false,
  resolution: 1,
  backgroundColor: 0x1d9ce0
});

document.body.appendChild(app.view);

loader
.add('bili', 'http://pic.deepred5.com/bilibili.jpg')                      
.load(setup)

function setup() {
  const bili = new Sprite(
    loader.resources["bili"].texture
  );
  bili.width = 50;
  bili.height = 50;

  app.stage.addChild(bili);

  app.ticker.add(() => {
    if (bili.x <= 200) {
      bili.x += 1;
    }
  })
}

使用前端的requestAnimationFrame也能够实现类似的效果

function setup() {
  const bili = new Sprite(
    loader.resources["bili"].texture
  );
  bili.width = 50;
  bili.height = 50;

  app.stage.addChild(bili);

  function move() {
    if (bili.x <= 200) {
      bili.x += 1;
      requestAnimationFrame(move)
    }
  }

  requestAnimationFrame(move)

}

补间动画

Ticker可以实现简单的动画,但是如果我们希望实现一些复杂效果,就需要自己编写很多代码。这时候可以选择一个兼容PIXI的动画库。常见的动画库有Tween.js,TweenMax等。

import { Application, Sprite, Loader } from 'pixi.js';

import { TweenMax } from 'gsap/all';

const loader = Loader.shared;

const app = new Application({
  width: 300,
  height: 300,
  antialias: true,
  transparent: false,
  resolution: 1,
  backgroundColor: 0x1d9ce0
});


document.body.appendChild(app.view);

loader
  .add('bili', 'http://pic.deepred5.com/bilibili.jpg')
  .load(setup)

function setup() {
  const bili = new Sprite(
    loader.resources["bili"].texture
  );
  bili.width = 50;
  bili.height = 50;

  app.stage.addChild(bili);

  // 1s内x和y轴移动100
  TweenMax.to(bili, 1, { x: 100, y: 100 });

}

TweenMax还提供了一个PixiPlugin,从而TweenMax可以理解PIXI的属性

import { Application, Sprite, Loader } from 'pixi.js';
import * as PIXI from 'pixi.js';
import gsap, { TweenMax, PixiPlugin } from 'gsap/all';

// 注册插件
gsap.registerPlugin(PixiPlugin);
PixiPlugin.registerPIXI(PIXI);

const loader = Loader.shared;

const app = new Application({
  width: 300,
  height: 300,
  antialias: true,
  transparent: false,
  resolution: 1,
  backgroundColor: 0x1d9ce0
});

document.body.appendChild(app.view);

loader
  .add('bili', 'http://pic.deepred5.com/bilibili.jpg')
  .load(setup)

function setup() {
  const bili = new Sprite(
    loader.resources["bili"].texture
  );
  bili.width = 50;
  bili.height = 50;

  app.stage.addChild(bili);


  // 一次修改多个属性
  TweenMax.to(bili, 1, { pixi: { scaleX: 1.2, scaleY: 1.2, skewX: 10, rotation: 20 } });

}

自定义Application

Applicatioin等于stage+loader+ticker等。
我们也可以自己创建这些对象。

import { Container, Renderer, Sprite, Loader, Ticker } from 'pixi.js';
import { TweenMax } from 'gsap/all';

// 自定义render
const renderer = new Renderer({
    width: 300,
    height: 300,
    antialias: true,
    transparent: false,
    resolution: 1,
    backgroundColor: 0x1d9ce0
});

// 自定义container
const stage = new Container();

// 自定义loader
const loader = new Loader();

// 自定义ticker
const ticker = new Ticker();

// 每次屏幕刷新重新渲染,否则只会渲染第一帧
ticker.add(() => {
    renderer.render(stage);
});

// 开始执行ticker,一定要调用这个方法,注册的回调函数才会被执行!!!
ticker.start();


document.body.appendChild(renderer.view);

loader
    .add('bili', 'http://pic.deepred5.com/bilibili.jpg')
    .load(setup)

function setup() {
    const bili = new Sprite(
        loader.resources["bili"].texture
    );
    bili.width = 50;
    bili.height = 50;

    stage.addChild(bili);

    // 动画效果
    ticker.add(() => {
        if (bili.x <= 200) {
            bili.x += 2;
        }
    });

    TweenMax.to(bili, 1, { y: 100, delay: 3 });
}