PixiJS 基础概念 #

核心架构概览 #

PixiJS 的架构设计清晰,核心组件各司其职:

text
┌─────────────────────────────────────────────────────────────┐
│                    PixiJS 核心架构                           │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   Application(应用)                                        │
│        │                                                    │
│        ├── Renderer(渲染器)                                │
│        │      │                                             │
│        │      ├── WebGL Renderer                           │
│        │      └── Canvas Renderer                          │
│        │                                                    │
│        ├── Stage(舞台)                                     │
│        │      │                                             │
│        │      └── Container(容器)                         │
│        │             │                                      │
│        │             ├── Sprite(精灵)                     │
│        │             ├── Graphics(图形)                   │
│        │             ├── Text(文本)                       │
│        │             └── ...                                │
│        │                                                    │
│        └── Ticker(计时器)                                  │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Application(应用) #

Application 是 PixiJS 应用的入口点,它整合了渲染器、舞台和计时器。

创建应用 #

javascript
import { Application } from 'pixi.js';

const app = new Application();

await app.init({
  width: 800,
  height: 600,
  backgroundColor: 0x1099bb
});

document.body.appendChild(app.canvas);

Application 属性 #

javascript
// 渲染器
app.renderer;

// 舞台(根容器)
app.stage;

// 画布元素
app.canvas;

// 屏幕尺寸
app.screen;

// 计时器
app.ticker;

// 配置选项
app.config;

Application 方法 #

javascript
// 渀染一帧
app.render();

// 销毁应用
app.destroy(removeView, options);

// 调整大小
app.renderer.resize(1024, 768);

完整示例 #

javascript
import { Application, Text } from 'pixi.js';

async function createApp() {
  const app = new Application();
  
  await app.init({
    width: 800,
    height: 600,
    backgroundColor: 0x1099bb,
    antialias: true,
    resolution: window.devicePixelRatio || 1,
    autoDensity: true
  });
  
  document.body.appendChild(app.canvas);
  
  return app;
}

const app = await createApp();

console.log('渲染器类型:', app.renderer.type);
console.log('屏幕宽度:', app.screen.width);
console.log('屏幕高度:', app.screen.height);

Renderer(渲染器) #

渲染器负责将显示对象绘制到画布上。

渲染器类型 #

text
┌─────────────────────────────────────────────────────────────┐
│                    渲染器类型                                │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   WebGL Renderer                                           │
│   ├── GPU 加速渲染                                          │
│   ├── 支持滤镜                                              │
│   ├── 支持混合模式                                          │
│   └── 高性能批处理                                          │
│                                                             │
│   Canvas Renderer                                           │
│   ├── CPU 渲染                                              │
│   ├── 兼容性好                                              │
│   ├── 不支持某些滤镜                                        │
│   └── 性能较低                                              │
│                                                             │
└─────────────────────────────────────────────────────────────┘

渲染器配置 #

javascript
await app.init({
  width: 800,
  height: 600,
  
  // 渲染器偏好
  preference: 'webgl2',  // 'webgl2', 'webgl1', 'canvas'
  
  // 抗锯齿
  antialias: true,
  
  // 分辨率
  resolution: 2,
  
  // 电源偏好
  powerPreference: 'high-performance'
});

渲染器属性 #

javascript
// 渲染器类型
app.renderer.type;  // 'WEBGL' 或 'CANVAS'

// 渲染器宽度
app.renderer.width;

// 渲染器高度
app.renderer.height;

// 分辨率
app.renderer.resolution;

// 屏幕矩形
app.renderer.screen;

// 背景
app.renderer.background;

手动渲染 #

javascript
// 关闭自动渲染
await app.init({
  width: 800,
  height: 600,
  autoStart: false
});

// 手动触发渲染
function gameLoop() {
  update();
  app.render();
  requestAnimationFrame(gameLoop);
}

gameLoop();

Stage(舞台) #

Stage 是显示对象树的根节点,所有可见对象都必须添加到舞台或其子容器中。

Stage 结构 #

