@guinetik/gcanvas 1.0.0

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 (349) hide show
  1. package/.github/workflows/release.yaml +70 -0
  2. package/.jshintrc +4 -0
  3. package/.vscode/settings.json +22 -0
  4. package/CLAUDE.md +310 -0
  5. package/blackhole.jpg +0 -0
  6. package/demo.png +0 -0
  7. package/demos/CNAME +1 -0
  8. package/demos/animations.html +31 -0
  9. package/demos/basic.html +38 -0
  10. package/demos/baskara.html +31 -0
  11. package/demos/bezier.html +35 -0
  12. package/demos/beziersignature.html +29 -0
  13. package/demos/blackhole.html +28 -0
  14. package/demos/blob.html +35 -0
  15. package/demos/demos.css +289 -0
  16. package/demos/easing.html +28 -0
  17. package/demos/events.html +195 -0
  18. package/demos/fluent.html +647 -0
  19. package/demos/fractals.html +36 -0
  20. package/demos/genart.html +26 -0
  21. package/demos/gendream.html +26 -0
  22. package/demos/group.html +36 -0
  23. package/demos/home.html +587 -0
  24. package/demos/index.html +364 -0
  25. package/demos/isometric.html +34 -0
  26. package/demos/js/animations.js +452 -0
  27. package/demos/js/basic.js +204 -0
  28. package/demos/js/baskara.js +751 -0
  29. package/demos/js/bezier.js +692 -0
  30. package/demos/js/beziersignature.js +241 -0
  31. package/demos/js/blackhole/accretiondisk.obj.js +379 -0
  32. package/demos/js/blackhole/blackhole.obj.js +318 -0
  33. package/demos/js/blackhole/index.js +409 -0
  34. package/demos/js/blackhole/particle.js +56 -0
  35. package/demos/js/blackhole/starfield.obj.js +218 -0
  36. package/demos/js/blob.js +2263 -0
  37. package/demos/js/easing.js +477 -0
  38. package/demos/js/fluent.js +183 -0
  39. package/demos/js/fractals.js +931 -0
  40. package/demos/js/fractalworker.js +93 -0
  41. package/demos/js/genart.js +268 -0
  42. package/demos/js/gendream.js +209 -0
  43. package/demos/js/group.js +140 -0
  44. package/demos/js/info-toggle.js +25 -0
  45. package/demos/js/isometric.js +863 -0
  46. package/demos/js/kerr.js +1556 -0
  47. package/demos/js/lavalamp.js +590 -0
  48. package/demos/js/layout.js +354 -0
  49. package/demos/js/mondrian.js +285 -0
  50. package/demos/js/opacity.js +275 -0
  51. package/demos/js/painter.js +484 -0
  52. package/demos/js/particles-showcase.js +514 -0
  53. package/demos/js/particles.js +299 -0
  54. package/demos/js/patterns.js +397 -0
  55. package/demos/js/penrose/artifact.js +69 -0
  56. package/demos/js/penrose/blackhole.js +121 -0
  57. package/demos/js/penrose/constants.js +73 -0
  58. package/demos/js/penrose/game.js +943 -0
  59. package/demos/js/penrose/lore.js +278 -0
  60. package/demos/js/penrose/penrosescene.js +892 -0
  61. package/demos/js/penrose/ship.js +216 -0
  62. package/demos/js/penrose/sounds.js +211 -0
  63. package/demos/js/penrose/voidparticle.js +55 -0
  64. package/demos/js/penrose/voidscene.js +258 -0
  65. package/demos/js/penrose/voidship.js +144 -0
  66. package/demos/js/penrose/wormhole.js +46 -0
  67. package/demos/js/pipeline.js +555 -0
  68. package/demos/js/scene.js +304 -0
  69. package/demos/js/scenes.js +320 -0
  70. package/demos/js/schrodinger.js +410 -0
  71. package/demos/js/schwarzschild.js +1023 -0
  72. package/demos/js/shapes.js +628 -0
  73. package/demos/js/space/alien.js +171 -0
  74. package/demos/js/space/boom.js +98 -0
  75. package/demos/js/space/boss.js +353 -0
  76. package/demos/js/space/buff.js +73 -0
  77. package/demos/js/space/bullet.js +102 -0
  78. package/demos/js/space/constants.js +85 -0
  79. package/demos/js/space/game.js +1884 -0
  80. package/demos/js/space/hud.js +112 -0
  81. package/demos/js/space/laserbeam.js +179 -0
  82. package/demos/js/space/lightning.js +277 -0
  83. package/demos/js/space/minion.js +192 -0
  84. package/demos/js/space/missile.js +212 -0
  85. package/demos/js/space/player.js +430 -0
  86. package/demos/js/space/powerup.js +90 -0
  87. package/demos/js/space/starfield.js +58 -0
  88. package/demos/js/space/starpower.js +90 -0
  89. package/demos/js/spacetime.js +559 -0
  90. package/demos/js/svgtween.js +204 -0
  91. package/demos/js/tde/accretiondisk.js +418 -0
  92. package/demos/js/tde/blackhole.js +219 -0
  93. package/demos/js/tde/blackholescene.js +209 -0
  94. package/demos/js/tde/config.js +59 -0
  95. package/demos/js/tde/index.js +695 -0
  96. package/demos/js/tde/jets.js +290 -0
  97. package/demos/js/tde/lensedstarfield.js +147 -0
  98. package/demos/js/tde/tdestar.js +317 -0
  99. package/demos/js/tde/tidalstream.js +356 -0
  100. package/demos/js/tde_old/blackhole.obj.js +354 -0
  101. package/demos/js/tde_old/debris.obj.js +791 -0
  102. package/demos/js/tde_old/flare.obj.js +239 -0
  103. package/demos/js/tde_old/index.js +448 -0
  104. package/demos/js/tde_old/star.obj.js +812 -0
  105. package/demos/js/tiles.js +312 -0
  106. package/demos/js/tweendemo.js +79 -0
  107. package/demos/js/visibility.js +102 -0
  108. package/demos/kerr.html +28 -0
  109. package/demos/lavalamp.html +27 -0
  110. package/demos/layouts.html +37 -0
  111. package/demos/logo.svg +4 -0
  112. package/demos/loop.html +84 -0
  113. package/demos/mondrian.html +32 -0
  114. package/demos/og_image.png +0 -0
  115. package/demos/opacity.html +36 -0
  116. package/demos/painter.html +39 -0
  117. package/demos/particles-showcase.html +28 -0
  118. package/demos/particles.html +24 -0
  119. package/demos/patterns.html +33 -0
  120. package/demos/penrose-game.html +31 -0
  121. package/demos/pipeline.html +737 -0
  122. package/demos/scene.html +33 -0
  123. package/demos/scenes.html +96 -0
  124. package/demos/schrodinger.html +27 -0
  125. package/demos/schwarzschild.html +27 -0
  126. package/demos/shapes.html +16 -0
  127. package/demos/space.html +85 -0
  128. package/demos/spacetime.html +27 -0
  129. package/demos/svgtween.html +29 -0
  130. package/demos/tde.html +28 -0
  131. package/demos/tiles.html +28 -0
  132. package/demos/transforms.html +400 -0
  133. package/demos/tween.html +45 -0
  134. package/demos/visibility.html +33 -0
  135. package/disk_example.png +0 -0
  136. package/docs/README.md +222 -0
  137. package/docs/concepts/architecture-overview.md +204 -0
  138. package/docs/concepts/lifecycle.md +255 -0
  139. package/docs/concepts/rendering-pipeline.md +279 -0
  140. package/docs/concepts/tde-zorder.md +106 -0
  141. package/docs/concepts/two-layer-architecture.md +229 -0
  142. package/docs/getting-started/first-game.md +354 -0
  143. package/docs/getting-started/hello-world.md +269 -0
  144. package/docs/getting-started/installation.md +157 -0
  145. package/docs/modules/collision/README.md +453 -0
  146. package/docs/modules/fluent/README.md +1075 -0
  147. package/docs/modules/game/README.md +303 -0
  148. package/docs/modules/isometric-camera.md +210 -0
  149. package/docs/modules/isometric.md +275 -0
  150. package/docs/modules/painter/README.md +328 -0
  151. package/docs/modules/particle/README.md +559 -0
  152. package/docs/modules/shapes/README.md +221 -0
  153. package/docs/modules/shapes/base/euclidian.md +123 -0
  154. package/docs/modules/shapes/base/geometry2d.md +204 -0
  155. package/docs/modules/shapes/base/renderable.md +215 -0
  156. package/docs/modules/shapes/base/shape.md +262 -0
  157. package/docs/modules/shapes/base/transformable.md +243 -0
  158. package/docs/modules/shapes/hierarchy.md +218 -0
  159. package/docs/modules/state/README.md +577 -0
  160. package/docs/modules/util/README.md +99 -0
  161. package/docs/modules/util/camera3d.md +412 -0
  162. package/docs/modules/util/scene3d.md +395 -0
  163. package/index.html +17 -0
  164. package/jsdoc.json +50 -0
  165. package/package.json +55 -0
  166. package/readme.md +599 -0
  167. package/scripts/build-demo.js +69 -0
  168. package/scripts/bundle4llm.js +276 -0
  169. package/scripts/clearconsole.js +48 -0
  170. package/src/collision/collision-system.js +332 -0
  171. package/src/collision/collision.js +303 -0
  172. package/src/collision/index.js +10 -0
  173. package/src/fluent/fluent-game.js +430 -0
  174. package/src/fluent/fluent-go.js +1060 -0
  175. package/src/fluent/fluent-layer.js +152 -0
  176. package/src/fluent/fluent-scene.js +291 -0
  177. package/src/fluent/index.js +98 -0
  178. package/src/fluent/sketch.js +380 -0
  179. package/src/game/game.js +467 -0
  180. package/src/game/index.js +49 -0
  181. package/src/game/objects/go.js +220 -0
  182. package/src/game/objects/imagego.js +30 -0
  183. package/src/game/objects/index.js +54 -0
  184. package/src/game/objects/isometric-scene.js +260 -0
  185. package/src/game/objects/layoutscene.js +549 -0
  186. package/src/game/objects/scene.js +175 -0
  187. package/src/game/objects/scene3d.js +118 -0
  188. package/src/game/objects/text.js +221 -0
  189. package/src/game/objects/wrapper.js +232 -0
  190. package/src/game/pipeline.js +243 -0
  191. package/src/game/ui/button.js +396 -0
  192. package/src/game/ui/cursor.js +93 -0
  193. package/src/game/ui/fps.js +91 -0
  194. package/src/game/ui/index.js +5 -0
  195. package/src/game/ui/togglebutton.js +93 -0
  196. package/src/game/ui/tooltip.js +249 -0
  197. package/src/index.js +25 -0
  198. package/src/io/events.js +20 -0
  199. package/src/io/index.js +86 -0
  200. package/src/io/input.js +70 -0
  201. package/src/io/keys.js +152 -0
  202. package/src/io/mouse.js +61 -0
  203. package/src/io/touch.js +39 -0
  204. package/src/logger/debugtab.js +138 -0
  205. package/src/logger/index.js +3 -0
  206. package/src/logger/loggable.js +47 -0
  207. package/src/logger/logger.js +113 -0
  208. package/src/math/complex.js +37 -0
  209. package/src/math/constants.js +1 -0
  210. package/src/math/fractal.js +1271 -0
  211. package/src/math/gr.js +201 -0
  212. package/src/math/heat.js +202 -0
  213. package/src/math/index.js +12 -0
  214. package/src/math/noise.js +433 -0
  215. package/src/math/orbital.js +191 -0
  216. package/src/math/patterns.js +1339 -0
  217. package/src/math/penrose.js +259 -0
  218. package/src/math/quantum.js +115 -0
  219. package/src/math/random.js +195 -0
  220. package/src/math/tensor.js +1009 -0
  221. package/src/mixins/anchor.js +131 -0
  222. package/src/mixins/draggable.js +72 -0
  223. package/src/mixins/index.js +2 -0
  224. package/src/motion/bezier.js +132 -0
  225. package/src/motion/bounce.js +58 -0
  226. package/src/motion/easing.js +349 -0
  227. package/src/motion/float.js +130 -0
  228. package/src/motion/follow.js +125 -0
  229. package/src/motion/hop.js +52 -0
  230. package/src/motion/index.js +82 -0
  231. package/src/motion/motion.js +1124 -0
  232. package/src/motion/orbit.js +49 -0
  233. package/src/motion/oscillate.js +39 -0
  234. package/src/motion/parabolic.js +141 -0
  235. package/src/motion/patrol.js +147 -0
  236. package/src/motion/pendulum.js +48 -0
  237. package/src/motion/pulse.js +88 -0
  238. package/src/motion/shake.js +83 -0
  239. package/src/motion/spiral.js +144 -0
  240. package/src/motion/spring.js +150 -0
  241. package/src/motion/swing.js +47 -0
  242. package/src/motion/tween.js +92 -0
  243. package/src/motion/tweenetik.js +139 -0
  244. package/src/motion/waypoint.js +210 -0
  245. package/src/painter/index.js +8 -0
  246. package/src/painter/painter.colors.js +331 -0
  247. package/src/painter/painter.effects.js +230 -0
  248. package/src/painter/painter.img.js +229 -0
  249. package/src/painter/painter.js +295 -0
  250. package/src/painter/painter.lines.js +189 -0
  251. package/src/painter/painter.opacity.js +41 -0
  252. package/src/painter/painter.shapes.js +277 -0
  253. package/src/painter/painter.text.js +273 -0
  254. package/src/particle/emitter.js +124 -0
  255. package/src/particle/index.js +11 -0
  256. package/src/particle/particle-system.js +322 -0
  257. package/src/particle/particle.js +71 -0
  258. package/src/particle/updaters.js +170 -0
  259. package/src/shapes/arc.js +43 -0
  260. package/src/shapes/arrow.js +33 -0
  261. package/src/shapes/bezier.js +42 -0
  262. package/src/shapes/circle.js +62 -0
  263. package/src/shapes/clouds.js +56 -0
  264. package/src/shapes/cone.js +219 -0
  265. package/src/shapes/cross.js +70 -0
  266. package/src/shapes/cube.js +244 -0
  267. package/src/shapes/cylinder.js +254 -0
  268. package/src/shapes/diamond.js +48 -0
  269. package/src/shapes/euclidian.js +111 -0
  270. package/src/shapes/figure.js +115 -0
  271. package/src/shapes/geometry.js +220 -0
  272. package/src/shapes/group.js +375 -0
  273. package/src/shapes/heart.js +42 -0
  274. package/src/shapes/hexagon.js +26 -0
  275. package/src/shapes/image.js +192 -0
  276. package/src/shapes/index.js +111 -0
  277. package/src/shapes/line.js +29 -0
  278. package/src/shapes/pattern.js +90 -0
  279. package/src/shapes/pin.js +44 -0
  280. package/src/shapes/poly.js +31 -0
  281. package/src/shapes/prism.js +226 -0
  282. package/src/shapes/rect.js +35 -0
  283. package/src/shapes/renderable.js +333 -0
  284. package/src/shapes/ring.js +26 -0
  285. package/src/shapes/roundrect.js +95 -0
  286. package/src/shapes/shape.js +117 -0
  287. package/src/shapes/slice.js +26 -0
  288. package/src/shapes/sphere.js +314 -0
  289. package/src/shapes/sphere3d.js +537 -0
  290. package/src/shapes/square.js +15 -0
  291. package/src/shapes/star.js +99 -0
  292. package/src/shapes/svg.js +408 -0
  293. package/src/shapes/text.js +553 -0
  294. package/src/shapes/traceable.js +83 -0
  295. package/src/shapes/transform.js +357 -0
  296. package/src/shapes/transformable.js +172 -0
  297. package/src/shapes/triangle.js +26 -0
  298. package/src/sound/index.js +17 -0
  299. package/src/sound/sound.js +473 -0
  300. package/src/sound/synth.analyzer.js +149 -0
  301. package/src/sound/synth.effects.js +207 -0
  302. package/src/sound/synth.envelope.js +59 -0
  303. package/src/sound/synth.js +229 -0
  304. package/src/sound/synth.musical.js +160 -0
  305. package/src/sound/synth.noise.js +85 -0
  306. package/src/sound/synth.oscillators.js +293 -0
  307. package/src/state/index.js +10 -0
  308. package/src/state/state-machine.js +371 -0
  309. package/src/util/camera3d.js +438 -0
  310. package/src/util/index.js +6 -0
  311. package/src/util/isometric-camera.js +235 -0
  312. package/src/util/layout.js +317 -0
  313. package/src/util/position.js +147 -0
  314. package/src/util/tasks.js +47 -0
  315. package/src/util/zindex.js +287 -0
  316. package/src/webgl/index.js +9 -0
  317. package/src/webgl/shaders/sphere-shaders.js +994 -0
  318. package/src/webgl/webgl-renderer.js +388 -0
  319. package/tde.png +0 -0
  320. package/test/math/orbital.test.js +61 -0
  321. package/test/math/tensor.test.js +114 -0
  322. package/test/particle/emitter.test.js +204 -0
  323. package/test/particle/particle-system.test.js +310 -0
  324. package/test/particle/particle.test.js +116 -0
  325. package/test/particle/updaters.test.js +386 -0
  326. package/test/setup.js +120 -0
  327. package/test/shapes/euclidian.test.js +44 -0
  328. package/test/shapes/geometry.test.js +86 -0
  329. package/test/shapes/group.test.js +86 -0
  330. package/test/shapes/rectangle.test.js +64 -0
  331. package/test/shapes/transform.test.js +379 -0
  332. package/test/util/camera3d.test.js +428 -0
  333. package/test/util/scene3d.test.js +352 -0
  334. package/types/collision.d.ts +249 -0
  335. package/types/common.d.ts +155 -0
  336. package/types/game.d.ts +497 -0
  337. package/types/index.d.ts +309 -0
  338. package/types/io.d.ts +188 -0
  339. package/types/logger.d.ts +127 -0
  340. package/types/math.d.ts +268 -0
  341. package/types/mixins.d.ts +92 -0
  342. package/types/motion.d.ts +678 -0
  343. package/types/painter.d.ts +378 -0
  344. package/types/shapes.d.ts +864 -0
  345. package/types/sound.d.ts +672 -0
  346. package/types/state.d.ts +251 -0
  347. package/types/util.d.ts +253 -0
  348. package/vite.config.js +50 -0
  349. package/vitest.config.js +13 -0
