pixijs-rendering
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePixiJS v8 Rendering
PixiJS v8 渲染
Set up and structure a PixiJS v8 application: the async , asset
loading via , the / scene graph, the ticker loop,
pointer events, and render groups. Pins the v8 API (async , unified
, ).
ApplicationAssetsContainerSpriteinitAssetseventMode搭建并构建PixiJS v8应用:异步、通过加载资源、/场景图、ticker循环、指针事件以及渲染组。锁定v8 API(异步、统一的、)。
ApplicationAssetsContainerSpriteinitAssetseventModeWhen to use
使用场景
- Use when starting a PixiJS v8 project, fixing a blank canvas, structuring the display list, loading textures, animating via the ticker, or handling pointer input.
- Use when depends on
package.json(v8) and code doespixi.js.import { Application } from 'pixi.js'
When not to use: Phaser's scene/loader model → . 3D scenes →
. PixiJS v7-and-earlier code (synchronous , , ) needs the v8 migration first;
this skill targets v8 only.
phaser-corethreejs-scene-setupnew Application({...})Loaderinteractive = true- 适用于启动PixiJS v8项目、修复空白画布问题、构建显示列表、加载纹理、通过ticker实现动画或处理指针输入时使用。
- 适用于依赖
package.json(v8版本)且代码中包含pixi.js的场景。import { Application } from 'pixi.js'
不适用于: Phaser的场景/加载器模型 → 请使用。3D场景 → 请使用。PixiJS v7及更早版本的代码(同步、、)需要先进行v8迁移;本技能仅针对v8版本。
phaser-corethreejs-scene-setupnew Application({...})Loaderinteractive = trueCore workflow
核心工作流程
- Create and the Application. In v8,
awaitis empty; configuration happens innew Application(). Appendawait app.init({...})(notapp.canvas) to the DOM. Wrap top-levelapp.viewin an async function for bundlers.await - Load assets with .
Assetsreturns aawait Assets.load(url). For many assets, register a manifest/bundle and load by name. There is no v7Texture.Loader - Build the scene graph. Everything descends from (a
app.stage). Group related objects inContainers; child transforms are relative to the parent. Draw order = insertion order (later = on top).Container - Animate with the ticker. . Scale motion by
app.ticker.add((ticker) => {...})(frames, ~1 at 60fps) orticker.deltaTime(milliseconds) so speed is frame-rate independent.ticker.deltaMS - Enable events per object by setting (or
eventMode = 'static'), then'dynamic'. Federated pointer events cover mouse/touch/pen.obj.on('pointerdown', ...) - Promote big static subtrees to render groups () so the GPU caches their transforms. Profile before and after; confirm pixels on screen.
isRenderGroup: true
- 创建并Application实例。在v8版本中,
await会创建空实例;配置需在new Application()中完成。将await app.init({...})(而非app.canvas)添加到DOM中。对于打包工具,需将顶层app.view包裹在异步函数中。await - 使用加载资源。
Assets会返回一个await Assets.load(url)。若需加载多个资源,可注册清单/资源包并通过名称加载。v8版本已移除v7中的Texture。Loader - 构建场景图。所有元素都从(一个
app.stage)派生。将相关对象分组到Container中;子元素的变换相对于父元素。绘制顺序等于插入顺序(后插入的元素在上方)。Container - 通过ticker实现动画。。使用
app.ticker.add((ticker) => {...})(帧数,60fps下约为1)或ticker.deltaTime(自上一帧以来的毫秒数)缩放运动,确保速度不受帧率影响。ticker.deltaMS - 为每个对象启用事件:设置(或
eventMode = 'static'),然后通过'dynamic'绑定事件。联合指针事件涵盖鼠标/触摸/手写笔操作。obj.on('pointerdown', ...) - 将大型静态子树提升为渲染组(设置),让GPU缓存其变换。请在使用前后进行性能分析;确认屏幕上的像素显示正常。
isRenderGroup: true
Patterns
实现模式
1. Async Application boot (the v8 entry point)
1. 异步Application启动(v8入口)
js
import { Application, Assets, Sprite } from 'pixi.js';
(async () => {
// v8: construct empty, then await init(). Config does NOT go in the constructor.
const app = new Application();
await app.init({
background: '#1099bb',
resizeTo: window, // track the window size
antialias: true,
// preference: 'webgpu', // opt into WebGPU; default 'webgl'
});
document.body.appendChild(app.canvas); // v8 uses app.canvas, not app.view
const texture = await Assets.load('https://pixijs.com/assets/bunny.png');
const bunny = new Sprite(texture);
bunny.anchor.set(0.5);
bunny.position.set(app.screen.width / 2, app.screen.height / 2);
app.stage.addChild(bunny);
})();js
import { Application, Assets, Sprite } from 'pixi.js';
(async () => {
// v8:先构造空实例,再await init()。配置参数不能放在构造函数中。
const app = new Application();
await app.init({
background: '#1099bb',
resizeTo: window, // 跟踪窗口大小
antialias: true,
// preference: 'webgpu', // 选择WebGPU;默认使用WebGL
});
document.body.appendChild(app.canvas); // v8使用app.canvas,而非app.view
const texture = await Assets.load('https://pixijs.com/assets/bunny.png');
const bunny = new Sprite(texture);
bunny.anchor.set(0.5);
bunny.position.set(app.screen.width / 2, app.screen.height / 2);
app.stage.addChild(bunny);
})();2. Containers for a relative-transform scene graph
2. 使用Container构建相对变换场景图
js
import { Container, Sprite } from 'pixi.js';
const world = new Container();
app.stage.addChild(world);
// Children are positioned relative to `world`; move/scale/rotate the whole group
// by transforming the parent.
for (let i = 0; i < 10; i++) {
const coin = new Sprite(coinTexture);
coin.x = i * 40;
world.addChild(coin);
}
world.position.set(100, 100);
world.scale.set(2); // every coin scales with the containerjs
import { Container, Sprite } from 'pixi.js';
const world = new Container();
app.stage.addChild(world);
// 子元素相对于`world`定位;通过变换父元素来移动/缩放/旋转整个组
for (let i = 0; i < 10; i++) {
const coin = new Sprite(coinTexture);
coin.x = i * 40;
world.addChild(coin);
}
world.position.set(100, 100);
world.scale.set(2); // 所有硬币会随容器一起缩放3. The ticker loop (frame-rate independent)
3. Ticker循环(帧率无关)
js
let elapsed = 0;
app.ticker.add((ticker) => {
// deltaTime ≈ 1 at 60fps; deltaMS is milliseconds since last frame.
elapsed += ticker.deltaMS;
bunny.rotation += 0.05 * ticker.deltaTime; // smooth at any frame rate
bunny.y = app.screen.height / 2 + Math.sin(elapsed / 500) * 50;
});js
let elapsed = 0;
app.ticker.add((ticker) => {
// deltaTime在60fps下约为1;deltaMS是自上一帧以来的毫秒数。
elapsed += ticker.deltaMS;
bunny.rotation += 0.05 * ticker.deltaTime; // 在任意帧率下保持流畅
bunny.y = app.screen.height / 2 + Math.sin(elapsed / 500) * 50;
});4. Pointer events (federated)
4. 指针事件(联合事件)
js
bunny.eventMode = 'static'; // 'static' = interactive, doesn't move on its own
bunny.cursor = 'pointer';
bunny.on('pointerdown', (event) => {
bunny.tint = 0xff0000;
// event.global is the pointer position in stage space.
});
bunny.on('pointerover', () => bunny.scale.set(1.1));
bunny.on('pointerout', () => bunny.scale.set(1.0));js
bunny.eventMode = 'static'; // 'static' = 可交互,自身不移动
bunny.cursor = 'pointer';
bunny.on('pointerdown', (event) => {
bunny.tint = 0xff0000;
// event.global是指针在舞台空间中的位置。
});
bunny.on('pointerover', () => bunny.scale.set(1.1));
bunny.on('pointerout', () => bunny.scale.set(1.0));5. Loading many assets by name (bundles)
5. 通过名称加载多个资源(资源包)
js
import { Assets } from 'pixi.js';
await Assets.init({
manifest: {
bundles: [{
name: 'level-1',
assets: [
{ alias: 'hero', src: 'assets/hero.png' },
{ alias: 'tiles', src: 'assets/tiles.png' },
],
}],
},
});
const bundle = await Assets.loadBundle('level-1'); // { hero: Texture, tiles: Texture }
const hero = new Sprite(bundle.hero);js
import { Assets } from 'pixi.js';
await Assets.init({
manifest: {
bundles: [{
name: 'level-1',
assets: [
{ alias: 'hero', src: 'assets/hero.png' },
{ alias: 'tiles', src: 'assets/tiles.png' },
],
}],
},
});
const bundle = await Assets.loadBundle('level-1'); // { hero: Texture, tiles: Texture }
const hero = new Sprite(bundle.hero);6. Render groups for large static layers
6. 为大型静态层使用渲染组
js
// A big, rarely-changing background subtree: let the GPU cache its transforms.
const background = new Container({ isRenderGroup: true });
app.stage.addChild(background);
// Add hundreds of static tiles to `background`. Moving `background` itself stays
// cheap; constantly re-adding/removing children negates the benefit.js
// 大型、极少变更的背景子树:让GPU缓存其变换。
const background = new Container({ isRenderGroup: true });
app.stage.addChild(background);
// 向`background`添加数百个静态瓦片。移动`background`本身的开销很低;频繁添加/移除子元素会抵消该优化的收益。Pitfalls
常见陷阱
- Blank canvas / "app.stage is undefined" → you didn't , or you configured the constructor. In v8 the constructor is empty; all options go to
await app.init().init() - is undefined → v8 renamed it to
app.view.app.canvas - v7 code throwing → →
interactive = true;eventMode = 'static'/Loader→loader.add; synchronousAssets.load→ asyncnew Application({...}).init - Top-level await build error (Vite ≤6.0.6) → wrap boot in .
(async () => { ... })() - Speed varies with frame rate → multiply movement by (or use
ticker.deltaTime); never assume 60fps.deltaMS - Clicks do nothing → the object's is still
eventMode(the default); set it to'none'or'static'.'dynamic' - Textures look blurry on pixel art → set
(or pass it when loading).
texture.source.scaleMode = 'nearest' - Memory grows → does not free GPU memory; call
removeChildandsprite.destroy()for assets you're done with.Assets.unload(url)
- 空白画布 / "app.stage is undefined" → 你没有,或者在构造函数中传入了配置。v8版本的构造函数是空的;所有选项都要传入
await app.init()。init() - 未定义 → v8版本已将其重命名为
app.view。app.canvas - v7代码报错 → 将改为
interactive = true;将eventMode = 'static'/Loader改为loader.add;将同步Assets.load改为异步new Application({...})。init - 顶层await构建错误(Vite ≤6.0.6) → 将启动代码包裹在中。
(async () => { ... })() - 速度随帧率变化 → 运动数值乘以(或使用
ticker.deltaTime);永远不要假设帧率是60fps。deltaMS - 点击无响应 → 对象的仍为默认值
eventMode;需将其设置为'none'或'static'。'dynamic' - 像素艺术纹理模糊 → 设置(或在加载时传入该参数)。
texture.source.scaleMode = 'nearest' - 内存持续增长 → 不会释放GPU内存;对于不再使用的资源,需调用
removeChild和sprite.destroy()。Assets.unload(url)
References
参考资料
- For the texture/asset pipeline (sprite sheets/atlases, , background loading, unloading) and Graphics/Text/
Assets.add/TilingSpriteplus filters, readParticleContainer.references/assets-and-display.md
- 关于纹理/资源流水线(精灵图/图集、、后台加载、卸载)以及Graphics/Text/
Assets.add/TilingSprite和滤镜的内容,请阅读ParticleContainer。references/assets-and-display.md
Related skills
相关技能
- — a batteries-included 2D framework (scenes, physics, input).
phaser-core - — 3D in the browser with three.js.
threejs-scene-setup - — greybox a playable slice quickly (often cites PixiJS).
prototype-fast
- — 功能完备的2D框架(包含场景、物理、输入系统)。
phaser-core - — 使用three.js在浏览器中实现3D效果。
threejs-scene-setup - — 快速构建可玩的原型切片(常引用PixiJS)。
prototype-fast