Sprites & Transforms
Sprite2D and Transform2D in @g2w/coreare a minimal, renderer-independent sprite model: a typed texture handle, a transform, a normalized anchor, and the visual properties games need. Core never inspects or destroys the texture — it is a genericTTexture the caller supplies, typically from a renderer's asset API.
The model is plain mutable data
Transform2D holds position (logical pixels), rotation (radians — clockwise in PixiJS screen space, because y points down), and scale multipliers. Properties are plain mutable numbers: gameplay code mutates them, and nothing touches the renderer until you say so:
import { Sprite2D, Transform2D } from "@g2w/core";
const logo = new Sprite2D({
texture, // typed by the caller
transform: new Transform2D({ x: 16, y: 32 }),
anchor: { x: 0.5, y: 0.5 }, // rotate around center
zIndex: 2,
});
// plain mutable data — no observers, no proxies
logo.transform.rotation += deltaTime;
logo.alpha = 0.8;Anchor2D.set() is the only mutation path and rejects out-of-range values instead of clamping.Project it with a view
createSpriteView from @g2w/renderer-pixi attaches a PixiJS Sprite to the stage as a pure projection of your model. There is no ticker, subscription, or second loop — you callsync() once per frame, after the model changes:
import { createSpriteView } from "@g2w/renderer-pixi";
const view = createSpriteView({ sprite: logo, renderer });
// once per frame, after the model changes:
update(deltaTime) {
// ...mutate logo.transform here
view.sync();
},
// teardown — the texture survives, only the display object dies
view.dispose();Ownership splits cleanly: the model is yours, the view's display object belongs to whoever created it. dispose() removes and destroys the display object — never the texture — and never touches the stage or other views. Disposal is idempotent. Each call tocreateSpriteView makes one new display object, so dispose a view before creating another for the same model.
Share one transform between sprites
Supplying an existing Transform2D makes the sprite reference your instance instead of creating its own — several sprites can be driven by one transform:
const bossTransform = new Transform2D({ x: 320, y: 180 });
const bossBody = new Sprite2D({
texture: bodyTex, transform: bossTransform,
});
const bossShadow = new Sprite2D({
texture: shadowTex, transform: bossTransform, alpha: 0.4,
});
// one mutation moves both sprites
bossTransform.x += 40 * deltaTime;Scope
Intentionally unsupported: parent/child hierarchies, tint, blend modes, animation timelines, and entity components — roadmap items, not hidden APIs.
Next steps
See Assets to load the textures these sprites render, orarchitecture notes for the renderer contract in full.