@@ -0,0 +1,204 @@
1
+ # Architecture Overview
2
+
3
+ > High-level system architecture, module relationships, and design philosophy.
4
+
5
+ ## Overview
6
+
7
+ GCanvas is a modular 2D rendering and game framework built on top of the HTML5 Canvas API. It follows a layered architecture where each module has a clear responsibility and minimal coupling to other modules.
8
+
9
+ The library is designed around three core principles:
10
+
11
+ 1. **Modularity** - Use only what you need
12
+ 2. **Composability** - Combine simple parts to build complex systems
13
+ 3. **Zero Dependencies** - Pure JavaScript, works everywhere
14
+
15
+ ## Module Architecture
16
+
17
+ ```
18
+ ┌─────────────────────────────────────────────────────────────────┐
19
+ │ GCanvas │
20
+ │ (index.js) │
21
+ ├─────────────────────────────────────────────────────────────────┤
22
+ │ │
23
+ │ ┌──────────────────────────────────────────────────────────┐ │
24
+ │ │ Core Modules │ │
25
+ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │ │
26
+ │ │ │ shapes/ │ │ game/ │ │ painter/ │ │ │
27
+ │ │ │ 40+ shapes │ │ Game loop │ │ Canvas API │ │ │
28
+ │ │ │ hierarchy │ │ Pipeline │ │ abstraction │ │ │
29
+ │ │ │ Group │ │ GameObject │ │ │ │ │
30
+ │ │ └─────────────┘ └─────────────┘ └─────────────────┘ │ │
31
+ │ └──────────────────────────────────────────────────────────┘ │
32
+ │ │
33
+ │ ┌──────────────────────────────────────────────────────────┐ │
34
+ │ │ Support Modules │ │
35
+ │ │ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │ │
36
+ │ │ │ motion │ │ io │ │ math │ │ util │ │ mixins │ │ │
37
+ │ │ │ Tween │ │ Events │ │ Random │ │ Layout │ │Draggable│ │ │
38
+ │ │ │ Easing │ │ Mouse │ │ Noise │ │Position│ │ Anchor │ │ │
39
+ │ │ │ Motion │ │ Keys │ │Fractals│ │ZIndex │ │ │ │ │
40
+ │ │ │Tweenetik│ │ Touch │ │Patterns│ │ Tasks │ │ │ │ │
41
+ │ │ └────────┘ └────────┘ └────────┘ └────────┘ └────────┘ │ │
42
+ │ └──────────────────────────────────────────────────────────┘ │
43
+ │ │
44
+ │ ┌──────────────────────────────────────────────────────────┐ │
45
+ │ │ Utility Modules │ │
46
+ │ │ ┌────────┐ │ │
47
+ │ │ │ logger │ │ │
48
+ │ │ │ Logger │ │ │
49
+ │ │ │Loggable│ │ │
50
+ │ │ │DebugTab│ │ │
51
+ │ │ └────────┘ │ │
52
+ │ └──────────────────────────────────────────────────────────┘ │
53
+ │ │
54
+ └─────────────────────────────────────────────────────────────────┘
55
+ ```
56
+
57
+ ## Module Responsibilities
58
+
59
+ ### Core Modules
60
+
61
+ | Module | Responsibility | Key Classes |
62
+ |--------|---------------|-------------|
63
+ | **shapes** | Visual primitives and rendering | `Shape`, `Circle`, `Rectangle`, `Group`, `Transformable` |
64
+ | **game** | Game loop, lifecycle, object management | `Game`, `Pipeline`, `GameObject`, `Scene` |
65
+ | **painter** | Canvas context abstraction | `Painter`, `PainterShapes`, `PainterText` |
66
+
67
+ ### Support Modules
68
+
69
+ | Module | Responsibility | Key Classes |
70
+ |--------|---------------|-------------|
71
+ | **motion** | Animation and tweening | `Motion`, `Tweenetik`, `Easing`, `Tween` |
72
+ | **io** | Input handling | `EventEmitter`, `Mouse`, `Keys`, `Touch`, `Input` |
73
+ | **math** | Mathematical utilities | `Random`, `Noise`, `Complex`, `Fractals`, `Patterns` |
74
+ | **util** | Layout and positioning | `Layout`, `Position`, `ZOrderedCollection` |
75
+ | **mixins** | Composable behaviors | `applyDraggable()`, `applyAnchor()` |
76
+
77
+ ### Utility Modules
78
+
79
+ | Module | Responsibility | Key Classes |
80
+ |--------|---------------|-------------|
81
+ | **logger** | Debug and logging | `Logger`, `Loggable`, `DebugTab` |
82
+
83
+ ## Data Flow
84
+
85
+ ```
86
+ User Input Game Loop
87
+ │ │
88
+ ▼ ▼
89
+ ┌────────┐ events ┌────────┐
90
+ │ IO │ ──────────────────►│ Game │
91
+ └────────┘ └────────┘
92
+
93
+ ┌──────────────┼──────────────┐
94
+ ▼ ▼ ▼
95
+ ┌──────────┐ ┌──────────┐ ┌──────────┐
96
+ │ Pipeline │ │ Tweenetik│ │ Painter │
97
+ │ update() │ │ update() │ │ clear() │
98
+ └──────────┘ └──────────┘ └──────────┘
99
+
100
+
101
+ ┌──────────┐
102
+ │GameObject│
103
+ │ update() │
104
+ │ render() │
105
+ └──────────┘
106
+
107
+
108
+ ┌──────────┐
109
+ │ Shape │
110
+ │ draw() │
111
+ └──────────┘
112
+
113
+
114
+ ┌──────────┐
115
+ │ Painter │
116
+ │ Canvas │
117
+ └──────────┘
118
+ ```
119
+
120
+ ## Design Patterns
121
+
122
+ ### 1. Inheritance Chain (Shapes)
123
+
124
+ Shapes use a linear inheritance hierarchy where each class adds specific functionality:
125
+
126
+ ```
127
+ Euclidian → Geometry2d → Traceable → Renderable → Transformable → Shape
128
+ ```
129
+
130
+ See: [Rendering Pipeline](./rendering-pipeline.md)
131
+
132
+ ### 2. Static Singleton (Painter)
133
+
134
+ `Painter` is a static utility class initialized once with the canvas context:
135
+
136
+ ```js
137
+ Painter.init(ctx);
138
+ Painter.shapes.circle(100, 100, 50);
139
+ ```
140
+
141
+ ### 3. Component Pattern (GameObject + Shape)
142
+
143
+ GameObjects compose shapes rather than inheriting from them:
144
+
145
+ ```js
146
+ class Player extends GameObject {
147
+ constructor(game) {
148
+ super(game);
149
+ this.shape = new Circle(40, { color: 'blue' });
150
+ }
151
+ }
152
+ ```
153
+
154
+ ### 4. Mixin Pattern (Behaviors)
155
+
156
+ Optional behaviors are applied via mixin functions:
157
+
158
+ ```js
159
+ applyDraggable(gameObject, gameObject.shape);
160
+ applyAnchor(gameObject, { anchor: 'top-right' });
161
+ ```
162
+
163
+ ### 5. Observer Pattern (Events)
164
+
165
+ The `EventEmitter` provides pub-sub event handling:
166
+
167
+ ```js
168
+ game.events.on('click', (e) => { ... });
169
+ game.events.emit('custom-event', data);
170
+ ```
171
+
172
+ ## Entry Point
173
+
174
+ The main entry point (`src/index.js`) re-exports all modules:
175
+
176
+ ```js
177
+ export * from "./util";
178
+ export * from "./math";
179
+ export * from "./logger";
180
+ export * from "./painter";
181
+ export * from "./shapes";
182
+ export * from "./io";
183
+ export * from "./game";
184
+ export * from "./motion";
185
+ export * from "./mixins";
186
+ ```
187
+
188
+ This allows importing any component from the main package:
189
+
190
+ ```js
191
+ import { Game, Circle, Painter, Motion } from 'gcanvas';
192
+ ```
193
+
194
+ ## Related
195
+
196
+ - [Two-Layer Architecture](./two-layer-architecture.md) - Shape vs Game layer
197
+ - [Rendering Pipeline](./rendering-pipeline.md) - Shape inheritance chain
198
+ - [Game Lifecycle](./lifecycle.md) - Update/render cycle
199
+
200
+ ## See Also
201
+
202
+ - [Shapes Module](../modules/shapes/README.md)
203
+ - [Game Module](../modules/game/README.md)
204
+ - [Painter Module](../modules/painter/README.md)
@@ -0,0 +1,255 @@
1
+ # Game Lifecycle
2
+
3
+ > Understanding the update/render cycle and frame timing.
4
+
5
+ ## Overview
6
+
7
+ The Game class manages the core game loop using `requestAnimationFrame`. It provides a fixed-timestep update cycle with automatic delta time calculation, ensuring consistent gameplay regardless of frame rate.
8
+
9
+ ## The Game Loop
10
+
11
+ ```
12
+ ┌─────────────────────────────────────────────────────────────────┐
13
+ │ Game Loop │
14
+ │ │
15
+ │ game.start() │
16
+ │ │ │
17
+ │ ▼ │
18
+ │ ┌─────────────────────────────────────────────────────────┐ │
19
+ │ │ requestAnimationFrame │ │
20
+ │ │ │ │ │
21
+ │ │ ▼ │ │
22
+ │ │ ┌─────────────────────────────────────────────────┐ │ │
23
+ │ │ │ loop(timestamp) │ │ │
24
+ │ │ │ │ │ │
25
+ │ │ │ 1. Calculate elapsed time │ │ │
26
+ │ │ │ elapsed = timestamp - lastTime │ │ │
27
+ │ │ │ │ │ │
28
+ │ │ │ 2. Accumulate time │ │ │
29
+ │ │ │ accumulator += elapsed │ │ │
30
+ │ │ │ │ │ │
31
+ │ │ │ 3. While accumulator >= frameInterval: │ │ │
32
+ │ │ │ │ │ │ │
33
+ │ │ │ ├─► update(dt) │ │ │
34
+ │ │ │ │ │ │ │ │
35
+ │ │ │ │ ├─► Pipeline.update(dt) │ │ │
36
+ │ │ │ │ │ └─► GameObject.update(dt) │ │ │
37
+ │ │ │ │ │ │ │ │
38
+ │ │ │ │ └─► Tweenetik.updateAll(dt) │ │ │
39
+ │ │ │ │ │ │ │
40
+ │ │ │ └─► accumulator -= frameInterval │ │ │
41
+ │ │ │ │ │ │
42
+ │ │ │ 4. render() │ │ │
43
+ │ │ │ │ │ │ │
44
+ │ │ │ ├─► Painter.clear() │ │ │
45
+ │ │ │ │ │ │ │
46
+ │ │ │ └─► Pipeline.render() │ │ │
47
+ │ │ │ └─► GameObject.render() │ │ │
48
+ │ │ │ └─► Shape.draw() │ │ │
49
+ │ │ │ │ │ │
50
+ │ │ │ 5. requestAnimationFrame(loop) │ │ │
51
+ │ │ │ │ │ │
52
+ │ │ └─────────────────────────────────────────────────┘ │ │
53
+ │ │ │ │ │
54
+ │ │ └───────────────────────────────┼───┘
55
+ │ └─────────────────────────────────────────────────────────┘ │
56
+ │ │
57
+ └─────────────────────────────────────────────────────────────────┘
58
+ ```
59
+
60
+ ## Fixed Timestep
61
+
62
+ GCanvas uses a **fixed timestep** pattern. This means:
63
+
64
+ - Updates happen at a consistent rate (default: 60 FPS)
65
+ - `dt` (delta time) is always the same value
66
+ - Game logic is frame-rate independent
67
+
68
+ ```js
69
+ // Default: 60 FPS = 16.67ms per frame
70
+ game.setFPS(60);
71
+
72
+ // dt in update() is always 1/60 = 0.01667 seconds
73
+ update(dt) {
74
+ // Move 200 pixels per second, regardless of actual frame rate
75
+ this.x += 200 * dt;
76
+ }
77
+ ```
78
+
79
+ ## Lifecycle Methods
80
+
81
+ ### Game Lifecycle
82
+
83
+ ```js
84
+ class MyGame extends Game {
85
+ constructor(canvas) {
86
+ super(canvas);
87
+ // 1. Constructor: Setup canvas, context, pipeline
88
+ }
89
+
90
+ init() {
91
+ super.init();
92
+ // 2. Init: Create scenes, objects, set up game state
93
+ // Called once before start()
94
+ }
95
+
96
+ update(dt) {
97
+ super.update(dt);
98
+ // 3. Update: Game logic (called every frame)
99
+ // dt = time since last update in seconds
100
+ }
101
+
102
+ render() {
103
+ super.render();
104
+ // 4. Render: Drawing (called every frame after update)
105
+ }
106
+ }
107
+
108
+ const game = new MyGame(canvas);
109
+ game.start(); // Calls init() then starts the loop
110
+ ```
111
+
112
+ ### GameObject Lifecycle
113
+
114
+ ```js
115
+ class Player extends GameObject {
116
+ constructor(game) {
117
+ super(game);
118
+ // 1. Constructor: Create shapes, set initial state
119
+ }
120
+
121
+ update(dt) {
122
+ // 2. Update: Movement, physics, game logic
123
+ // Called every frame while active
124
+ }
125
+
126
+ render() {
127
+ // 3. Render: Draw the object
128
+ // Called every frame while visible
129
+ }
130
+
131
+ destroy() {
132
+ super.destroy();
133
+ // 4. Destroy: Cleanup when removed
134
+ }
135
+ }
136
+ ```
137
+
138
+ ## Delta Time (dt)
139
+
140
+ The `dt` parameter represents time elapsed since the last update, in **seconds**.
141
+
142
+ ```js
143
+ update(dt) {
144
+ // dt ≈ 0.01667 at 60 FPS
145
+ // dt ≈ 0.03333 at 30 FPS
146
+
147
+ // Movement: pixels per second
148
+ this.x += this.speed * dt; // speed = 200 means 200 px/sec
149
+
150
+ // Rotation: radians per second
151
+ this.rotation += Math.PI * dt; // Half rotation per second
152
+
153
+ // Timers
154
+ this.timer += dt;
155
+ if (this.timer >= 2.0) { // 2 seconds
156
+ this.doSomething();
157
+ this.timer = 0;
158
+ }
159
+ }
160
+ ```
161
+
162
+ ## Frame Rate Control
163
+
164
+ ```js
165
+ // Set target FPS
166
+ game.setFPS(60); // Default
167
+ game.setFPS(30); // Lower for mobile/performance
168
+
169
+ // Current frame number
170
+ console.log(game.frame);
171
+
172
+ // Pause on blur (tab switch)
173
+ game.enablePauseOnBlur(true);
174
+ ```
175
+
176
+ ## Pipeline Execution Order
177
+
178
+ The Pipeline manages multiple objects and ensures proper execution order:
179
+
180
+ ```
181
+ Pipeline.update(dt)
182
+ ├─► Filter active objects
183
+ ├─► Sort by zIndex
184
+ ├─► For each object:
185
+ │ └─► object.update(dt)
186
+ └─► Tweenetik.updateAll(dt)
187
+
188
+ Pipeline.render()
189
+ ├─► Filter visible objects
190
+ ├─► Sort by zIndex (low to high)
191
+ └─► For each object:
192
+ └─► object.render()
193
+ ```
194
+
195
+ ## Scenes and Hierarchy
196
+
197
+ Scenes create nested lifecycles:
198
+
199
+ ```js
200
+ // Scene contains GameObjects
201
+ const scene = new Scene(game);
202
+ scene.add(player);
203
+ scene.add(enemy);
204
+ game.pipeline.add(scene);
205
+
206
+ // Lifecycle flows through hierarchy:
207
+ // Pipeline.update()
208
+ // └─► Scene.update()
209
+ // ├─► player.update()
210
+ // └─► enemy.update()
211
+ ```
212
+
213
+ ## State Management
214
+
215
+ ```js
216
+ class MyGame extends Game {
217
+ init() {
218
+ this.state = 'menu'; // menu, playing, paused, gameover
219
+ }
220
+
221
+ update(dt) {
222
+ switch (this.state) {
223
+ case 'menu':
224
+ this.menuScene.update(dt);
225
+ break;
226
+ case 'playing':
227
+ this.gameScene.update(dt);
228
+ break;
229
+ case 'paused':
230
+ // Don't update game objects
231
+ break;
232
+ }
233
+ }
234
+ }
235
+ ```
236
+
237
+ ## Performance Tips
238
+
239
+ 1. **Use `active` flag** - Set `gameObject.active = false` to skip updates
240
+ 2. **Use `visible` flag** - Set `shape.visible = false` to skip rendering
241
+ 3. **Pool objects** - Reuse objects instead of creating/destroying
242
+ 4. **Batch similar operations** - Group shapes in containers
243
+ 5. **Profile with DevTools** - Use browser performance tools
244
+
245
+ ## Related
246
+
247
+ - [Architecture Overview](./architecture-overview.md) - Full system architecture
248
+ - [Two-Layer Architecture](./two-layer-architecture.md) - Shape vs Game layer
249
+ - [Rendering Pipeline](./rendering-pipeline.md) - Shape inheritance chain
250
+
251
+ ## See Also
252
+
253
+ - [Game Module](../modules/game/README.md)
254
+ - [Pipeline](../modules/game/pipeline.md)
255
+ - [GameObject](../modules/game/gameobject.md)