text
┌─────────────────────────────────────────────────────────────┐
│                    Stage 结构                                │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   Stage (根容器)                                            │
│        │                                                    │
│        ├── Container (UI层)                                 │
│        │      │                                             │
│        │      ├── Text                                      │
│        │      └── Graphics                                  │
│        │                                                    │
│        ├── Container (游戏层)                               │
│        │      │                                             │
│        │      ├── Sprite (玩家)                             │
│        │      ├── Sprite (敌人)                             │
│        │      └── Container (粒子系统)                      │
│        │                                                    │
│        └── Container (背景层)                               │
│               │                                             │
│               └── TilingSprite                              │
│                                                             │
└─────────────────────────────────────────────────────────────┘

操作 Stage #

javascript
// 添加子对象
app.stage.addChild(sprite);

// 移除子对象
app.stage.removeChild(sprite);

// 移除所有子对象
app.stage.removeChildren();

// 按索引操作
app.stage.addChildAt(sprite, 0);
app.stage.removeChildAt(0);
app.stage.setChildIndex(sprite, 2);

// 查找子对象
app.stage.getChildIndex(sprite);
app.stage.getChildAt(0);

Container(容器) #

Container 是用于组织显示对象的容器,可以包含其他显示对象。

创建容器 #

javascript
import { Container } from 'pixi.js';

const container = new Container();
container.x = 100;
container.y = 100;

app.stage.addChild(container);

容器特性 #

text
┌─────────────────────────────────────────────────────────────┐
│                    Container 特性                            │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   1. 变换继承                                               │
│      子对象继承父容器的变换                                  │
│                                                             │
│   2. 可见性控制                                             │
│      父容器隐藏时,子对象也隐藏                              │
│                                                             │
│   3. 透明度继承                                             │
│      子对象透明度与父容器相乘                                │
│                                                             │
│   4. 层级管理                                               │
│      子对象按添加顺序渲染                                    │
│                                                             │
│   5. 事件冒泡                                               │
│      事件可以在容器间冒泡                                    │
│                                                             │
└─────────────────────────────────────────────────────────────┘

变换继承示例 #

javascript
const parent = new Container();
parent.x = 100;
parent.y = 100;
parent.rotation = Math.PI / 4;
parent.scale.set(2, 2);

const child = new Graphics();
child.circle(0, 0, 25);
child.fill({ color: 0xff0000 });

parent.addChild(child);
app.stage.addChild(parent);

// 子对象实际位置:(100, 100)
// 子对象实际旋转:45度
// 子对象实际缩放:2倍

容器操作 #

javascript
const container = new Container();

// 添加多个子对象
container.addChild(sprite1, sprite2, sprite3);

// 遍历子对象
container.children.forEach(child => {
  console.log(child);
});

// 排序(按 y 坐标)
container.children.sort((a, b) => a.y - b.y);

// 按名称查找
const found = container.getChildByName('player');

// 交换子对象顺序
container.swapChildren(sprite1, sprite2);

实用容器模式 #

javascript
// 分层容器
class LayeredStage {
  constructor(app) {
    this.background = new Container();
    this.game = new Container();
    this.ui = new Container();
    
    app.stage.addChild(
      this.background,
      this.game,
      this.ui
    );
  }
}

// 视差容器
class ParallaxLayer extends Container {
  constructor(speed) {
    super();
    this.speed = speed;
  }
  
  update(cameraX) {
    this.x = -cameraX * this.speed;
  }
}

DisplayObject(显示对象) #

DisplayObject 是所有可见对象的基类。

显示对象属性 #

javascript
const sprite = PIXI.Sprite.from('player.png');

// 位置
sprite.x = 100;
sprite.y = 100;
sprite.position.set(100, 100);

// 锚点(0-1)
sprite.anchor.set(0.5, 0.5);

// 原点(像素)
sprite.pivot.set(50, 50);

// 缩放
sprite.scale.x = 2;
sprite.scale.y = 2;
sprite.scale.set(2, 2);

// 旋转(弧度)
sprite.rotation = Math.PI / 4;

