@guinetik/gcanvas 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (217) hide show
  1. package/dist/gcanvas.es.js +25656 -0
  2. package/dist/gcanvas.es.min.js +1 -0
  3. package/dist/gcanvas.umd.js +1 -0
  4. package/dist/gcanvas.umd.min.js +1 -0
  5. package/package.json +23 -6
  6. package/src/game/objects/index.js +1 -0
  7. package/src/game/objects/spritesheet.js +260 -0
  8. package/src/game/ui/theme.js +6 -0
  9. package/src/io/keys.js +9 -1
  10. package/src/math/boolean.js +481 -0
  11. package/src/math/index.js +1 -0
  12. package/.github/workflows/release.yaml +0 -70
  13. package/.jshintrc +0 -4
  14. package/.vscode/settings.json +0 -22
  15. package/CLAUDE.md +0 -310
  16. package/blackhole.jpg +0 -0
  17. package/demo.png +0 -0
  18. package/demos/CNAME +0 -1
  19. package/demos/animations.html +0 -31
  20. package/demos/basic.html +0 -38
  21. package/demos/baskara.html +0 -31
  22. package/demos/bezier.html +0 -35
  23. package/demos/beziersignature.html +0 -29
  24. package/demos/blackhole.html +0 -28
  25. package/demos/blob.html +0 -35
  26. package/demos/coordinates.html +0 -698
  27. package/demos/cube3d.html +0 -23
  28. package/demos/demos.css +0 -303
  29. package/demos/dino.html +0 -42
  30. package/demos/easing.html +0 -28
  31. package/demos/events.html +0 -195
  32. package/demos/fluent.html +0 -647
  33. package/demos/fluid-simple.html +0 -22
  34. package/demos/fluid.html +0 -37
  35. package/demos/fractals.html +0 -36
  36. package/demos/gameobjects.html +0 -626
  37. package/demos/genart.html +0 -26
  38. package/demos/gendream.html +0 -26
  39. package/demos/group.html +0 -36
  40. package/demos/home.html +0 -587
  41. package/demos/index.html +0 -376
  42. package/demos/isometric.html +0 -34
  43. package/demos/js/animations.js +0 -452
  44. package/demos/js/basic.js +0 -204
  45. package/demos/js/baskara.js +0 -751
  46. package/demos/js/bezier.js +0 -692
  47. package/demos/js/beziersignature.js +0 -241
  48. package/demos/js/blackhole/accretiondisk.obj.js +0 -379
  49. package/demos/js/blackhole/blackhole.obj.js +0 -318
  50. package/demos/js/blackhole/index.js +0 -409
  51. package/demos/js/blackhole/particle.js +0 -56
  52. package/demos/js/blackhole/starfield.obj.js +0 -218
  53. package/demos/js/blob.js +0 -2276
  54. package/demos/js/coordinates.js +0 -840
  55. package/demos/js/cube3d.js +0 -789
  56. package/demos/js/dino.js +0 -1420
  57. package/demos/js/easing.js +0 -477
  58. package/demos/js/fluent.js +0 -183
  59. package/demos/js/fluid-simple.js +0 -253
  60. package/demos/js/fluid.js +0 -527
  61. package/demos/js/fractals.js +0 -931
  62. package/demos/js/fractalworker.js +0 -93
  63. package/demos/js/gameobjects.js +0 -176
  64. package/demos/js/genart.js +0 -268
  65. package/demos/js/gendream.js +0 -209
  66. package/demos/js/group.js +0 -140
  67. package/demos/js/info-toggle.js +0 -25
  68. package/demos/js/isometric.js +0 -863
  69. package/demos/js/kerr.js +0 -1556
  70. package/demos/js/lavalamp.js +0 -590
  71. package/demos/js/layout.js +0 -354
  72. package/demos/js/mondrian.js +0 -285
  73. package/demos/js/opacity.js +0 -275
  74. package/demos/js/painter.js +0 -484
  75. package/demos/js/particles-showcase.js +0 -514
  76. package/demos/js/particles.js +0 -299
  77. package/demos/js/patterns.js +0 -397
  78. package/demos/js/penrose/artifact.js +0 -69
  79. package/demos/js/penrose/blackhole.js +0 -121
  80. package/demos/js/penrose/constants.js +0 -73
  81. package/demos/js/penrose/game.js +0 -943
  82. package/demos/js/penrose/lore.js +0 -278
  83. package/demos/js/penrose/penrosescene.js +0 -892
  84. package/demos/js/penrose/ship.js +0 -216
  85. package/demos/js/penrose/sounds.js +0 -211
  86. package/demos/js/penrose/voidparticle.js +0 -55
  87. package/demos/js/penrose/voidscene.js +0 -258
  88. package/demos/js/penrose/voidship.js +0 -144
  89. package/demos/js/penrose/wormhole.js +0 -46
  90. package/demos/js/pipeline.js +0 -555
  91. package/demos/js/plane3d.js +0 -256
  92. package/demos/js/platformer.js +0 -1579
  93. package/demos/js/scene.js +0 -304
  94. package/demos/js/scenes.js +0 -320
  95. package/demos/js/schrodinger.js +0 -410
  96. package/demos/js/schwarzschild.js +0 -1023
  97. package/demos/js/shapes.js +0 -628
  98. package/demos/js/space/alien.js +0 -171
  99. package/demos/js/space/boom.js +0 -98
  100. package/demos/js/space/boss.js +0 -353
  101. package/demos/js/space/buff.js +0 -73
  102. package/demos/js/space/bullet.js +0 -102
  103. package/demos/js/space/constants.js +0 -85
  104. package/demos/js/space/game.js +0 -1884
  105. package/demos/js/space/hud.js +0 -112
  106. package/demos/js/space/laserbeam.js +0 -179
  107. package/demos/js/space/lightning.js +0 -277
  108. package/demos/js/space/minion.js +0 -192
  109. package/demos/js/space/missile.js +0 -212
  110. package/demos/js/space/player.js +0 -430
  111. package/demos/js/space/powerup.js +0 -90
  112. package/demos/js/space/starfield.js +0 -58
  113. package/demos/js/space/starpower.js +0 -90
  114. package/demos/js/spacetime.js +0 -559
  115. package/demos/js/sphere3d.js +0 -229
  116. package/demos/js/sprite.js +0 -473
  117. package/demos/js/svgtween.js +0 -204
  118. package/demos/js/tde/accretiondisk.js +0 -471
  119. package/demos/js/tde/blackhole.js +0 -219
  120. package/demos/js/tde/blackholescene.js +0 -209
  121. package/demos/js/tde/config.js +0 -59
  122. package/demos/js/tde/index.js +0 -820
  123. package/demos/js/tde/jets.js +0 -290
  124. package/demos/js/tde/lensedstarfield.js +0 -154
  125. package/demos/js/tde/tdestar.js +0 -297
  126. package/demos/js/tde/tidalstream.js +0 -372
  127. package/demos/js/tde_old/blackhole.obj.js +0 -354
  128. package/demos/js/tde_old/debris.obj.js +0 -791
  129. package/demos/js/tde_old/flare.obj.js +0 -239
  130. package/demos/js/tde_old/index.js +0 -448
  131. package/demos/js/tde_old/star.obj.js +0 -812
  132. package/demos/js/tiles.js +0 -312
  133. package/demos/js/tweendemo.js +0 -79
  134. package/demos/js/visibility.js +0 -102
  135. package/demos/kerr.html +0 -28
  136. package/demos/lavalamp.html +0 -27
  137. package/demos/layouts.html +0 -37
  138. package/demos/logo.svg +0 -4
  139. package/demos/loop.html +0 -84
  140. package/demos/mondrian.html +0 -32
  141. package/demos/og_image.png +0 -0
  142. package/demos/opacity.html +0 -36
  143. package/demos/painter.html +0 -39
  144. package/demos/particles-showcase.html +0 -28
  145. package/demos/particles.html +0 -24
  146. package/demos/patterns.html +0 -33
  147. package/demos/penrose-game.html +0 -31
  148. package/demos/pipeline.html +0 -737
  149. package/demos/plane3d.html +0 -24
  150. package/demos/platformer.html +0 -43
  151. package/demos/scene.html +0 -33
  152. package/demos/scenes.html +0 -96
  153. package/demos/schrodinger.html +0 -27
  154. package/demos/schwarzschild.html +0 -27
  155. package/demos/shapes.html +0 -16
  156. package/demos/space.html +0 -85
  157. package/demos/spacetime.html +0 -27
  158. package/demos/sphere3d.html +0 -24
  159. package/demos/sprite.html +0 -18
  160. package/demos/svgtween.html +0 -29
  161. package/demos/tde.html +0 -28
  162. package/demos/tiles.html +0 -28
  163. package/demos/transforms.html +0 -400
  164. package/demos/tween.html +0 -45
  165. package/demos/visibility.html +0 -33
  166. package/docs/README.md +0 -230
  167. package/docs/api/FluidSystem.md +0 -173
  168. package/docs/concepts/architecture-overview.md +0 -204
  169. package/docs/concepts/coordinate-system.md +0 -384
  170. package/docs/concepts/lifecycle.md +0 -255
  171. package/docs/concepts/rendering-pipeline.md +0 -279
  172. package/docs/concepts/shapes-vs-gameobjects.md +0 -187
  173. package/docs/concepts/tde-zorder.md +0 -106
  174. package/docs/concepts/two-layer-architecture.md +0 -229
  175. package/docs/fluid-dynamics.md +0 -99
  176. package/docs/getting-started/first-game.md +0 -354
  177. package/docs/getting-started/hello-world.md +0 -269
  178. package/docs/getting-started/installation.md +0 -175
  179. package/docs/modules/collision/README.md +0 -453
  180. package/docs/modules/fluent/README.md +0 -1075
  181. package/docs/modules/game/README.md +0 -303
  182. package/docs/modules/isometric-camera.md +0 -210
  183. package/docs/modules/isometric.md +0 -275
  184. package/docs/modules/painter/README.md +0 -328
  185. package/docs/modules/particle/README.md +0 -559
  186. package/docs/modules/shapes/README.md +0 -221
  187. package/docs/modules/shapes/base/euclidian.md +0 -123
  188. package/docs/modules/shapes/base/geometry2d.md +0 -204
  189. package/docs/modules/shapes/base/renderable.md +0 -215
  190. package/docs/modules/shapes/base/shape.md +0 -262
  191. package/docs/modules/shapes/base/transformable.md +0 -243
  192. package/docs/modules/shapes/hierarchy.md +0 -218
  193. package/docs/modules/state/README.md +0 -577
  194. package/docs/modules/util/README.md +0 -99
  195. package/docs/modules/util/camera3d.md +0 -412
  196. package/docs/modules/util/scene3d.md +0 -395
  197. package/index.html +0 -17
  198. package/jsdoc.json +0 -50
  199. package/scripts/build-demo.js +0 -69
  200. package/scripts/bundle4llm.js +0 -276
  201. package/scripts/clearconsole.js +0 -48
  202. package/test/math/orbital.test.js +0 -61
  203. package/test/math/tensor.test.js +0 -114
  204. package/test/particle/emitter.test.js +0 -204
  205. package/test/particle/particle-system.test.js +0 -310
  206. package/test/particle/particle.test.js +0 -116
  207. package/test/particle/updaters.test.js +0 -386
  208. package/test/setup.js +0 -120
  209. package/test/shapes/euclidian.test.js +0 -44
  210. package/test/shapes/geometry.test.js +0 -86
  211. package/test/shapes/group.test.js +0 -86
  212. package/test/shapes/rectangle.test.js +0 -64
  213. package/test/shapes/transform.test.js +0 -379
  214. package/test/util/camera3d.test.js +0 -428
  215. package/test/util/scene3d.test.js +0 -352
  216. package/vite.config.js +0 -50
  217. package/vitest.config.js +0 -13
