|
1 | 1 | # Rendering with Pixi |
2 | 2 |
|
3 | | -:::info |
| 3 | +This page shows how to render 2D shapes and UI (like health bars) in Dreamlab using RawPixi + PixiJS v8’s Graphics API. |
4 | 4 |
|
5 | | -This page is a work-in-progress. |
| 5 | +Pixi v8’s Graphics uses a modern, chainable builder style (e.g. `.rect().fill().stroke()`), supports gradients/textures, SVG paths, and a reusable GraphicsContext. |
| 6 | + |
| 7 | +## Getting Started: RawPixi and Graphics objects |
| 8 | + |
| 9 | +Try attaching this below script to any entity. This will draw a blue box that tracks the position of the entity. |
| 10 | +```ts |
| 11 | +import { Behavior, RawPixi } from "@dreamlab/engine"; |
| 12 | +import * as PIXI from "@dreamlab/vendor/pixi.ts"; |
| 13 | + |
| 14 | +export default class GraphicsDemo extends Behavior { |
| 15 | + rawPixi!: RawPixi; |
| 16 | + g!: PIXI.Graphics; |
| 17 | + |
| 18 | + onInitialize() { |
| 19 | + if (!this.game.isClient()) return; |
| 20 | + this.rawPixi = this.game.local.spawn({ |
| 21 | + type: RawPixi, |
| 22 | + name: "GraphicsTest", |
| 23 | + transform: { position: this.entity.pos, z: 5 }, |
| 24 | + }); |
| 25 | + |
| 26 | + // Create a PIXI.Graphics and add it to the RawPixi container |
| 27 | + this.g = new PIXI.Graphics(); |
| 28 | + this.rawPixi!.container!.addChild(this.g); |
| 29 | + |
| 30 | + // 3) Draw something simple |
| 31 | + this.g |
| 32 | + .rect(0, 0, 5, 5) |
| 33 | + .fill("#00ffb7"); |
| 34 | + } |
| 35 | + |
| 36 | + onPostTick() { |
| 37 | + if (!this.game.isClient()) return; |
| 38 | + // Keep your graphics positioned relative to your entity |
| 39 | + this.rawPixi.globalTransform.position.x = this.entity.pos.x; |
| 40 | + this.rawPixi.globalTransform.position.y = this.entity.pos.y; |
| 41 | + } |
| 42 | +} |
| 43 | +``` |
| 44 | + |
| 45 | +You should see a teal square get rendered at your entity's position: |
| 46 | + |
| 47 | + |
| 48 | + |
| 49 | +## Usage |
| 50 | + |
| 51 | +### All the different shapes & features |
| 52 | + |
| 53 | +#### 1) Fills (solid, gradient, texture) |
| 54 | + |
| 55 | +**Solid color** |
| 56 | + |
| 57 | +```ts |
| 58 | +g.rect(0, 0, 200, 20).fill("#3ed36f"); |
| 59 | +``` |
| 60 | + |
| 61 | +**Gradient fill** (v8 `FillGradient`): |
| 62 | + |
| 63 | +```ts |
| 64 | +import * as PIXI from "@dreamlab/vendor/pixi.ts"; |
| 65 | + |
| 66 | +const grad = new PIXI.FillGradient(0, 0, 200, 0); // linear left→right |
| 67 | +grad.addColorStop(0, "#3ed36f"); |
| 68 | +grad.addColorStop(1, "#e55039"); |
| 69 | + |
| 70 | +g.rect(0, 0, 200, 20).fill(grad); |
| 71 | +``` |
| 72 | + |
| 73 | +Pixi v8 adds first-class gradient fills you can pass to `fill()`. ([Pixi docs][2]) |
| 74 | + |
| 75 | +**Texture fill** |
| 76 | + |
| 77 | +```ts |
| 78 | +const tex = await PIXI.Assets.load("ui/stripe.png"); |
| 79 | +g.rect(0, 0, 200, 20).texture(tex).fill(); // apply texture, then fill |
| 80 | +``` |
| 81 | + |
| 82 | +`Graphics.texture()` lets you paint textures onto shapes before calling `fill()`. See the API for details. ([Pixi docs][3]) |
| 83 | + |
| 84 | +#### Strokes (outlines) |
| 85 | + |
| 86 | +```ts |
| 87 | +g.roundRect(0, 0, 120, 16, 4) |
| 88 | + .stroke({ |
| 89 | + color: "#2f3342", |
| 90 | + width: 1, |
| 91 | + alignment: 0.5, // 0=inside, 0.5=center, 1=outside (see notes below) |
| 92 | + cap: "round", |
| 93 | + join: "round", |
| 94 | + miterLimit: 2, |
| 95 | + }); |
| 96 | +``` |
| 97 | + |
| 98 | +Stroke properties in v8 are passed as a `StrokeStyle`/`StrokeAttributes` object (width, alignment, cap, join, miterLimit, etc.). ([Pixi docs][4]) |
| 99 | + |
| 100 | +#### Paths, curves, arcs |
| 101 | + |
| 102 | +```ts |
| 103 | +g.moveTo(10, 10) |
| 104 | + .quadraticCurveTo(60, -20, 110, 10) // control (60,-20) → end (110,10) |
| 105 | + .stroke({ width: 2 }); |
| 106 | + |
| 107 | +g.arc(80, 80, 24, 0, Math.PI * 1.5).stroke({ width: 2 }); |
| 108 | +``` |
| 109 | + |
| 110 | +Curves (`quadraticCurveTo`, Bezier) and arcs are part of the v8 `Graphics`/`GraphicsContext` API. ([Pixi docs][3]) |
| 111 | + |
| 112 | +#### Advanced shapes |
| 113 | + |
| 114 | +```ts |
| 115 | +g.regularPoly(200, 60, 24, 6) // hexagon |
| 116 | + .fill("#55b6ff") |
| 117 | + .star(80, 160, 5, 24, 12) // 5-point star |
| 118 | + .fill("#ffd54d"); |
| 119 | +``` |
| 120 | + |
| 121 | +See the API for `regularPoly`, `roundPoly`, `star`, etc. ([Pixi docs][3]) |
| 122 | + |
| 123 | +#### “Cutting” holes |
| 124 | + |
| 125 | +```ts |
| 126 | +g.rect(0, 0, 100, 100).fill("#3ed36f") |
| 127 | + .circle(50, 50, 20).cut(); // removes the circle from the previous fill |
| 128 | +``` |
| 129 | + |
| 130 | +Use `.cut()` to punch a hole out of the previous shape (ensure the hole stays enclosed for correct triangulation). ([Pixi docs][1]) |
| 131 | + |
| 132 | +#### SVG path support |
| 133 | + |
| 134 | +```ts |
| 135 | +g.svg(` |
| 136 | + <svg> |
| 137 | + <path d="M 100 350 q 150 -300 300 0" stroke="blue" /> |
| 138 | + </svg> |
| 139 | +`); |
| 140 | +``` |
| 141 | + |
| 142 | +You can parse simple SVG path data into graphics; it’s great for icons and decorative lines. ([Pixi docs][1]) |
| 143 | + |
| 144 | +#### Masks & hit areas |
| 145 | + |
| 146 | +Any `Graphics` object can be used as a **mask** or **hit area**: |
| 147 | + |
| 148 | +```ts |
| 149 | +const mask = new PIXI.Graphics().circle(0, 0, 32).fill(0xffffff); |
| 150 | +this.rawPixi.container.mask = mask; |
| 151 | +``` |
| 152 | + |
| 153 | +This is a common pattern for clipping UI/art. ([Pixi docs][7]) |
| 154 | + |
| 155 | +--- |
| 156 | + |
| 157 | +### Performance tips (v8) |
| 158 | + |
| 159 | +* **Build, don’t rebuild.** Avoid clearing and reconstructing complex geometry every frame. Prefer swapping prebuilt `GraphicsContext`s (`graphic.context = nextContext`) when animating. ([Pixi docs][1]) |
| 160 | +* **Reuse contexts.** Multiple `Graphics` can share one `GraphicsContext` (great for repeated shapes). Destroying a shared context will destroy all dependents, so manage lifetime carefully. ([Pixi docs][1]) |
| 161 | +* **Batching:** Many simple `Graphics` often batch better than one mega-shape. ([Pixi docs][1]) |
| 162 | + |
| 163 | +```ts |
| 164 | +const barCtx = new PIXI.GraphicsContext().rect(0, 0, 64, 8).fill("#1e1f26"); |
| 165 | +const outlineCtx = new PIXI.GraphicsContext().roundRect(0, 0, 64, 8, 3) |
| 166 | + .stroke({ color: "#2f3342", width: 1 }); |
| 167 | + |
| 168 | +const barA = new PIXI.Graphics(barCtx); |
| 169 | +const barB = new PIXI.Graphics(barCtx); // cheap reuse |
| 170 | +``` |
| 171 | +--- |
| 172 | + |
| 173 | +### Quick reference |
| 174 | + |
| 175 | +* **Shapes:** `.rect`, `.roundRect`, `.circle`, `.ellipse`, `.arc`, `.moveTo/.lineTo`, `.quadraticCurveTo`, `.regularPoly`, `.roundPoly`, `.star` ([Pixi docs][3]) |
| 176 | +* **Fills:** `.fill(color|FillGradient|pattern)`, `.texture(texture)` (then `.fill()`) ([Pixi docs][2]) |
| 177 | +* **Strokes:** `.stroke({ width, color, alignment, cap, join, miterLimit, ... })` ([Pixi docs][4]) |
| 178 | +* **Holes:** `.cut()` (applies to the previous shape) ([Pixi docs][1]) |
| 179 | +* **SVG:** `.svg("<svg>…</svg>")` ([Pixi docs][1]) |
| 180 | +* **Context reuse:** `new GraphicsContext(...)` and pass it to `new Graphics(context)`; swap via `graphic.context = other` ([Pixi docs][1]) |
| 181 | + |
| 182 | +--- |
| 183 | + |
| 184 | +### Further reading |
| 185 | + |
| 186 | +* **Graphics (v8 guide):** overview, shapes, SVG, holes, performance, gotchas. ([Pixi docs][1]) |
| 187 | +* **Graphics API (v8):** full method list (`fill`, `stroke`, `regularPoly`, `star`, `texture`, transforms, etc.). ([Pixi docs][3]) |
| 188 | +* **Fills (guide):** colors, textures, gradients (`FillGradient`, stops). ([Pixi docs][2]) |
| 189 | + |
| 190 | +[1]: https://pixijs.com/8.x/guides/components/scene-objects/graphics "Graphics | PixiJS" |
| 191 | +[2]: https://pixijs.com/8.x/guides/components/scene-objects/graphics/graphics-fill "Graphics Fill" |
| 192 | +[3]: https://pixijs.download/v8.2.3/docs/scene.Graphics.html " |
| 193 | + PixiJS API Documentation |
| 194 | + " |
| 195 | +[4]: https://pixijs.download/v8.4.0/docs/scene.StrokeAttributes.html "StrokeAttributes" |
| 196 | +[5]: https://github.com/pixijs/pixijs/issues/10950 "Hit test on strokes doesn't honor `alignment` StrokeStyle ..." |
| 197 | +[6]: https://pixijs.com/8.x/guides/components/scene-objects/graphics/graphics-pixel-line "Graphics Pixel Line" |
| 198 | +[7]: https://pixijs.download/v8.1.7/docs/scene.Graphics.html "Graphics" |
6 | 199 |
|
7 | | -::: |
|
0 commit comments