// 倾斜
sprite.skew.set(0.1, 0);

// 透明度(0-1)
sprite.alpha = 0.5;

// 可见性
sprite.visible = true;

// 混合模式
sprite.blendMode = 'normal';

// 滤镜
sprite.filters = [new PIXI.BlurFilter()];

// 遮罩
sprite.mask = maskGraphics;

// 渲染组
sprite.parentGroup = myGroup;

// z 轴排序
sprite.zIndex = 10;

坐标系统 #

text
┌─────────────────────────────────────────────────────────────┐
│                    坐标系统                                  │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   全局坐标(屏幕坐标)                                       │
│   ┌────────────────────────────────────────┐               │
│   │ (0,0)                                  │               │
│   │                                        │               │
│   │              屏幕空间                   │               │
│   │                                        │               │
│   │                                  (w,h) │               │
│   └────────────────────────────────────────┘               │
│                                                             │
│   本地坐标(相对于父容器)                                   │
│   ┌────────────────────────────────────────┐               │
│   │ parent (100, 100)                       │               │
│   │   ┌──────────────────┐                 │               │
│   │   │ (0,0) child      │                 │               │
│   │   │                  │                 │               │
│   │   └──────────────────┘                 │               │
│   └────────────────────────────────────────┘               │
│                                                             │
└─────────────────────────────────────────────────────────────┘

坐标转换 #

javascript
// 本地坐标转全局坐标
const globalPos = sprite.toGlobal({ x: 0, y: 0 });
console.log('全局坐标:', globalPos.x, globalPos.y);

// 全局坐标转本地坐标
const localPos = sprite.toLocal({ x: 100, y: 100 });
console.log('本地坐标:', localPos.x, localPos.y);

// 从一个对象转换到另一个对象
const pos = sprite1.toLocal({ x: 0, y: 0 }, sprite2);

边界框 #

javascript
// 获取边界框
const bounds = sprite.getBounds();

console.log('x:', bounds.x);
console.log('y:', bounds.y);
console.log('width:', bounds.width);
console.log('height:', bounds.height);

// 获取本地边界框
const localBounds = sprite.getLocalBounds();

Sprite(精灵) #

Sprite 是最常用的显示对象,用于显示图像。

创建精灵 #

javascript
import { Sprite } from 'pixi.js';

// 从图片路径创建
const sprite1 = Sprite.from('player.png');

// 从纹理创建
const texture = PIXI.Texture.from('player.png');
const sprite2 = new Sprite(texture);

// 从帧创建(精灵表)
const sprite3 = Sprite.from('spritesheet.json#player');

精灵属性 #

javascript
const sprite = Sprite.from('player.png');

// 锚点(旋转和缩放的中心点)
sprite.anchor.set(0.5);  // 中心
sprite.anchor.set(0, 0); // 左上角
sprite.anchor.set(1, 1); // 右下角

// 纹理区域
sprite.texture = PIXI.Texture.from('other.png');

// 色调
sprite.tint = 0xff0000;  // 红色调

// 翻转
sprite.scale.x = -1;  // 水平翻转

AnimatedSprite(动画精灵) #

javascript
import { AnimatedSprite } from 'pixi.js';

// 从精灵表创建动画
const frames = [];
for (let i = 0; i < 8; i++) {
  frames.push(PIXI.Texture.from(`walk_${i}.png`));
}

const animatedSprite = new AnimatedSprite(frames);

// 播放动画
animatedSprite.play();

// 动画速度
animatedSprite.animationSpeed = 0.1;

// 循环
animatedSprite.loop = true;

// 动画事件
animatedSprite.onComplete = () => {
  console.log('动画完成');
};

Ticker(计时器) #

Ticker 是 PixiJS 的核心计时系统,用于驱动动画和游戏循环。

使用 Ticker #

javascript
// Application 自动创建 Ticker
app.ticker.add((ticker) => {
  // ticker.deltaTime - 上一帧到这一帧的时间(归一化)
  // ticker.deltaMS - 毫秒数
  // ticker.FPS - 当前帧率
  
  sprite.rotation += 0.01 * ticker.deltaTime;
});