@@ -1,279 +0,0 @@
1
- # Rendering Pipeline
2
-
3
- > The shape inheritance chain from Euclidian to concrete shapes.
4
-
5
- ## Overview
6
-
7
- Every visual element in GCanvas inherits from a chain of base classes. Each layer adds specific functionality, building from simple spatial properties to full rendering capabilities.
8
-
9
- ## The Inheritance Chain
10
-
11
- ```
12
- ┌─────────────────────────────────────────────────────────────────┐
13
- │ │
14
- │ Euclidian │
15
- │ ├── x, y (position) │
16
- │ ├── width, height (dimensions) │
17
- │ └── debug rendering support │
18
- │ │ │
19
- │ ▼ │
20
- │ Geometry2d │
21
- │ ├── getBounds() - bounding box calculation │
22
- │ ├── minX, maxX, minY, maxY - constraints │
23
- │ ├── crisp - pixel-perfect alignment │
24
- │ └── dirty flag tracking │
25
- │ │ │
26
- │ ▼ │
27
- │ Traceable │
28
- │ ├── drawDebug() - debug visualization │
29
- │ └── logging capabilities │
30
- │ │ │
31
- │ ▼ │
32
- │ Renderable │
33
- │ ├── visible - show/hide │
34
- │ ├── opacity - transparency (0-1) │
35
- │ ├── shadowColor, shadowBlur, shadowOffset │
36
- │ ├── blendMode - canvas composite operation │
37
- │ ├── zIndex - stacking order │
38
- │ └── render() - main render lifecycle │
39
- │ │ │
40
- │ ▼ │
41
- │ Transformable │
42
- │ ├── rotation - angle in radians │
43
- │ ├── scaleX, scaleY - scaling factors │
44
- │ ├── applyTransforms() - canvas transform │
45
- │ └── getTransformedBounds() - rotated bounds │
46
- │ │ │
47
- │ ▼ │
48
- │ Shape │
49
- │ ├── color - fill color │
50
- │ ├── stroke - stroke color │
51
- │ ├── lineWidth, lineJoin, lineCap │
52
- │ └── draw() - abstract (override in subclasses) │
53
- │ │ │
54
- │ ▼ │
55
- │ ┌─────────┬─────────┬─────────┬─────────┬─────────┐ │
56
- │ │ Circle │Rectangle│ Star │ Cube │ ... │ │
57
- │ │ draw() │ draw() │ draw() │ draw() │ │ │
58
- │ └─────────┴─────────┴─────────┴─────────┴─────────┘ │
59
- │ │
60
- └─────────────────────────────────────────────────────────────────┘
61
- ```
62
-
63
- ## Layer Details
64
-
65
- ### 1. Euclidian
66
-
67
- **Source:** `src/shapes/euclidian.js`
68
-
69
- The foundation class providing basic spatial properties.
70
-
71
- ```js
72
- class Euclidian {
73
- x = 0; // Center X position
74
- y = 0; // Center Y position
75
- width = 0; // Width
76
- height = 0; // Height
77
- }
78
- ```
79
-
80
- **Key Concept:** Position is center-based, not top-left. A shape at `(100, 100)` has its center at that point.
81
-
82
- ### 2. Geometry2d
83
-
84
- **Source:** `src/shapes/geometry.js`
85
-
86
- Adds bounding box calculations and positional constraints.
87
-
88
- ```js
89
- // Get the bounding box
90
- const bounds = shape.getBounds();
91
- // { x, y, width, height }
92
-
93
- // Constrain position
94
- shape.minX = 0;
95
- shape.maxX = 800;
96
- shape.applyConstraints();
97
- ```
98
-
99
- ### 3. Traceable
100
-
101
- **Source:** `src/shapes/traceable.js`
102
-
103
- Adds debug visualization capabilities.
104
-
105
- ```js
106
- shape.drawDebug(ctx); // Draw bounding box and center point
107
- ```
108
-
109
- ### 4. Renderable
110
-
111
- **Source:** `src/shapes/renderable.js`
112
-
113
- Adds visual properties and the main `render()` lifecycle.
114
-
115
- ```js
116
- shape.visible = true;
117
- shape.opacity = 0.8;
118
- shape.shadowColor = 'rgba(0,0,0,0.5)';
119
- shape.shadowBlur = 10;
120
- shape.shadowOffsetX = 5;
121
- shape.shadowOffsetY = 5;
122
- ```
123
-
124
- **The `render()` method:**
125
-
126
- ```js
127
- render() {
128
- if (!this.visible || this.opacity <= 0) return;
129
-
130
- Painter.save();
131
- Painter.effects.setBlendMode(this.blendMode);
132
- Painter.opacity.pushOpacity(this.opacity);
133
- Painter.translateTo(this.x, this.y);
134
-
135
- // Apply shadows
136
- if (this.shadowColor) {
137
- ctx.shadowColor = this.shadowColor;
138
- ctx.shadowBlur = this.shadowBlur;
139
- ctx.shadowOffsetX = this.shadowOffsetX;
140
- ctx.shadowOffsetY = this.shadowOffsetY;
141
- }
142
-
143
- this.draw(); // Call subclass implementation
144
-
145
- Painter.opacity.popOpacity();
146
- Painter.restore();
147
- }
148
- ```
149
-
150
- ### 5. Transformable
151
-
152
- **Source:** `src/shapes/transformable.js`
153
-
154
- Adds rotation and scaling.
155
-
156
- ```js
157
- shape.rotation = Math.PI / 4; // 45 degrees
158
- shape.scaleX = 2.0;
159
- shape.scaleY = 0.5;
160
- ```
161
-
162
- **Transform application:**
163
-
164
- ```js
165
- applyTransforms() {
166
- if (this.rotation !== 0) {
167
- Painter.rotate(this.rotation);
168
- }
169
- if (this.scaleX !== 1 || this.scaleY !== 1) {
170
- Painter.scale(this.scaleX, this.scaleY);
171
- }
172
- }
173
- ```
174
-
175
- ### 6. Shape
176
-
177
- **Source:** `src/shapes/shape.js`
178
-
179
- Adds canvas styling (fill and stroke).
180
-
181
- ```js
182
- const circle = new Circle(50, {
183
- color: 'red', // Fill color
184
- stroke: 'black', // Stroke color
185
- lineWidth: 2, // Stroke width
186
- lineJoin: 'round', // Line join style
187
- lineCap: 'round' // Line cap style
188
- });
189
- ```
190
-
191
- ## The Render Flow
192
-
193
- When `shape.render()` is called (or `shape.draw()` directly):
194
-
195
- ```
196
- 1. render() called
197
-
198
- ├─► Check visible && opacity > 0
199
-
200
- ├─► Painter.save() ─── Save canvas state
201
-
202
- ├─► Set blend mode
203
-
204
- ├─► Push opacity
205
-
206
- ├─► Translate to (x, y) ─── Move to shape center
207
-
208
- ├─► Apply shadows
209
-
210
- ├─► draw() called ─── Subclass implementation
211
- │ │
212
- │ ├─► applyTransforms() ─── Rotation & scale
213
- │ │
214
- │ └─► Painter.shapes.* ─── Actual drawing
215
-
216
- ├─► Pop opacity
217
-
218
- └─► Painter.restore() ─── Restore canvas state
219
- ```
220
-
221
- ## Coordinate System
222
-
223
- GCanvas uses a **center-based** coordinate system:
224
-
225
- ```
226
- ┌────────────────────────────────────┐
227
- │ Canvas │
228
- │ │
229
- │ (0,0) top-left │
230
- │ ┌──────────────────┐ │
231
- │ │ │ │
232
- │ │ (x, y) │ │
233
- │ │ ●──────────┼─width │
234
- │ │ │ │ │
235
- │ │ │ │ │
236
- │ └───────┼──────────┘ │
237
- │ height │
238
- │ │
239
- └────────────────────────────────────┘
240
- ```
241
-
242
- The `(x, y)` point is the **center** of the shape, not the top-left corner.
243
-
244
- ## Creating Custom Shapes
245
-
246
- Extend `Shape` and implement `draw()`:
247
-
248
- ```js
249
- import { Shape, Painter } from '@guinetik/gcanvas';
250
-
251
- class CustomShape extends Shape {
252
- constructor(options = {}) {
253
- super(options);
254
- this.customProp = options.customProp ?? 'default';
255
- }
256
-
257
- draw() {
258
- super.draw(); // Apply transforms
259
-
260
- // Draw using Painter
261
- Painter.shapes.fillCircle(0, 0, this.width / 2, this.color);
262
- Painter.shapes.strokeCircle(0, 0, this.width / 2, this.stroke, this.lineWidth);
263
- }
264
- }
265
- ```
266
-
267
- ## Related
268
-
269
- - [Architecture Overview](./architecture-overview.md) - Full system architecture
270
- - [Two-Layer Architecture](./two-layer-architecture.md) - Shape vs Game layer
271
- - [Shape Hierarchy](../modules/shapes/hierarchy.md) - Detailed class documentation
272
-
273
- ## See Also
274
-
275
- - [Euclidian](../modules/shapes/base/euclidian.md)
276
- - [Geometry2d](../modules/shapes/base/geometry2d.md)
277
- - [Renderable](../modules/shapes/base/renderable.md)
278
- - [Transformable](../modules/shapes/base/transformable.md)
279
- - [Shape](../modules/shapes/base/shape.md)
@@ -1,187 +0,0 @@
1
- # Shapes vs GameObjects
2
-
3
- GCanvas serves two distinct use cases with different abstractions. Understanding when to use each is key to working effectively with the library.
4
-
5
- ## Overview
6
-
7
- | Aspect | Shapes | GameObjects |
8
- |--------|--------|-------------|
9
- | Purpose | Direct canvas rendering | Managed game pipeline |
10
- | Game loop | Not required | Required |
11
- | Rendering | Call `render()` manually | Automatic via pipeline |
12
- | State | Stateless between frames | Maintains state |
13
- | Lifecycle | None | `update(dt)` / `draw()` |
14
- | Best for | Generative art, static visuals | Games, animations, interactive apps |
15
-
16
- ## The Two Hierarchies
17
-
18
- ### Shape Hierarchy (Drawing)
19
-
20
- ```
21
- Euclidian → Geometry2d → Renderable → Transformable → Shape
22
- ```
23
-
24
- - **Euclidian**: Basic positioning (x, y, width, height)
25
- - **Geometry2d**: Bounds constraints, bounding box calculations
26
- - **Renderable**: Visibility, opacity, shadows
27
- - **Transformable**: Rotation, scaling
28
- - **Shape**: Styling (fill, stroke, lineWidth)
29
-
30
- ### GameObject Hierarchy (Pipeline)
31
-
32
- ```
33
- GameObject → Scene / Sprite / Text
34
- ```
35
-
36
- - **GameObject**: Base class with `update(dt)` and `draw()` lifecycle
37
- - **Scene**: Container for other GameObjects
38
- - **Sprite**: Animated GameObject with frame-by-frame timeline
39
- - **Text**: Text rendering with automatic updates
40
-
41
- ### Containers
42
-
43
- | Container | Holds | Has update()? |
44
- |-----------|-------|---------------|
45
- | `Group` | Shapes | No |
46
- | `Scene` | GameObjects | Yes |
47
-
48
- ## When to Use What
49
-
50
- | Use Case | Use This | Why |
51
- |----------|----------|-----|
52
- | Static visualization | `Shape` + `render()` | No update loop needed |
53
- | Generative art | `Shape`, `Group` | Direct control, no overhead |
54
- | Game character | `Sprite` (GameObject) | Needs update cycle for animation |
55
- | UI elements | `Text`, `Scene` | Pipeline handles positioning |
56
- | Complex scene | `Scene` with children | Hierarchical transforms, lifecycle |
57
- | Composite shape | `Group` | Transform multiple shapes together |
58
-
59
- ## Example: Shapes Only (No Game Loop)
60
-
61
- You can use GCanvas purely for drawing without any game infrastructure:
62
-
63
- ```javascript
64
- import { Circle, Rectangle, Group, Painter } from "gcanvas";
65
-
66
- // Get canvas context
67
- const canvas = document.getElementById("canvas");
68
- const ctx = canvas.getContext("2d");
69
- Painter.ctx = ctx;
70
-
71
- // Create shapes
72
- const circle = new Circle(50, { x: 100, y: 100, color: "#0f0" });
73
- const rect = new Rectangle({ x: 200, y: 100, width: 80, height: 60, color: "#0ff" });
74
-
75
- // Render directly - no game loop needed
76
- circle.render();
77
- rect.render();
78
-
79
- // Group multiple shapes
80
- const group = new Group({ x: 300, y: 100, rotation: Math.PI / 4 });
81
- group.add(new Circle(20, { color: "#f0f" }));
82
- group.add(new Rectangle({ y: 30, width: 40, height: 20, color: "#ff0" }));
83
- group.render();
84
- ```
85
-
86
- > **Note:** This is perfect for one-off drawings, generative art, or when you want full control over the render loop.
87
-
88
- ## Example: GameObjects with Pipeline
89
-
90
- When you need animation, input handling, and managed lifecycles:
91
-
92
- ```javascript
93
- import { Game, Scene, Sprite, Text, Circle, Keys } from "gcanvas";
94
-
95
- class MyGame extends Game {
96
- init() {
97
- super.init();
98
-
99
- // Create a scene (GameObject container)
100
- this.scene = new Scene(this, { anchor: "center" });
101
-
102
- // Create a sprite with animation (GameObject)
103
- this.player = new Sprite(this, { x: 0, y: 0, frameRate: 10 });
104
- this.player.addFrame(new Circle(20, { color: "#0f0" }));
105
- this.player.addFrame(new Circle(25, { color: "#0ff" }));
106
- this.player.play();
107
-
108
- // Add to scene
109
- this.scene.add(this.player);
110
-
111
- // Add scene to pipeline - now it's managed
112
- this.pipeline.add(this.scene);
113
-
114
- // Input handling
115
- this.events.on(Keys.SPACE, () => this.player.pause());
116
- }
117
-
118
- update(dt) {
119
- super.update(dt);
120
- // Player sprite automatically updates via pipeline
121
- }
122
- }
123
- ```
124
-
125
- > **Note:** GameObjects get their `update(dt)` called automatically by the pipeline each frame.
126
-
127
- ## Bridging: Shape to GameObject
128
-
129
- Sometimes you have a Shape (or Group of shapes) that you want to add to the pipeline. Use `ShapeGOFactory`:
130
-
131
- ```javascript
132
- import { Game, Group, Circle, Rectangle, ShapeGOFactory } from "gcanvas";
133
-
134
- class MyGame extends Game {
135
- init() {
136
- super.init();
137
-
138
- // Create a Group of shapes
139
- const avatar = new Group();
140
- avatar.add(new Circle(30, { color: "#0f0" })); // head
141
- avatar.add(new Rectangle({ y: 50, width: 40, height: 60, color: "#0f0" })); // body
142
-
143
- // Wrap it as a GameObject so it can join the pipeline
144
- const avatarGO = ShapeGOFactory.create(this, avatar, {
145
- x: 100,
146
- y: 100,
147
- interactive: true // enables click/hover events
148
- });
149
-
150
- // Now it's a proper GameObject
151
- this.pipeline.add(avatarGO);
152
- }
153
- }
154
- ```
155
-
156
- > **Important:** Never put GameObjects inside Groups. Group is a Shape container - it won't call `update()` on its children. Always use Scene for GameObjects.
157
-
158
- ## Quick Reference
159
-
160
- | Class | Type | Container | Has update()? |
161
- |-------|------|-----------|---------------|
162
- | `Circle`, `Rectangle`, etc. | Shape | Group | No |
163
- | `Group` | Shape container | Group | No |
164
- | `TextShape` | Shape | Group | No |
165
- | `GameObject` | Base GO | Scene / Pipeline | Yes |
166
- | `Scene` | GO container | Scene / Pipeline | Yes |
167
- | `Sprite` | Animated GO | Scene / Pipeline | Yes |
168
- | `Text` | Text GO | Scene / Pipeline | Yes |
169
-
170
- ## TL;DR
171
-
172
- **Just Drawing?**
173
- - Use `Shape`, `Group`
174
- - Call `.render()` yourself
175
- - No Game class needed
176
-
177
- **Building a Game?**
178
- - Use `GameObject`, `Scene`, `Sprite`
179
- - Add to `pipeline`
180
- - Extend `Game` class
181
-
182
- ## See Also
183
-
184
- - [Coordinate System](./coordinate-system.md) - How positioning works (center-based, parent-child, Camera3D)
185
- - [Rendering Pipeline](./rendering-pipeline.md) - Deep dive into the Shape hierarchy
186
- - [Architecture Overview](./architecture-overview.md) - High-level system design
187
- - [Lifecycle](./lifecycle.md) - GameObject lifecycle details
@@ -1,106 +0,0 @@
1
- # TDE Demo Z-Order Rendering System
2
-
3
- This document describes the z-ordering (depth sorting) system used in the Tidal Disruption Event (TDE) demo.
4
-
5
- ## Overview
6
-
7
- The TDE demo uses a 3D scene with multiple objects that need to be rendered in the correct order based on their depth relative to the camera. The system uses a combination of:
8
-
9
- 1. **Static z-index buckets** for objects that always render in a fixed order
10
- 2. **Dynamic z-index updates** for objects whose render order depends on camera position
11
-
12
- ## Z-Index Buckets
13
-
14
- Objects are assigned to z-index buckets. Lower z-index values render first (behind), higher values render later (in front).
15
-
16
- **Only the Star has a dynamic z-index** that changes based on its position relative to the camera. The TidalStream particles always render on top for a cleaner visual effect.
17
-
18
- | Object | Z-Index | Description |
19
- |--------|---------|-------------|
20
- | Star (back) | 10 | Star when behind black hole |
21
- | BlackHole | 15 | Dark shadow - at the back |
22
- | AccretionDisk | 20 | Disk renders over the black hole |
23
- | Star (front) | 25 | Star when in front of black hole |
24
- | TidalStream | 30 | Particles - always on top |
25
- | RelativisticJets | 40 | Jets - always on top |
26
-
27
- ### Layering by Camera View
28
-
29
- **When star is IN FRONT of black hole:**
30
- - Stream (30) > Star (25) > Disk (20) > BlackHole (15)
31
-
32
- **When star is BEHIND black hole:**
33
- - Stream (30) > Disk (20) > BlackHole (15) > Star (10)
34
-
35
- The accretion disk particles curve around the black hole visually, and the stream always stays on top.
36
-
37
- ## Rendering Rules
38
-
39
- ### Rule 1: TidalStream Always Behind Star
40
- The tidal stream particles (z-index 10) always render behind the star (z-index 25-35). This ensures the star is always visible and the stream appears to emanate from behind/around it.
41
-
42
- ### Rule 2: Star in Front of Black Hole (When Closer)
43
- When the star is closer to the camera than the black hole, the star's z-index is set to 35 (starFront), which is higher than the black hole's z-index of 30. This causes the star to render after (on top of) the black hole.
44
-
45
- ### Rule 3: Black Hole in Front of Star (When Star is Behind)
46
- When the star is farther from the camera than the black hole, the star's z-index is set to 25 (starBack), which is lower than the black hole's z-index of 30. This causes the black hole to render after (on top of) the star.
47
-
48
- ## Dynamic Z-Order Algorithm
49
-
50
- The `BlackHoleScene.updateStarZOrder()` method handles dynamic z-ordering:
51
-
52
- ```javascript
53
- updateStarZOrder() {
54
- const camera = this.game.camera;
55
-
56
- // Project star position to get depth after camera rotation
57
- const projStar = camera.project(star.x, star.y, star.z);
58
-
59
- // Black hole is always at origin
60
- const projBH = camera.project(0, 0, 0);
61
-
62
- // Lower projected z = closer to camera
63
- const starInFront = projStar.z < projBH.z;
64
-
65
- // Update z-index based on depth comparison
66
- star.zIndex = starInFront ? Z.starFront : Z.starBack;
67
- }
68
- ```
69
-
70
- ### Critical: Update Order
71
-
72
- The z-order update **must be called AFTER** the star position is updated each frame. This is done in `TDEDemo.update()` at the end, after all state-based position updates:
73
-
74
- ```javascript
75
- // In TDEDemo.update(), at the end:
76
- if (this.scene) {
77
- this.scene.updateStarZOrder();
78
- }
79
- ```
80
-
81
- If called before the position update, it uses stale position data and causes incorrect ordering.
82
-
83
- ## Camera3D Projection
84
-
85
- The `Camera3D.project()` method returns:
86
- - `x, y`: Screen position
87
- - `z`: Depth after rotation (lower = closer to camera)
88
- - `scale`: Perspective scale factor
89
-
90
- The depth (`z`) value is used for z-order comparisons. Objects with lower depth values are closer to the camera and should render on top.
91
-
92
- ## Scene3D Sorting
93
-
94
- `Scene3D` sorts children before rendering:
95
-
96
- 1. **Primary sort**: By `zIndex` (lower renders first)
97
- 2. **Secondary sort**: By projected `z` depth (back-to-front, as tie-breaker)
98
-
99
- This ensures objects with different z-indices render in the correct order, while objects with the same z-index are sorted by actual depth.
100
-
101
- ## Implementation Files
102
-
103
- - `demos/js/tde/blackholescene.js` - Main scene with z-ordering logic
104
- - `src/game/objects/scene3d.js` - Base Scene3D with depth sorting
105
- - `src/util/camera3d.js` - Camera projection utilities
106
-