A character assembled from independently swappable, independently tintable layers -
skin, eyes, hair, garments, worn equipment - rather than one flat sprite per combination.
A second palette is a colour change on one layer; worn equipment shows because it is
another layer added on top, not a redrawn sprite for every gear combination a game might
have. tools/make-example-assets.mjs already draws its characters this way; this is the
runtime counterpart that keeps the layers together as one sprite that moves as a unit.
hero.layer('hair')?.lerpTint(0x8b4513, 1); // dye it brown hero.setTexture('weapon', swordTexture); // equip a different sword later console.log(hero.hasLayer('weapon')); // true
hero.alpha = 0.5; // the whole assembled character turns translucent, every layer at once
LayeredSprite is a plain Pixi Container, not itself a TintedSprite: its own alpha
still fades every layer together, since Pixi composes a container's alpha into each
child's when rendering, the same way it would for any other container of sprites. A
single layer can still be faded on its own through layer(name), which returns the
TintedSprite directly.
A character assembled from independently swappable, independently tintable layers - skin, eyes, hair, garments, worn equipment - rather than one flat sprite per combination. A second palette is a colour change on one layer; worn equipment shows because it is another layer added on top, not a redrawn sprite for every gear combination a game might have.
tools/make-example-assets.mjsalready draws its characters this way; this is the runtime counterpart that keeps the layers together as one sprite that moves as a unit.Example
LayeredSpriteis a plain PixiContainer, not itself aTintedSprite: its ownalphastill fades every layer together, since Pixi composes a container's alpha into each child's when rendering, the same way it would for any other container of sprites. A single layer can still be faded on its own throughlayer(name), which returns theTintedSpritedirectly.