[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6WXQ7Y23MHT5RFDYA0BWH8J":3,"skill-same:01M6WXQ7Y23MHT5RFDYA0BWH8J":79},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":39,"linkOnly":40,"markdownContent":41,"markdownBody":42,"frontMatter":43,"refName":52,"commitSha":53,"skillDirectory":54,"forksCount":14,"repositoryHtmlUrl":55,"repositoryHomepageUrl":56,"ownerHtmlUrl":57,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":58,"install":59,"resources":72},"01M6WXQ7Y23MHT5RFDYA0BWH8J","pixijs-gamedev",null,"PixiJS 2D rendering and game development — sprites, animation loops, interaction, and WebGL\u002FCanvas rendering. Use when building PixiJS apps, creating 2D games, integrating sprites and animations, or implementing interactive graphics in the browser.","projectious-work\u002Fprocesskit","projectious-work","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F263889726?v=4","01M6N97TJJ118WQ35CHRV8RD0E","projectious.work","01M6N97TPWJPF0BMKYQ4PBY5W8",0,"MIT","https:\u002F\u002Fgithub.com\u002Fprojectious-work\u002Fprocesskit\u002Fblob\u002Fmain\u002Farchive\u002Fprocesskit-install-20261101\u002Fcontext\u002Ftemplates\u002Fprocesskit\u002Fv0.11.1\u002Fcontext\u002Fskills\u002Fengineering\u002Fpixijs-gamedev\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38],"pixijs gamedev","gamedev","pixijs","interaction","when","animations","2d","implementing","games","loops","rendering","canvas","apps","work","game","Animation","game development","2d games","browser","development","2026-11-10 10:12:30",false,"---\nname: pixijs-gamedev\ndescription: |\n  PixiJS 2D rendering and game development — sprites, animation loops, interaction, and WebGL\u002FCanvas rendering. Use when building PixiJS apps, creating 2D games, integrating sprites and animations, or implementing interactive graphics in the browser.\nmetadata:\n  processkit:\n    apiVersion: processkit.projectious.work\u002Fv1\n    id: SKILL-pixijs-gamedev\n    version: \"1.1.0\"\n    created: 2026-04-06T00:00:00Z\n    category: engineering\n---\n\n# PixiJS Game Development\n\n## Intro\n\nPixiJS renders 2D scenes through a display-object tree (`Application`\nholds a `stage` `Container`, which holds `Sprite`s, `Graphics`, and\nnested `Container`s). Drive updates from the `Ticker`, load assets\nthrough `Assets`, and reach for `ParticleContainer` only when raw\nbatch performance matters.\n\n## Overview\n\n### Application setup\n\nCreate an `Application`, `await app.init({...})`, then append\n`app.canvas` to the DOM. Pass `resizeTo: window` for a responsive\ncanvas, `antialias: true` for smoother edges, and\n`resolution: window.devicePixelRatio` plus `autoDensity: true` for\nsharp HiDPI rendering. PixiJS picks WebGL by default and falls back\nto Canvas automatically.\n\n### Sprites and textures\n\nLoad textures via `Assets.load('hero.png')` (returns a promise) and\nconstruct sprites with `new Sprite(texture)` or `Sprite.from(texture)`.\nSet `anchor.set(0.5)` to center the origin so rotation and scaling\nbehave intuitively. `Assets` caches by URL — loading the same source\ntwice is free. Use `Texture.EMPTY` as a placeholder while assets are\nstill loading.\n\n### Display hierarchy\n\n`Container` is the base group: children inherit position, scale,\nrotation, and alpha from their parent. Set `sortableChildren = true`\non a container and assign `zIndex` to children to control draw order.\nRemove off-screen objects from the stage rather than just hiding them.\nUse `ParticleContainer` for thousands of identical sprites — it\ntrades features for raw throughput.\n\n### Animation and the ticker\n\nDrive everything from `app.ticker.add((ticker) => { ... })`. The\n`ticker.deltaTime` value is normalized to 1.0 at the target FPS so\nmovement stays frame-rate independent. Use `AnimatedSprite` for\nspritesheet animations and control `animationSpeed` independently of\nthe main ticker. For complex tweening, integrate GSAP rather than\nhand-rolling easing.\n\n### Interaction and events\n\nSet `eventMode = 'static'` on any display object that should receive\npointer events, then attach handlers with `.on('pointerdown', ...)`.\nThe same events fire for mouse and touch. Custom hit regions go on\n`hitArea` (Circle, Rectangle, Polygon). The drag pattern is\n`pointerdown` on the sprite → `pointermove` on the stage → `pointerup`\non the stage. Disable interaction on non-interactive children to keep\nhit-testing fast.\n\n### Graphics and effects\n\n`new Graphics()` exposes vector primitives — `rect`, `circle`,\n`moveTo`\u002F`lineTo`, `roundRect` — with chainable `fill()` and\n`stroke()` calls. For static shapes that you'll reuse, render once to\na texture with `app.renderer.generateTexture()`. Apply filters via\n`displayObject.filters = [new BlurFilter(...)]`; chain filters by\nadding them to the array in order. Filters are GPU-intensive — use\nthem sparingly on mobile.\n\n### Asset loading\n\nUse `Assets.add({ alias, src })` then `Assets.load(alias)` for named\nassets, or define bundles with `Assets.addBundle('game', {...})` and\n`await Assets.loadBundle('game')`. Bundle loading reports progress\nvia a callback. Supported formats: PNG, JPG, WebP, SVG, JSON\n(spritesheets), and audio via plugins. Preload critical assets before\nshowing the game; lazy-load secondary assets in the background.\n\n## Gotchas\n\nAgent-specific failure modes — provider-neutral pause-and-self-check items:\n\n- **Accessing `app.canvas` or `app.stage` before `await app.init()` resolves.** PixiJS v8 requires the async init to complete before the renderer is ready. Accessing canvas or stage properties before init resolves throws an error. Always `await app.init({...})` before any further setup.\n- **Multiplying movement by raw frame deltas instead of `ticker.deltaTime`.** Raw frame time varies with device refresh rate — objects move twice as fast on a 120Hz display if you use raw milliseconds. `ticker.deltaTime` is normalized to 1.0 at the target FPS, making movement frame-rate independent. Always multiply speeds by `deltaTime`.\n- **Constructing sprites by passing a URL string directly instead of using `Assets.load()`.** Bypassing the `Assets` cache reloads the file on every construction call. Use `await Assets.load('hero.png')` once and construct sprites from the returned texture to benefit from caching.\n- **Leaving off-screen objects in the display tree instead of removing them.** Hidden or off-screen objects that remain in the scene still receive render calls. For games with many projectiles or particles, accumulated off-screen objects are a primary cause of frame rate degradation. Remove from parent when no longer needed.\n- **Setting `eventMode = 'static'` on containers without disabling it on non-interactive children.** Every object with event mode enabled participates in hit-testing on each pointer event. Enabling it on containers whose children need no interaction inflates hit-testing cost. Only enable interaction on objects that actually handle pointer events.\n- **Applying the same filter to many individual objects instead of to a shared parent container.** Each filter application is a separate GPU pass. A blur applied individually to 50 sprites costs 50 GPU passes; the same blur applied once to their parent container costs one pass. Group objects and apply filters at the container level.\n- **Showing the game scene before critical assets have finished loading.** Displaying a scene before its textures are loaded results in sprites rendering as white squares or as invisible objects. Preload all assets required by the first visible scene before transitioning out of the loading screen.\n\n## Full reference\n\n### Application boilerplate\n\n```js\nimport { Application, Assets, Sprite, Container, Graphics, Text } from 'pixi.js';\n\nconst app = new Application();\nawait app.init({\n  width: 800,\n  height: 600,\n  background: '#1a1a2e',\n  antialias: true,\n  resolution: window.devicePixelRatio || 1,\n  autoDensity: true,\n});\ndocument.body.appendChild(app.canvas);\n```\n\n### Core classes\n\n| Class               | Purpose                                  | Key properties                                  |\n|---------------------|------------------------------------------|-------------------------------------------------|\n| `Application`       | Entry point, manages renderer and ticker | `stage`, `ticker`, `screen`, `canvas`           |\n| `Sprite`            | Displays a texture                       | `texture`, `anchor`, `tint`, `alpha`            |\n| `Container`         | Groups display objects                   | `children`, `sortableChildren`, `zIndex`        |\n| `Graphics`          | Vector drawing                           | `rect()`, `circle()`, `fill()`, `stroke()`      |\n| `Text`              | Renders text                             | `text`, `style`, `resolution`                   |\n| `AnimatedSprite`    | Frame-based animation                    | `textures`, `animationSpeed`, `currentFrame`    |\n| `ParticleContainer` | High-performance sprite batch            | `maxSize`, `properties`                         |\n| `Ticker`            | Game loop manager                        | `deltaTime`, `FPS`, `speed`                     |\n\n### Asset loading patterns\n\n```js\n\u002F\u002F Single asset\nconst texture = await Assets.load('hero.png');\nconst sprite = new Sprite(texture);\n\n\u002F\u002F Bundled assets\nAssets.addBundle('level1', {\n  background: 'bg.png',\n  tileset: 'tiles.json',\n  music: 'theme.mp3',\n});\nawait Assets.loadBundle('level1');\n\n\u002F\u002F With progress tracking\nAssets.loadBundle('level1', (progress) => {\n  console.log(`Loading: ${Math.round(progress * 100)}%`);\n});\n```\n\n### Sprite operations\n\n```js\nconst sprite = Sprite.from(texture);\nsprite.anchor.set(0.5);           \u002F\u002F Center origin\nsprite.position.set(400, 300);    \u002F\u002F Set position\nsprite.scale.set(2);              \u002F\u002F Uniform scale\nsprite.rotation = Math.PI \u002F 4;    \u002F\u002F Rotate 45 degrees\nsprite.alpha = 0.8;               \u002F\u002F Semi-transparent\nsprite.tint = 0xff6b6b;           \u002F\u002F Color tint\nsprite.eventMode = 'static';      \u002F\u002F Enable interaction\nsprite.cursor = 'pointer';        \u002F\u002F Pointer cursor\n```\n\n### Game loop\n\n```js\napp.ticker.add((ticker) => {\n  \u002F\u002F ticker.deltaTime = 1.0 at 60fps, scales with frame time\n  sprite.x += speed * ticker.deltaTime;\n  sprite.rotation += 0.01 * ticker.deltaTime;\n});\n\n\u002F\u002F Control ticker\napp.ticker.speed = 0.5;   \u002F\u002F Half speed\napp.ticker.stop();         \u002F\u002F Pause\napp.ticker.start();        \u002F\u002F Resume\n```\n\n### Drag pattern\n\n```js\nlet dragging = false;\nsprite.eventMode = 'static';\nsprite.on('pointerdown', () => { dragging = true; });\n\napp.stage.eventMode = 'static';\napp.stage.hitArea = app.screen;\napp.stage.on('pointermove', (e) => {\n  if (dragging) sprite.position.copyFrom(e.global);\n});\napp.stage.on('pointerup', () => { dragging = false; });\n```\n\n### Graphics drawing\n\n```js\nconst g = new Graphics();\ng.rect(0, 0, 200, 100).fill({ color: 0x3498db, alpha: 0.8 });\ng.circle(100, 100, 50).fill(0xe74c3c).stroke({ color: 0xffffff, width: 2 });\ng.moveTo(0, 0).lineTo(200, 200).stroke({ color: 0x2ecc71, width: 3 });\ng.roundRect(10, 10, 180, 80, 12).fill(0x9b59b6);\n```\n\n### Text rendering\n\n```js\nconst text = new Text({\n  text: 'Score: 0',\n  style: {\n    fontFamily: 'Arial',\n    fontSize: 36,\n    fontWeight: 'bold',\n    fill: 0xffffff,\n    stroke: { color: 0x000000, width: 4 },\n    dropShadow: { color: 0x000000, blur: 4, distance: 2 },\n  },\n});\ntext.anchor.set(0.5);\n```\n\n### AnimatedSprite from spritesheet\n\n```js\nimport { AnimatedSprite, Spritesheet } from 'pixi.js';\n\nconst sheet = await Assets.load('character.json');\nconst walkFrames = sheet.animations['walk']; \u002F\u002F array of textures\nconst character = new AnimatedSprite(walkFrames);\ncharacter.animationSpeed = 0.15;\ncharacter.play();\n\n\u002F\u002F Control\ncharacter.stop();\ncharacter.gotoAndPlay(0);\ncharacter.loop = true;\ncharacter.onComplete = () => { \u002F* animation finished *\u002F };\n```\n\n### Object pooling\n\n```js\nconst pool = [];\nfunction getSprite(texture) {\n  const sprite = pool.pop() || new Sprite(texture);\n  sprite.visible = true;\n  return sprite;\n}\nfunction releaseSprite(sprite) {\n  sprite.visible = false;\n  pool.push(sprite);\n}\n```\n\n### Scene management\n\n```js\nconst scenes = { menu: new Container(), game: new Container() };\nfunction switchScene(name) {\n  Object.values(scenes).forEach(s => s.visible = false);\n  scenes[name].visible = true;\n}\napp.stage.addChild(scenes.menu, scenes.game);\nswitchScene('menu');\n```\n\n### Performance tips\n\n- Use `ParticleContainer` for 10k+ identical sprites\n- Each filter forces a render-texture pass — limit them\n- Pool and reuse objects rather than creating\u002Fdestroying every frame\n- Texture atlases reduce draw calls (PixiJS batches automatically)\n- Always call `destroy()` on removed display objects to free GPU\n  memory\n- Avoid frequent `blendMode` changes — they break batching\n- Profile with `app.ticker.FPS` and the browser DevTools Performance\n  tab\n\n### Further reading\n\n- [PixiJS Documentation](https:\u002F\u002Fpixijs.download\u002Frelease\u002Fdocs\u002F)\n- [PixiJS Examples](https:\u002F\u002Fpixijs.io\u002Fexamples\u002F)\n","# PixiJS Game Development\n\n## Intro\n\nPixiJS renders 2D scenes through a display-object tree (`Application`\nholds a `stage` `Container`, which holds `Sprite`s, `Graphics`, and\nnested `Container`s). Drive updates from the `Ticker`, load assets\nthrough `Assets`, and reach for `ParticleContainer` only when raw\nbatch performance matters.\n\n## Overview\n\n### Application setup\n\nCreate an `Application`, `await app.init({...})`, then append\n`app.canvas` to the DOM. Pass `resizeTo: window` for a responsive\ncanvas, `antialias: true` for smoother edges, and\n`resolution: window.devicePixelRatio` plus `autoDensity: true` for\nsharp HiDPI rendering. PixiJS picks WebGL by default and falls back\nto Canvas automatically.\n\n### Sprites and textures\n\nLoad textures via `Assets.load('hero.png')` (returns a promise) and\nconstruct sprites with `new Sprite(texture)` or `Sprite.from(texture)`.\nSet `anchor.set(0.5)` to center the origin so rotation and scaling\nbehave intuitively. `Assets` caches by URL — loading the same source\ntwice is free. Use `Texture.EMPTY` as a placeholder while assets are\nstill loading.\n\n### Display hierarchy\n\n`Container` is the base group: children inherit position, scale,\nrotation, and alpha from their parent. Set `sortableChildren = true`\non a container and assign `zIndex` to children to control draw order.\nRemove off-screen objects from the stage rather than just hiding them.\nUse `ParticleContainer` for thousands of identical sprites — it\ntrades features for raw throughput.\n\n### Animation and the ticker\n\nDrive everything from `app.ticker.add((ticker) => { ... })`. The\n`ticker.deltaTime` value is normalized to 1.0 at the target FPS so\nmovement stays frame-rate independent. Use `AnimatedSprite` for\nspritesheet animations and control `animationSpeed` independently of\nthe main ticker. For complex tweening, integrate GSAP rather than\nhand-rolling easing.\n\n### Interaction and events\n\nSet `eventMode = 'static'` on any display object that should receive\npointer events, then attach handlers with `.on('pointerdown', ...)`.\nThe same events fire for mouse and touch. Custom hit regions go on\n`hitArea` (Circle, Rectangle, Polygon). The drag pattern is\n`pointerdown` on the sprite → `pointermove` on the stage → `pointerup`\non the stage. Disable interaction on non-interactive children to keep\nhit-testing fast.\n\n### Graphics and effects\n\n`new Graphics()` exposes vector primitives — `rect`, `circle`,\n`moveTo`\u002F`lineTo`, `roundRect` — with chainable `fill()` and\n`stroke()` calls. For static shapes that you'll reuse, render once to\na texture with `app.renderer.generateTexture()`. Apply filters via\n`displayObject.filters = [new BlurFilter(...)]`; chain filters by\nadding them to the array in order. Filters are GPU-intensive — use\nthem sparingly on mobile.\n\n### Asset loading\n\nUse `Assets.add({ alias, src })` then `Assets.load(alias)` for named\nassets, or define bundles with `Assets.addBundle('game', {...})` and\n`await Assets.loadBundle('game')`. Bundle loading reports progress\nvia a callback. Supported formats: PNG, JPG, WebP, SVG, JSON\n(spritesheets), and audio via plugins. Preload critical assets before\nshowing the game; lazy-load secondary assets in the background.\n\n## Gotchas\n\nAgent-specific failure modes — provider-neutral pause-and-self-check items:\n\n- **Accessing `app.canvas` or `app.stage` before `await app.init()` resolves.** PixiJS v8 requires the async init to complete before the renderer is ready. Accessing canvas or stage properties before init resolves throws an error. Always `await app.init({...})` before any further setup.\n- **Multiplying movement by raw frame deltas instead of `ticker.deltaTime`.** Raw frame time varies with device refresh rate — objects move twice as fast on a 120Hz display if you use raw milliseconds. `ticker.deltaTime` is normalized to 1.0 at the target FPS, making movement frame-rate independent. Always multiply speeds by `deltaTime`.\n- **Constructing sprites by passing a URL string directly instead of using `Assets.load()`.** Bypassing the `Assets` cache reloads the file on every construction call. Use `await Assets.load('hero.png')` once and construct sprites from the returned texture to benefit from caching.\n- **Leaving off-screen objects in the display tree instead of removing them.** Hidden or off-screen objects that remain in the scene still receive render calls. For games with many projectiles or particles, accumulated off-screen objects are a primary cause of frame rate degradation. Remove from parent when no longer needed.\n- **Setting `eventMode = 'static'` on containers without disabling it on non-interactive children.** Every object with event mode enabled participates in hit-testing on each pointer event. Enabling it on containers whose children need no interaction inflates hit-testing cost. Only enable interaction on objects that actually handle pointer events.\n- **Applying the same filter to many individual objects instead of to a shared parent container.** Each filter application is a separate GPU pass. A blur applied individually to 50 sprites costs 50 GPU passes; the same blur applied once to their parent container costs one pass. Group objects and apply filters at the container level.\n- **Showing the game scene before critical assets have finished loading.** Displaying a scene before its textures are loaded results in sprites rendering as white squares or as invisible objects. Preload all assets required by the first visible scene before transitioning out of the loading screen.\n\n## Full reference\n\n### Application boilerplate\n\n```js\nimport { Application, Assets, Sprite, Container, Graphics, Text } from 'pixi.js';\n\nconst app = new Application();\nawait app.init({\n  width: 800,\n  height: 600,\n  background: '#1a1a2e',\n  antialias: true,\n  resolution: window.devicePixelRatio || 1,\n  autoDensity: true,\n});\ndocument.body.appendChild(app.canvas);\n```\n\n### Core classes\n\n| Class               | Purpose                                  | Key properties                                  |\n|---------------------|------------------------------------------|-------------------------------------------------|\n| `Application`       | Entry point, manages renderer and ticker | `stage`, `ticker`, `screen`, `canvas`           |\n| `Sprite`            | Displays a texture                       | `texture`, `anchor`, `tint`, `alpha`            |\n| `Container`         | Groups display objects                   | `children`, `sortableChildren`, `zIndex`        |\n| `Graphics`          | Vector drawing                           | `rect()`, `circle()`, `fill()`, `stroke()`      |\n| `Text`              | Renders text                             | `text`, `style`, `resolution`                   |\n| `AnimatedSprite`    | Frame-based animation                    | `textures`, `animationSpeed`, `currentFrame`    |\n| `ParticleContainer` | High-performance sprite batch            | `maxSize`, `properties`                         |\n| `Ticker`            | Game loop manager                        | `deltaTime`, `FPS`, `speed`                     |\n\n### Asset loading patterns\n\n```js\n\u002F\u002F Single asset\nconst texture = await Assets.load('hero.png');\nconst sprite = new Sprite(texture);\n\n\u002F\u002F Bundled assets\nAssets.addBundle('level1', {\n  background: 'bg.png',\n  tileset: 'tiles.json',\n  music: 'theme.mp3',\n});\nawait Assets.loadBundle('level1');\n\n\u002F\u002F With progress tracking\nAssets.loadBundle('level1', (progress) => {\n  console.log(`Loading: ${Math.round(progress * 100)}%`);\n});\n```\n\n### Sprite operations\n\n```js\nconst sprite = Sprite.from(texture);\nsprite.anchor.set(0.5);           \u002F\u002F Center origin\nsprite.position.set(400, 300);    \u002F\u002F Set position\nsprite.scale.set(2);              \u002F\u002F Uniform scale\nsprite.rotation = Math.PI \u002F 4;    \u002F\u002F Rotate 45 degrees\nsprite.alpha = 0.8;               \u002F\u002F Semi-transparent\nsprite.tint = 0xff6b6b;           \u002F\u002F Color tint\nsprite.eventMode = 'static';      \u002F\u002F Enable interaction\nsprite.cursor = 'pointer';        \u002F\u002F Pointer cursor\n```\n\n### Game loop\n\n```js\napp.ticker.add((ticker) => {\n  \u002F\u002F ticker.deltaTime = 1.0 at 60fps, scales with frame time\n  sprite.x += speed * ticker.deltaTime;\n  sprite.rotation += 0.01 * ticker.deltaTime;\n});\n\n\u002F\u002F Control ticker\napp.ticker.speed = 0.5;   \u002F\u002F Half speed\napp.ticker.stop();         \u002F\u002F Pause\napp.ticker.start();        \u002F\u002F Resume\n```\n\n### Drag pattern\n\n```js\nlet dragging = false;\nsprite.eventMode = 'static';\nsprite.on('pointerdown', () => { dragging = true; });\n\napp.stage.eventMode = 'static';\napp.stage.hitArea = app.screen;\napp.stage.on('pointermove', (e) => {\n  if (dragging) sprite.position.copyFrom(e.global);\n});\napp.stage.on('pointerup', () => { dragging = false; });\n```\n\n### Graphics drawing\n\n```js\nconst g = new Graphics();\ng.rect(0, 0, 200, 100).fill({ color: 0x3498db, alpha: 0.8 });\ng.circle(100, 100, 50).fill(0xe74c3c).stroke({ color: 0xffffff, width: 2 });\ng.moveTo(0, 0).lineTo(200, 200).stroke({ color: 0x2ecc71, width: 3 });\ng.roundRect(10, 10, 180, 80, 12).fill(0x9b59b6);\n```\n\n### Text rendering\n\n```js\nconst text = new Text({\n  text: 'Score: 0',\n  style: {\n    fontFamily: 'Arial',\n    fontSize: 36,\n    fontWeight: 'bold',\n    fill: 0xffffff,\n    stroke: { color: 0x000000, width: 4 },\n    dropShadow: { color: 0x000000, blur: 4, distance: 2 },\n  },\n});\ntext.anchor.set(0.5);\n```\n\n### AnimatedSprite from spritesheet\n\n```js\nimport { AnimatedSprite, Spritesheet } from 'pixi.js';\n\nconst sheet = await Assets.load('character.json');\nconst walkFrames = sheet.animations['walk']; \u002F\u002F array of textures\nconst character = new AnimatedSprite(walkFrames);\ncharacter.animationSpeed = 0.15;\ncharacter.play();\n\n\u002F\u002F Control\ncharacter.stop();\ncharacter.gotoAndPlay(0);\ncharacter.loop = true;\ncharacter.onComplete = () => { \u002F* animation finished *\u002F };\n```\n\n### Object pooling\n\n```js\nconst pool = [];\nfunction getSprite(texture) {\n  const sprite = pool.pop() || new Sprite(texture);\n  sprite.visible = true;\n  return sprite;\n}\nfunction releaseSprite(sprite) {\n  sprite.visible = false;\n  pool.push(sprite);\n}\n```\n\n### Scene management\n\n```js\nconst scenes = { menu: new Container(), game: new Container() };\nfunction switchScene(name) {\n  Object.values(scenes).forEach(s => s.visible = false);\n  scenes[name].visible = true;\n}\napp.stage.addChild(scenes.menu, scenes.game);\nswitchScene('menu');\n```\n\n### Performance tips\n\n- Use `ParticleContainer` for 10k+ identical sprites\n- Each filter forces a render-texture pass — limit them\n- Pool and reuse objects rather than creating\u002Fdestroying every frame\n- Texture atlases reduce draw calls (PixiJS batches automatically)\n- Always call `destroy()` on removed display objects to free GPU\n  memory\n- Avoid frequent `blendMode` changes — they break batching\n- Profile with `app.ticker.FPS` and the browser DevTools Performance\n  tab\n\n### Further reading\n\n- [PixiJS Documentation](https:\u002F\u002Fpixijs.download\u002Frelease\u002Fdocs\u002F)\n- [PixiJS Examples](https:\u002F\u002Fpixijs.io\u002Fexamples\u002F)\n",{"name":5,"metadata":44,"description":51},{"processkit":45},{"id":46,"created":47,"version":48,"category":49,"apiVersion":50},"SKILL-pixijs-gamedev",1775433600000,"1.1.0","engineering","processkit.projectious.work\u002Fv1","PixiJS 2D rendering and game development — sprites, animation loops, interaction, and WebGL\u002FCanvas rendering. Use when building PixiJS apps, creating 2D games, integrating sprites and animations, or implementing interactive graphics in the browser.\n","main","4876a92620ee792aac2ac9a1a806322d8a572367","archive\u002Fprocesskit-install-20261101\u002Fcontext\u002Ftemplates\u002Fprocesskit\u002Fv0.11.1\u002Fcontext\u002Fskills\u002Fengineering\u002Fpixijs-gamedev","https:\u002F\u002Fgithub.com\u002Fprojectious-work\u002Fprocesskit","https:\u002F\u002Fprojectious-work.github.io\u002Fprocesskit\u002F","https:\u002F\u002Fgithub.com\u002Fprojectious-work","2026-11-11 23:24:18",{"source":8,"skillName":5,"commands":60,"prompt":70,"zipAvailable":71},[61,64,67],{"tool":62,"command":63},"npx","npx skills add projectious-work\u002Fprocesskit --skill pixijs-gamedev",{"tool":65,"command":66},"bunx","bunx skills add projectious-work\u002Fprocesskit --skill pixijs-gamedev",{"tool":68,"command":69},"pnpm","pnpm dlx skills add projectious-work\u002Fprocesskit --skill pixijs-gamedev","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fprojectious-work\u002Fprocesskit\u002Fblob\u002Fmain\u002Farchive\u002Fprocesskit-install-20261101\u002Fcontext\u002Ftemplates\u002Fprocesskit\u002Fv0.11.1\u002Fcontext\u002Fskills\u002Fengineering\u002Fpixijs-gamedev\u002FSKILL.md",true,[73],{"path":74,"resourceType":75,"resourceTypeDesc":76,"sizeBytes":77,"sourceHtmlUrl":78},"references\u002Fapi-cheatsheet.md","REFERENCE","参考文档",5180,"https:\u002F\u002Fgithub.com\u002Fprojectious-work\u002Fprocesskit\u002Fblob\u002Fmain\u002Farchive\u002Fprocesskit-install-20261101\u002Fcontext\u002Ftemplates\u002Fprocesskit\u002Fv0.11.1\u002Fcontext\u002Fskills\u002Fengineering\u002Fpixijs-gamedev\u002Freferences\u002Fapi-cheatsheet.md",[80,107,127,148,165,183],{"skillNo":81,"name":82,"nameZh":6,"description":83,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":84,"categories":85,"keywords":91,"publishedAt":39},"01M6X5MTC89B4ZGXW3JVSQCPF8","skill-management","Manage Skill package manifests as v1 ontology entities.","https:\u002F\u002Fgithub.com\u002Fprojectious-work\u002Fprocesskit\u002Fblob\u002Fmain\u002Fsrc\u002Fcontext\u002Fskills\u002Fprocesskit\u002Fskill-management\u002FSKILL.md",[86],{"categoryNo":87,"categoryName":88,"taxonomyType":89,"taxonomyTypeDesc":90},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[92,93,94,95,96,97,32,98,99,100,82,101,102,103,104,105,106],"management","skill management","create","update","package","alpha","list","manage","ontology","get","as","manifests","v1","skill package","transition",{"skillNo":108,"name":109,"nameZh":6,"description":110,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":111,"categories":112,"keywords":114,"publishedAt":39},"01M6X5MCV74NHW5MEDNHZRF2C8","schema-management","Manage generated processkit schema contracts through deterministic MCP rebuild and inspection workflows.","https:\u002F\u002Fgithub.com\u002Fprojectious-work\u002Fprocesskit\u002Fblob\u002Fmain\u002Fsrc\u002Fcontext\u002Fskills\u002Fprocesskit\u002Fschema-management\u002FSKILL.md",[113],{"categoryNo":87,"categoryName":88,"taxonomyType":89,"taxonomyTypeDesc":90},[92,115,116,117,118,119,97,32,120,121,99,122,123,124,101,125,126],"schema","schema management","MCP","workflows","validation","generated","rebuild","contracts","wed","deterministic","contract","mode",{"skillNo":128,"name":129,"nameZh":6,"description":130,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":131,"categories":132,"keywords":133,"publishedAt":39},"01M6X5M5G6YJ96AMZGSCZJ1D13","proposition-management","Record claims, risks, beliefs, world facts, WSJF estimates, and assumptions through the Proposition interface.","https:\u002F\u002Fgithub.com\u002Fprojectious-work\u002Fprocesskit\u002Fblob\u002Fmain\u002Fsrc\u002Fcontext\u002Fskills\u002Fprocesskit\u002Fproposition-management\u002FSKILL.md",[],[92,134,135,94,95,136,97,32,137,138,139,140,101,141,142,143,144,145,146,147],"proposition","proposition management","index","log","world","record","query","creation","event","interface","updates","facts","claims","WSJF",{"skillNo":149,"name":150,"nameZh":6,"description":151,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":152,"categories":153,"keywords":154,"publishedAt":39},"01M6X5KMQ83QN9M6MPWZM7344F","ontology-management","Manage generated v1 ontology entities that do not require a dedicated domain server.","https:\u002F\u002Fgithub.com\u002Fprojectious-work\u002Fprocesskit\u002Fblob\u002Fmain\u002Fsrc\u002Fcontext\u002Fskills\u002Fprocesskit\u002Fontology-management\u002FSKILL.md",[],[92,100,155,94,97,156,157,120,158,137,99,159,160,101,161,162,142,163,104,164],"ontology management","lifecycle","archive","roadmap","do","domain","iteration","keep","measurement","generic",{"skillNo":166,"name":167,"nameZh":6,"description":168,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":169,"categories":170,"keywords":171,"publishedAt":39},"01M6X5KCY2DN3SM21RERSFNEBT","okf-compatibility","Import, export, and validate conformant Open Knowledge Format bundles.","https:\u002F\u002Fgithub.com\u002Fprojectious-work\u002Fprocesskit\u002Fblob\u002Fmain\u002Fsrc\u002Fcontext\u002Fskills\u002Fprocesskit\u002Fokf-compatibility\u002FSKILL.md",[],[172,173,174,175,97,176,177,178,32,179,180,181,182],"okf","compatibility","okf compatibility","validate","open","knowledge","format","export","bundles","bundle","import",{"skillNo":184,"name":185,"nameZh":6,"description":186,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":187,"categories":188,"keywords":189,"publishedAt":39},"01M6X5JA8S5PNGJVFW4EQY8T83","capability-management","Manage versioned Capability entities and their governed lifecycle.","https:\u002F\u002Fgithub.com\u002Fprojectious-work\u002Fprocesskit\u002Fblob\u002Fmain\u002Fsrc\u002Fcontext\u002Fskills\u002Fprocesskit\u002Fcapability-management\u002FSKILL.md",[],[92,190,191,94,95,136,97,156,32,98,137,192,99,139,101,162,142,143,193,106],"capability","capability management","queries","changes"]