Ticker 属性 #

javascript
// 当前 FPS
app.ticker.FPS;

// 帧时间(毫秒)
app.ticker.deltaMS;

// 归一化帧时间(60fps 为基准)
app.ticker.deltaTime;

// 是否暂停
app.ticker.started;

// 最小 FPS
app.ticker.minFPS = 30;

// 最大 FPS
app.ticker.maxFPS = 60;

手动控制 Ticker #

javascript
// 停止
app.ticker.stop();

// 启动
app.ticker.start();

// 移除回调
const callback = (ticker) => {
  sprite.rotation += 0.01 * ticker.deltaTime;
};

app.ticker.add(callback);
app.ticker.remove(callback);

// 单次回调
app.ticker.addOnce((ticker) => {
  console.log('下一帧执行');
});

独立 Ticker #

javascript
import { Ticker } from 'pixi.js';

const myTicker = new Ticker();

myTicker.add((ticker) => {
  // 独立的更新循环
});

myTicker.start();

实战示例 #

创建游戏场景 #

javascript
import { Application, Container, Sprite, Text } from 'pixi.js';

class GameScene {
  constructor() {
    this.app = new Application();
    this.layers = {};
  }
  
  async init() {
    await this.app.init({
      width: 800,
      height: 600,
      backgroundColor: 0x1099bb
    });
    
    document.body.appendChild(this.app.canvas);
    
    this.createLayers();
    this.createPlayer();
    this.setupGameLoop();
  }
  
  createLayers() {
    this.layers.background = new Container();
    this.layers.game = new Container();
    this.layers.ui = new Container();
    
    this.app.stage.addChild(
      this.layers.background,
      this.layers.game,
      this.layers.ui
    );
  }
  
  createPlayer() {
    this.player = Sprite.from('player.png');
    this.player.anchor.set(0.5);
    this.player.x = this.app.screen.width / 2;
    this.player.y = this.app.screen.height / 2;
    
    this.layers.game.addChild(this.player);
  }
  
  setupGameLoop() {
    this.app.ticker.add((ticker) => {
      this.update(ticker.deltaTime);
    });
  }
  
  update(delta) {
    this.player.rotation += 0.01 * delta;
  }
}

const game = new GameScene();
await game.init();

粒子效果 #

javascript
import { Application, Container, Sprite, Ticker } from 'pixi.js';

class ParticleSystem {
  constructor(app, options = {}) {
    this.app = app;
    this.container = new Container();
    this.particles = [];
    this.options = {
      count: options.count || 100,
      speed: options.speed || 2,
      lifetime: options.lifetime || 60,
      texture: options.texture || 'particle.png'
    };
    
    this.init();
  }
  
  init() {
    for (let i = 0; i < this.options.count; i++) {
      this.createParticle();
    }
    
    this.app.stage.addChild(this.container);
    
    this.app.ticker.add((ticker) => {
      this.update(ticker.deltaTime);
    });
  }
  
  createParticle() {
    const particle = Sprite.from(this.options.texture);
    particle.anchor.set(0.5);
    particle.x = this.app.screen.width / 2;
    particle.y = this.app.screen.height / 2;
    
    particle.vx = (Math.random() - 0.5) * this.options.speed;
    particle.vy = (Math.random() - 0.5) * this.options.speed;
    particle.life = this.options.lifetime;
    
    this.container.addChild(particle);
    this.particles.push(particle);
  }
  
  update(delta) {
    for (let i = this.particles.length - 1; i >= 0; i--) {
      const p = this.particles[i];
      
      p.x += p.vx * delta;
      p.y += p.vy * delta;
      p.life -= delta;
      p.alpha = p.life / this.options.lifetime;
      
      if (p.life <= 0) {
        this.container.removeChild(p);
        this.particles.splice(i, 1);
        this.createParticle();
      }
    }
  }
}

下一步 #

掌握了基础概念后,接下来学习 图形绘制,学习如何使用 Graphics API 绘制各种形状!

最后更新:2026-03-29