@inglorious/engine 0.1.0 → 0.2.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 (292) hide show
  1. package/README.md +39 -36
  2. package/package.json +20 -33
  3. package/src/engine/ai/movement/dynamic/align.js +63 -63
  4. package/src/engine/ai/movement/dynamic/arrive.js +42 -43
  5. package/src/engine/ai/movement/dynamic/evade.js +38 -38
  6. package/src/engine/ai/movement/dynamic/face.js +19 -20
  7. package/src/engine/ai/movement/dynamic/flee.js +45 -45
  8. package/src/engine/ai/movement/dynamic/look-where-youre-going.js +16 -17
  9. package/src/engine/ai/movement/dynamic/match-velocity.js +51 -50
  10. package/src/engine/ai/movement/dynamic/pursue.js +38 -38
  11. package/src/engine/ai/movement/dynamic/seek.js +44 -44
  12. package/src/engine/ai/movement/dynamic/wander.js +31 -32
  13. package/src/engine/ai/movement/kinematic/align.js +37 -37
  14. package/src/engine/ai/movement/kinematic/arrive.js +42 -42
  15. package/src/engine/ai/movement/kinematic/face.js +19 -20
  16. package/src/engine/ai/movement/kinematic/flee.js +26 -26
  17. package/src/engine/ai/movement/kinematic/seek.js +26 -26
  18. package/src/engine/ai/movement/kinematic/seek.test.js +42 -42
  19. package/src/engine/ai/movement/kinematic/wander-as-seek.js +31 -31
  20. package/src/engine/ai/movement/kinematic/wander.js +27 -27
  21. package/src/engine/animation/sprite.js +101 -0
  22. package/src/engine/animation/ticker.js +38 -0
  23. package/src/engine/behaviors/camera.js +68 -0
  24. package/src/engine/behaviors/controls/dynamic/modern.js +76 -0
  25. package/src/engine/behaviors/controls/dynamic/shooter.js +84 -0
  26. package/src/engine/behaviors/controls/dynamic/tank.js +69 -0
  27. package/src/engine/behaviors/controls/event-handlers.js +17 -0
  28. package/src/engine/behaviors/controls/kinematic/modern.js +76 -0
  29. package/src/engine/behaviors/controls/kinematic/shooter.js +82 -0
  30. package/src/engine/behaviors/controls/kinematic/tank.js +67 -0
  31. package/src/engine/behaviors/debug/collision.js +35 -0
  32. package/src/engine/behaviors/fps.js +29 -0
  33. package/src/engine/behaviors/fsm.js +33 -0
  34. package/src/{game/decorators → engine/behaviors}/fsm.test.js +49 -56
  35. package/src/engine/behaviors/game.js +15 -0
  36. package/src/engine/behaviors/input/controls.js +37 -0
  37. package/src/engine/behaviors/input/gamepad.js +114 -0
  38. package/src/engine/behaviors/input/input.js +48 -0
  39. package/src/engine/behaviors/input/keyboard.js +64 -0
  40. package/src/engine/behaviors/input/mouse.js +91 -0
  41. package/src/engine/behaviors/physics/bouncy.js +25 -0
  42. package/src/engine/behaviors/physics/clamped.js +36 -0
  43. package/src/{game/decorators/collisions.js → engine/behaviors/physics/collidable.js} +20 -24
  44. package/src/engine/behaviors/physics/jumpable.js +145 -0
  45. package/src/engine/behaviors/ui/button.js +17 -0
  46. package/src/engine/collision/detection.js +110 -115
  47. package/src/engine/core/api.js +34 -0
  48. package/src/engine/core/dev-tools.js +135 -0
  49. package/src/engine/core/engine.js +119 -0
  50. package/src/engine/core/loop.js +15 -0
  51. package/src/engine/{loop → core/loops}/animation-frame.js +25 -26
  52. package/src/engine/{loop → core/loops}/elapsed.js +22 -23
  53. package/src/engine/{loop → core/loops}/fixed.js +27 -28
  54. package/src/engine/{loop → core/loops}/flash.js +13 -14
  55. package/src/engine/{loop → core/loops}/lag.js +26 -27
  56. package/src/engine/core/select.js +26 -0
  57. package/src/engine/core/store.js +178 -0
  58. package/src/engine/core/store.test.js +110 -0
  59. package/src/engine/movement/dynamic/modern.js +21 -24
  60. package/src/engine/movement/dynamic/tank.js +43 -43
  61. package/src/engine/movement/kinematic/modern.js +16 -16
  62. package/src/engine/movement/kinematic/modern.test.js +27 -27
  63. package/src/engine/movement/kinematic/tank.js +27 -27
  64. package/src/engine/physics/bounds.js +138 -0
  65. package/src/engine/physics/position.js +43 -0
  66. package/src/engine/physics/position.test.js +80 -0
  67. package/src/engine/systems/sprite-animation.js +27 -0
  68. package/src/main.js +10 -5
  69. package/src/renderers/canvas/absolute-position.js +18 -0
  70. package/src/renderers/canvas/camera.js +13 -0
  71. package/src/renderers/canvas/canvas-renderer.js +68 -0
  72. package/src/{ui → renderers}/canvas/character.js +38 -35
  73. package/src/{ui → renderers}/canvas/form/button.js +25 -25
  74. package/src/{ui → renderers}/canvas/fps.js +18 -18
  75. package/src/renderers/canvas/image/hitmask.js +51 -0
  76. package/src/{ui → renderers}/canvas/image/image.js +34 -37
  77. package/src/{ui → renderers}/canvas/image/sprite.js +49 -49
  78. package/src/{ui → renderers}/canvas/image/tilemap.js +66 -64
  79. package/src/{ui → renderers}/canvas/mouse.js +37 -37
  80. package/src/renderers/canvas/rendering-system.js +79 -0
  81. package/src/{ui → renderers}/canvas/shapes/circle.js +29 -31
  82. package/src/{ui → renderers}/canvas/shapes/rectangle.js +27 -31
  83. package/src/renderers/react/game/character/index.jsx +20 -0
  84. package/src/{ui → renderers}/react/game/cursor/index.jsx +20 -20
  85. package/src/{ui → renderers}/react/game/form/fields/field/index.jsx +56 -56
  86. package/src/{ui → renderers}/react/game/form/fields/index.jsx +12 -12
  87. package/src/{ui → renderers}/react/game/form/index.jsx +22 -22
  88. package/src/{ui → renderers}/react/game/fps/index.jsx +16 -16
  89. package/src/{ui → renderers}/react/game/game.jsx +72 -71
  90. package/src/{ui → renderers}/react/game/index.jsx +29 -29
  91. package/src/{ui → renderers}/react/game/platform/index.jsx +30 -30
  92. package/src/{ui → renderers}/react/game/scene/index.jsx +27 -25
  93. package/src/{ui → renderers}/react/game/sprite/index.jsx +60 -58
  94. package/src/{ui → renderers}/react/game/stats/index.jsx +22 -22
  95. package/src/{ui → renderers}/react/hocs/with-absolute-position/index.jsx +20 -20
  96. package/src/{ui → renderers}/react/index.jsx +9 -9
  97. package/src/utils/algorithms/decision-tree.js +24 -24
  98. package/src/utils/algorithms/decision-tree.test.js +153 -102
  99. package/src/utils/algorithms/path-finding.js +155 -155
  100. package/src/utils/algorithms/path-finding.test.js +151 -151
  101. package/src/utils/data-structures/array.js +83 -83
  102. package/src/utils/data-structures/array.test.js +173 -173
  103. package/src/utils/data-structures/board.js +159 -159
  104. package/src/utils/data-structures/board.test.js +242 -242
  105. package/src/utils/data-structures/boolean.js +9 -9
  106. package/src/utils/data-structures/heap.js +164 -164
  107. package/src/utils/data-structures/heap.test.js +103 -103
  108. package/src/utils/data-structures/object.js +138 -102
  109. package/src/utils/data-structures/object.test.js +218 -121
  110. package/src/utils/data-structures/objects.js +66 -48
  111. package/src/utils/data-structures/objects.test.js +99 -99
  112. package/src/utils/data-structures/tree.js +36 -36
  113. package/src/utils/data-structures/tree.test.js +33 -33
  114. package/src/utils/functions/functions.js +19 -19
  115. package/src/utils/functions/functions.test.js +23 -23
  116. package/src/utils/math/geometry/circle.js +70 -117
  117. package/src/utils/math/geometry/circle.test.js +97 -97
  118. package/src/utils/math/geometry/hitmask.js +70 -39
  119. package/src/utils/math/geometry/hitmask.test.js +155 -84
  120. package/src/utils/math/geometry/line.js +35 -35
  121. package/src/utils/math/geometry/line.test.js +49 -49
  122. package/src/utils/math/geometry/point.js +78 -71
  123. package/src/utils/math/geometry/point.test.js +81 -81
  124. package/src/utils/math/geometry/rectangle.js +76 -45
  125. package/src/utils/math/geometry/rectangle.test.js +42 -42
  126. package/src/utils/math/geometry/segment.js +80 -80
  127. package/src/utils/math/geometry/segment.test.js +183 -183
  128. package/src/utils/math/geometry/triangle.js +15 -15
  129. package/src/utils/math/geometry/triangle.test.js +11 -11
  130. package/src/utils/math/linear-algebra/2d.js +28 -28
  131. package/src/utils/math/linear-algebra/2d.test.js +17 -17
  132. package/src/utils/math/linear-algebra/quaternion.js +22 -22
  133. package/src/utils/math/linear-algebra/quaternion.test.js +25 -25
  134. package/src/utils/math/linear-algebra/quaternions.js +20 -20
  135. package/src/utils/math/linear-algebra/quaternions.test.js +29 -29
  136. package/src/utils/math/linear-algebra/vector.js +327 -302
  137. package/src/utils/math/linear-algebra/vector.test.js +265 -257
  138. package/src/utils/math/linear-algebra/vectors.js +122 -122
  139. package/src/utils/math/linear-algebra/vectors.test.js +65 -65
  140. package/src/utils/math/linear-interpolation.js +9 -0
  141. package/src/utils/math/numbers.js +90 -90
  142. package/src/utils/math/numbers.test.js +137 -137
  143. package/src/utils/math/rng.js +44 -44
  144. package/src/utils/math/rng.test.js +39 -39
  145. package/src/utils/math/statistics.js +43 -43
  146. package/src/utils/math/statistics.test.js +47 -47
  147. package/src/utils/math/trigonometry.js +89 -89
  148. package/src/utils/math/trigonometry.test.js +52 -52
  149. package/src/utils/physics/acceleration.js +61 -63
  150. package/src/utils/physics/friction.js +28 -30
  151. package/src/utils/physics/friction.test.js +42 -44
  152. package/src/utils/physics/gravity.js +69 -71
  153. package/src/utils/physics/gravity.test.js +77 -80
  154. package/src/utils/physics/jump.js +31 -41
  155. package/src/utils/physics/velocity.js +36 -38
  156. package/src/docs/ai/movement/dynamic/align.js +0 -131
  157. package/src/docs/ai/movement/dynamic/arrive.js +0 -88
  158. package/src/docs/ai/movement/dynamic/dynamic.mdx +0 -99
  159. package/src/docs/ai/movement/dynamic/dynamic.stories.js +0 -58
  160. package/src/docs/ai/movement/dynamic/evade.js +0 -72
  161. package/src/docs/ai/movement/dynamic/face.js +0 -90
  162. package/src/docs/ai/movement/dynamic/flee.js +0 -38
  163. package/src/docs/ai/movement/dynamic/look-where-youre-going.js +0 -114
  164. package/src/docs/ai/movement/dynamic/match-velocity.js +0 -92
  165. package/src/docs/ai/movement/dynamic/pursue.js +0 -72
  166. package/src/docs/ai/movement/dynamic/seek.js +0 -37
  167. package/src/docs/ai/movement/dynamic/wander.js +0 -71
  168. package/src/docs/ai/movement/kinematic/align.js +0 -122
  169. package/src/docs/ai/movement/kinematic/arrive.js +0 -78
  170. package/src/docs/ai/movement/kinematic/face.js +0 -82
  171. package/src/docs/ai/movement/kinematic/flee.js +0 -36
  172. package/src/docs/ai/movement/kinematic/kinematic.mdx +0 -67
  173. package/src/docs/ai/movement/kinematic/kinematic.stories.js +0 -42
  174. package/src/docs/ai/movement/kinematic/seek.js +0 -34
  175. package/src/docs/ai/movement/kinematic/wander-as-seek.js +0 -62
  176. package/src/docs/ai/movement/kinematic/wander.js +0 -28
  177. package/src/docs/bounds.js +0 -7
  178. package/src/docs/code-reuse.js +0 -35
  179. package/src/docs/collision/circles.js +0 -58
  180. package/src/docs/collision/collision.mdx +0 -27
  181. package/src/docs/collision/collision.stories.js +0 -22
  182. package/src/docs/collision/platform.js +0 -76
  183. package/src/docs/collision/tilemap.js +0 -181
  184. package/src/docs/empty.js +0 -1
  185. package/src/docs/engine.mdx +0 -81
  186. package/src/docs/engine.stories.js +0 -37
  187. package/src/docs/event-handlers.js +0 -68
  188. package/src/docs/framerate.js +0 -37
  189. package/src/docs/game.jsx +0 -15
  190. package/src/docs/image/image.js +0 -19
  191. package/src/docs/image/image.stories.js +0 -22
  192. package/src/docs/image/sprite.js +0 -39
  193. package/src/docs/image/tilemap.js +0 -84
  194. package/src/docs/input/controls.js +0 -67
  195. package/src/docs/input/gamepad.js +0 -67
  196. package/src/docs/input/input.mdx +0 -55
  197. package/src/docs/input/input.stories.js +0 -27
  198. package/src/docs/input/keyboard.js +0 -58
  199. package/src/docs/input/mouse.js +0 -32
  200. package/src/docs/instances.js +0 -49
  201. package/src/docs/player/dynamic/double-jump.js +0 -90
  202. package/src/docs/player/dynamic/dynamic.stories.js +0 -32
  203. package/src/docs/player/dynamic/jump.js +0 -83
  204. package/src/docs/player/dynamic/modern-controls.js +0 -57
  205. package/src/docs/player/dynamic/shooter-controls.js +0 -51
  206. package/src/docs/player/dynamic/tank-controls.js +0 -44
  207. package/src/docs/player/kinematic/double-jump.js +0 -90
  208. package/src/docs/player/kinematic/jump.js +0 -82
  209. package/src/docs/player/kinematic/kinematic.stories.js +0 -32
  210. package/src/docs/player/kinematic/modern-controls.js +0 -56
  211. package/src/docs/player/kinematic/shooter-controls.js +0 -48
  212. package/src/docs/player/kinematic/tank-controls.js +0 -42
  213. package/src/docs/quick-start/first-game.js +0 -49
  214. package/src/docs/quick-start/hello-world.js +0 -1
  215. package/src/docs/quick-start.mdx +0 -127
  216. package/src/docs/quick-start.stories.js +0 -17
  217. package/src/docs/recipes/add-and-remove.js +0 -71
  218. package/src/docs/recipes/add-instance.js +0 -42
  219. package/src/docs/recipes/decision-tree.js +0 -169
  220. package/src/docs/recipes/random-instances.js +0 -25
  221. package/src/docs/recipes/recipes.mdx +0 -81
  222. package/src/docs/recipes/recipes.stories.js +0 -37
  223. package/src/docs/recipes/remove-instance.js +0 -52
  224. package/src/docs/recipes/states.js +0 -64
  225. package/src/docs/ui/button.js +0 -28
  226. package/src/docs/ui/form.stories.js +0 -55
  227. package/src/docs/ui-chooser.jsx +0 -6
  228. package/src/docs/utils/data-structures/object.mdx +0 -47
  229. package/src/docs/utils/data-structures/objects.mdx +0 -30
  230. package/src/docs/utils/functions/functions.mdx +0 -34
  231. package/src/docs/utils/math/geometry/circle.mdx +0 -55
  232. package/src/docs/utils/math/geometry/point.mdx +0 -38
  233. package/src/docs/utils/math/geometry/rectangle.mdx +0 -24
  234. package/src/docs/utils/math/geometry/segment.mdx +0 -55
  235. package/src/docs/utils/math/geometry/triangle.mdx +0 -22
  236. package/src/docs/utils/math/linear-algebra/2d.mdx +0 -22
  237. package/src/docs/utils/math/linear-algebra/quaternion.mdx +0 -21
  238. package/src/docs/utils/math/linear-algebra/quaternions.mdx +0 -22
  239. package/src/docs/utils/math/linear-algebra/vector.mdx +0 -177
  240. package/src/docs/utils/math/linear-algebra/vectors.mdx +0 -58
  241. package/src/docs/utils/math/numbers.mdx +0 -76
  242. package/src/docs/utils/math/random.mdx +0 -35
  243. package/src/docs/utils/math/statistics.mdx +0 -38
  244. package/src/docs/utils/math/trigonometry.mdx +0 -85
  245. package/src/docs/utils/physics/friction.mdx +0 -20
  246. package/src/docs/utils/physics/gravity.mdx +0 -28
  247. package/src/engine/loop.js +0 -15
  248. package/src/engine/store.js +0 -174
  249. package/src/engine/store.test.js +0 -256
  250. package/src/engine.js +0 -74
  251. package/src/game/animation.js +0 -26
  252. package/src/game/bounds.js +0 -66
  253. package/src/game/decorators/character.js +0 -5
  254. package/src/game/decorators/clamp-to-bounds.js +0 -15
  255. package/src/game/decorators/controls/dynamic/modern.js +0 -48
  256. package/src/game/decorators/controls/dynamic/shooter.js +0 -47
  257. package/src/game/decorators/controls/dynamic/tank.js +0 -55
  258. package/src/game/decorators/controls/kinematic/modern.js +0 -49
  259. package/src/game/decorators/controls/kinematic/shooter.js +0 -45
  260. package/src/game/decorators/controls/kinematic/tank.js +0 -52
  261. package/src/game/decorators/debug/collisions.js +0 -32
  262. package/src/game/decorators/double-jump.js +0 -70
  263. package/src/game/decorators/fps.js +0 -30
  264. package/src/game/decorators/fsm.js +0 -27
  265. package/src/game/decorators/game.js +0 -11
  266. package/src/game/decorators/image/image.js +0 -5
  267. package/src/game/decorators/image/sprite.js +0 -5
  268. package/src/game/decorators/image/tilemap.js +0 -5
  269. package/src/game/decorators/input/controls.js +0 -27
  270. package/src/game/decorators/input/gamepad.js +0 -74
  271. package/src/game/decorators/input/input.js +0 -41
  272. package/src/game/decorators/input/keyboard.js +0 -49
  273. package/src/game/decorators/input/mouse.js +0 -65
  274. package/src/game/decorators/jump.js +0 -72
  275. package/src/game/decorators/platform.js +0 -5
  276. package/src/game/decorators/ui/button.js +0 -21
  277. package/src/game/sprite.js +0 -119
  278. package/src/ui/canvas/absolute-position.js +0 -17
  279. package/src/ui/canvas/image/hitmask.js +0 -37
  280. package/src/ui/canvas.js +0 -81
  281. package/src/ui/react/game/character/index.jsx +0 -30
  282. package/src/utils/math/geometry/platform.js +0 -42
  283. package/src/utils/math/geometry/platform.test.js +0 -133
  284. /package/src/{ui → renderers}/react/game/character/character.module.scss +0 -0
  285. /package/src/{ui → renderers}/react/game/cursor/cursor.module.scss +0 -0
  286. /package/src/{ui → renderers}/react/game/form/fields/field/field.module.scss +0 -0
  287. /package/src/{ui → renderers}/react/game/form/fields/fields.module.scss +0 -0
  288. /package/src/{ui → renderers}/react/game/form/form.module.scss +0 -0
  289. /package/src/{ui → renderers}/react/game/platform/platform.module.scss +0 -0
  290. /package/src/{ui → renderers}/react/game/scene/scene.module.scss +0 -0
  291. /package/src/{ui → renderers}/react/game/sprite/sprite.module.css +0 -0
  292. /package/src/{ui → renderers}/react/hocs/with-absolute-position/with-absolute-position.module.scss +0 -0
@@ -1,58 +0,0 @@
1
- import { collidesWith } from "@inglorious/engine/collision/detection.js"
2
- import { bounce } from "@inglorious/game/bounds.js"
3
- import { enableCharacter } from "@inglorious/game/decorators/character.js"
4
- import { merge } from "@inglorious/utils/data-structures/objects.js"
5
- import { mod } from "@inglorious/utils/math/numbers.js"
6
- import { pi } from "@inglorious/utils/math/trigonometry.js"
7
-
8
- export default {
9
- types: {
10
- character: [
11
- enableCharacter(),
12
- {
13
- "game:update"(instance, event, options) {
14
- const characters = Object.values(options.instances).filter(
15
- ({ type }) => type === "character",
16
- )
17
- const target = characters.find(({ id }) => id !== instance.id)
18
-
19
- if (collidesWith(instance, target)) {
20
- instance.orientation += pi()
21
- instance.orientation = mod(instance.orientation, 2 * pi())
22
- }
23
- merge(instance, bounce(instance, options))
24
- },
25
- },
26
- ],
27
- },
28
-
29
- instances: {
30
- left: {
31
- type: "character",
32
- position: [200, 0, 300],
33
- orientation: 0,
34
- maxSpeed: 250,
35
- collisions: {
36
- hitbox: {
37
- shape: "circle",
38
- offset: [-6, 0, -6],
39
- radius: 12,
40
- },
41
- },
42
- },
43
-
44
- right: {
45
- type: "character",
46
- position: [600, 0, 300],
47
- orientation: pi(),
48
- maxSpeed: 250,
49
- collisions: {
50
- hitbox: {
51
- shape: "circle",
52
- offset: [-6, 0, -6],
53
- radius: 12,
54
- },
55
- },
56
- },
57
- },
58
- }
@@ -1,27 +0,0 @@
1
- import { Canvas, Meta, Source } from '@storybook/blocks'
2
- import * as Collision from './collision.stories'
3
-
4
- import circles from './circles?raw'
5
- import platform from './platform?raw'
6
-
7
- <Meta of={Collision} />
8
-
9
- # Collision Detection
10
-
11
- Examples on how to use the built-in collision detection functions.
12
-
13
- ## Circles
14
-
15
- Two shapes with a circular hitbox bounce against each other when colliding.
16
-
17
- <Source dark code={circles} />
18
-
19
- <Canvas of={Collision.Circles} />
20
-
21
- ## Platform
22
-
23
- A character is able to jump on top of a platform and keep its `y` position.
24
-
25
- <Source dark code={platform} />
26
-
27
- <Canvas of={Collision.Platform} />
@@ -1,22 +0,0 @@
1
- import UiChooser from "@inglorious/docs/ui-chooser.jsx"
2
-
3
- import circles from "./circles.js"
4
- import platform from "./platform.js"
5
- import tilemap from "./tilemap.js"
6
-
7
- export default {
8
- title: "Engine/Collision Detection",
9
- component: UiChooser,
10
- }
11
-
12
- export const Circles = {
13
- args: { config: circles },
14
- }
15
-
16
- export const Platform = {
17
- args: { config: platform },
18
- }
19
-
20
- export const Tilemap = {
21
- args: { config: tilemap },
22
- }
@@ -1,76 +0,0 @@
1
- import { enableCharacter } from "@inglorious/game/decorators/character.js"
2
- import { enableClampToBounds } from "@inglorious/game/decorators/clamp-to-bounds.js"
3
- import { enableModernControls } from "@inglorious/game/decorators/controls/kinematic/modern.js"
4
- import {
5
- createControls,
6
- enableControls,
7
- } from "@inglorious/game/decorators/input/controls.js"
8
- import { enableJump } from "@inglorious/game/decorators/jump.js"
9
- import { enablePlatform } from "@inglorious/game/decorators/platform.js"
10
-
11
- export default {
12
- types: {
13
- ...enableControls(),
14
-
15
- platform: [enablePlatform()],
16
-
17
- character: [
18
- enableCharacter(),
19
- enableModernControls(),
20
- enableClampToBounds(),
21
- enableJump(),
22
- ],
23
- },
24
-
25
- instances: {
26
- ...createControls("input0", {
27
- ArrowLeft: "left",
28
- ArrowRight: "right",
29
- Space: "jump",
30
- KeyA: "left",
31
- KeyD: "right",
32
- Btn0: "jump",
33
- Btn14: "left",
34
- Btn15: "right",
35
- Axis0: "leftRight",
36
- }),
37
-
38
- ground: {
39
- type: "platform",
40
- position: [0, 50, 0],
41
- size: [800, 50, 0],
42
- backgroundColor: "green",
43
- collisions: {
44
- platform: {
45
- shape: "platform",
46
- },
47
- },
48
- },
49
-
50
- platform: {
51
- type: "platform",
52
- position: [600, 100, 0],
53
- size: [80, 20, 0],
54
- backgroundColor: "grey",
55
- collisions: {
56
- platform: {
57
- shape: "platform",
58
- },
59
- },
60
- },
61
-
62
- character: {
63
- type: "character",
64
- layer: 1,
65
- position: [200, 62, 0],
66
- collisions: {
67
- platform: {
68
- // shape: "rectangle",
69
- // size: [24, 24, 24],
70
- shape: "circle",
71
- radius: 12,
72
- },
73
- },
74
- },
75
- },
76
- }
@@ -1,181 +0,0 @@
1
- import { findCollisions } from "@inglorious/engine/collision/detection.js"
2
- import { enableCollisionsDebug } from "@inglorious/game/decorators/debug/collisions.js"
3
- import { enableSprite } from "@inglorious/game/decorators/image/sprite.js"
4
- import { enableTilemap } from "@inglorious/game/decorators/image/tilemap.js"
5
- import {
6
- createControls,
7
- enableControls,
8
- } from "@inglorious/game/decorators/input/controls.js"
9
- import { Sprite } from "@inglorious/game/sprite.js"
10
- import { extend } from "@inglorious/utils/data-structures/objects.js"
11
- import { zero } from "@inglorious/utils/math/linear-algebra/vector.js"
12
-
13
- const X = 0
14
- const Z = 2
15
-
16
- export default {
17
- types: {
18
- ...enableControls(),
19
-
20
- tilemap: [enableTilemap(), enableCollisionsDebug()],
21
-
22
- player: [
23
- enableSprite(),
24
- enableCollisionsDebug(),
25
- // enableModernControls(),
26
- (type) =>
27
- extend(type, {
28
- "game:update"(instance, event, options) {
29
- type["game:update"]?.(instance, event, options)
30
-
31
- const { maxSpeed } = instance
32
- const { dungeon } = options.instances
33
-
34
- const spriteState = Sprite.move2(instance)
35
- Sprite.play(spriteState, instance, options)
36
-
37
- const { input0 } = options.instances
38
- instance.velocity = zero()
39
-
40
- if (input0.left) {
41
- instance.velocity[X] = -maxSpeed
42
- }
43
- if (input0.right) {
44
- instance.velocity[X] = maxSpeed
45
- }
46
- if (input0.leftRight != null) {
47
- instance.velocity[X] += input0.leftRight * maxSpeed
48
- }
49
-
50
- const oldX = instance.position[X]
51
- instance.position[X] += instance.velocity[X] * options.dt
52
- if (findCollisions(dungeon, instance)) {
53
- instance.position[X] = oldX
54
- }
55
-
56
- if (input0.down) {
57
- instance.velocity[Z] = -maxSpeed
58
- }
59
- if (input0.up) {
60
- instance.velocity[Z] = maxSpeed
61
- }
62
- if (input0.upDown != null) {
63
- instance.velocity[Z] += -input0.upDown * maxSpeed
64
- }
65
-
66
- const oldZ = instance.position[Z]
67
- instance.position[Z] += instance.velocity[Z] * options.dt
68
- if (findCollisions(dungeon, instance)) {
69
- instance.position[Z] = oldZ
70
- }
71
- },
72
- }),
73
- ],
74
- },
75
-
76
- instances: {
77
- game: {
78
- pixelated: true,
79
- },
80
-
81
- ...createControls("input0", {
82
- ArrowLeft: "left",
83
- ArrowRight: "right",
84
- ArrowDown: "down",
85
- ArrowUp: "up",
86
- }),
87
-
88
- dungeon: {
89
- type: "tilemap",
90
- position: [400 - (16 * 6 * 3) / 2, 0, 300 - (16 * 5 * 3) / 2],
91
- tilemap: {
92
- image: {
93
- id: "dungeon",
94
- src: "/tilemaps/dungeon.png",
95
- imageSize: [160, 160],
96
- tileSize: [16, 16],
97
- columns: 6,
98
- scale: 3,
99
- },
100
- layers: [
101
- {
102
- tiles: [
103
- // first row
104
- 0, 1, 2, 3, 4, 5,
105
- // second row
106
- 10, 11, 12, 13, 14, 15,
107
- // third row
108
- 20, 21, 22, 23, 24, 25,
109
- // fourth row
110
- 30, 31, 32, 33, 34, 35,
111
- // fifth row
112
- 40, 41, 42, 43, 44, 45,
113
- ],
114
- },
115
- {
116
- tiles: [
117
- // first row
118
- -1, -1, -1, -1, -1, -1,
119
- // second row
120
- -1, -1, 83, -1, -1, -1,
121
- // third row
122
- -1, -1, -1, 97, -1, -1,
123
- // fourth row
124
- -1, -1, -1, -1, -1, -1,
125
- // fifth row
126
- -1, -1, 66, 67, -1, -1,
127
- ],
128
- },
129
- ],
130
- },
131
- collisions: {
132
- hitbox: {
133
- shape: "hitmask",
134
- tileSize: [48, 48],
135
- columns: 6,
136
- heights: [
137
- // first row
138
- 2, 2, 2, 2, 2, 2,
139
- // second row
140
- 2, 0, 1, 0, 0, 2,
141
- // third row
142
- 2, 0, 0, 1, 0, 2,
143
- // fourth row
144
- 2, 0, 0, 0, 0, 2,
145
- // fifth row
146
- 2, 2, 2, 2, 2, 2,
147
- ],
148
- },
149
- },
150
- },
151
-
152
- player: {
153
- type: "player",
154
- position: [400 - 16 * 3, 1, 300 - 16],
155
- maxSpeed: 250,
156
- sprite: {
157
- image: {
158
- id: "dungeon_character",
159
- src: "/sprites/dungeon_character.png",
160
- imageSize: [112, 64],
161
- tileSize: [16, 16],
162
- scale: 3,
163
- },
164
- speed: 0.2,
165
- frames: {
166
- right: [17],
167
- left: [0x80000000 + 17],
168
- },
169
- },
170
- collisions: {
171
- hitbox: {
172
- shape: "rectangle",
173
- size: [48, 0, 48],
174
- offset: [-48 / 2, 0, -48 / 2],
175
- // size: [24, 0, 24],
176
- // offset: [-8, 0, -8],
177
- },
178
- },
179
- },
180
- },
181
- }
package/src/docs/empty.js DELETED
@@ -1 +0,0 @@
1
- export default {}
@@ -1,81 +0,0 @@
1
- import { Canvas, Meta, Source } from '@storybook/blocks'
2
- import * as Engine from './engine.stories'
3
-
4
- import bounds from './bounds?raw'
5
- import codeReuse from './code-reuse?raw'
6
- import eventHandlers from './event-handlers?raw'
7
- import framerate from './framerate?raw'
8
-
9
- <Meta of={Engine} />
10
-
11
- # Core Concepts
12
-
13
- This page showcases some of the core concepts and features of the Inglorious Engine. If you are just getting started, we recommend you check out the [Quick Start Guide](/docs/quick-start--docs) first.
14
-
15
- Inglorious Engine is a headless game engine that takes a configuration file in plain JavaScript and creates a scene. The UI can be implemented in any technology: canvas, HTML, ...here we are using React components.
16
-
17
- Here are a few examples of what you can do.
18
-
19
- ## Bounds
20
-
21
- We can customize the game's bounds by passing an array of four numbers: these will hold the upper and lower bounds in pixels.
22
-
23
- The game is an instance in the game, that we can customize as we please.
24
-
25
- <Source dark code={bounds} />
26
-
27
- <Canvas of={Engine.Bounds} />
28
-
29
- ## Event Handlers
30
-
31
- To animate stuff we write event handlers for events that are triggered by our instances or by the game itself. The `game:update` event, for example, is triggered at every cycle of the game loop.
32
-
33
- An event handler accepts the following arguments:
34
-
35
- - The `instance` itself that is handling the event, so we can change its properties to our needs;
36
- - The triggered `event`, which contains a `payload` that holds whatever we need to accomplish our task;
37
- - An `options` object that contains the following:
38
- - The elapsed time `dt`, which can help slow down certain movement algorithms based on the current FPS;
39
- - The game's current `config` object (here you can find the scene's `bounds`, for example);
40
- - All `instances` present in the scene; note that they are read-only, so look but don't touch!
41
-
42
- You might notice the code directly changes properties on the `instance`. While this looks like a direct mutation, the engine uses [Immer](https://immerjs.github.io/immer/) under the hood. This allows you to write simple, mutable-style code while Immer handles the complexity of producing a new, immutable state object for you. It's the best of both worlds: simple code and the safety of immutability.
43
-
44
- The character shown here updates its velocity and position at every frame, going back and forth like it's patroling the scene!
45
-
46
- The `fps` type shows FPS debug info on the top left of the scene; its value is updated based on the `dt` time at every `game:update` event.
47
-
48
- <Source dark code={eventHandlers} />
49
-
50
- <Canvas of={Engine.EventHandlers} />
51
-
52
- ## Code Reuse
53
-
54
- Coding is beautiful, but reusing code without reinventing the wheel is even better! This is where the engine's functional approach really shines.
55
-
56
- Instead of relying on complex class inheritance hierarchies, we use **function composition**. In this example, all the code necessary to draw the character is encapsulated in an `enableCharacter()` decorator.
57
-
58
- This approach is more flexible and powerful than inheritance. You can mix and match behaviors by simply adding decorators to an array, avoiding problems like the "diamond problem" and creating deeply nested, brittle class structures. You are free to combine `canBeControlledByPlayer`, `canBeHurt`, and `canShoot` decorators on the fly.
59
-
60
- The event handler for this character is also using a predefined `bounce()` function. There are many predefined functions out there at your disposal, just look through the documentation to find the ones that suit you best.
61
-
62
- <Source dark code={codeReuse} />
63
-
64
- <Canvas of={Engine.CodeReuse} />
65
-
66
- ## Fixed Framerate
67
-
68
- What if you want to provide a more retro feel to your game? You can use a fixed framerate and make your animations more jerky by changing the default loop.
69
-
70
- <Source dark code={framerate} />
71
-
72
- <Canvas of={Engine.Framerate} />
73
-
74
- ## What's Next?
75
-
76
- You've now seen the core features of the engine. Here's where you can go from here:
77
-
78
- - **Add player controls**: See [Input Handling](/docs/engine-input--docs) for keyboard and mouse.
79
- - **Detect collisions**: Learn about [Collision Detection](/docs/engine-collision-detection--docs).
80
- - **Build autonomous characters**: Explore [AI Kinematic Movement](/docs/ai-movement-kinematic--docs) and [AI Dynamic Movement](/docs/ai-movement-dynamic--docs).
81
- - **See complete examples**: Look at our [Recipes](/docs/engine-recipes--docs) for common game patterns.
@@ -1,37 +0,0 @@
1
- import UiChooser from "@inglorious/docs/ui-chooser.jsx"
2
-
3
- import bounds from "./bounds.js"
4
- import codeReuse from "./code-reuse.js"
5
- import empty from "./empty.js"
6
- import eventHandlers from "./event-handlers.js"
7
- import framerate from "./framerate.js"
8
- import instances from "./instances.js"
9
-
10
- export default {
11
- title: "Engine",
12
- component: UiChooser,
13
- }
14
-
15
- export const Empty = {
16
- args: { config: empty },
17
- }
18
-
19
- export const Bounds = {
20
- args: { config: bounds },
21
- }
22
-
23
- export const Instances = {
24
- args: { config: instances },
25
- }
26
-
27
- export const EventHandlers = {
28
- args: { config: eventHandlers },
29
- }
30
-
31
- export const CodeReuse = {
32
- args: { config: codeReuse },
33
- }
34
-
35
- export const Framerate = {
36
- args: { config: framerate },
37
- }
@@ -1,68 +0,0 @@
1
- const X = 0
2
-
3
- export default {
4
- types: {
5
- character: {
6
- draw(ctx, instance) {
7
- const {
8
- size = 24,
9
- orientation = 0,
10
- stroke = "black",
11
- fill = "transparent",
12
- } = instance
13
-
14
- const radius = size * 0.5
15
-
16
- ctx.save()
17
- ctx.rotate(-orientation)
18
- ctx.translate(radius - 1, 0)
19
-
20
- ctx.fillStyle = "black"
21
-
22
- ctx.beginPath()
23
- ctx.moveTo(0, 6)
24
- ctx.lineTo(0, -6)
25
- ctx.lineTo(6, 0)
26
- ctx.fill()
27
- ctx.closePath()
28
- ctx.restore()
29
-
30
- ctx.save()
31
- ctx.lineWidth = 1
32
- ctx.strokeStyle = stroke
33
- ctx.fillStyle = fill
34
-
35
- ctx.beginPath()
36
- ctx.arc(0, 0, radius, 0, 2 * 3.14)
37
- ctx.fill()
38
- ctx.stroke()
39
- ctx.closePath()
40
- ctx.restore()
41
- },
42
-
43
- "game:update"(instance, event, { dt, instances }) {
44
- const [left, , right] = instances.game.bounds
45
-
46
- if (instance.position[X] > right) {
47
- instance.velocity[X] = -instance.maxSpeed
48
- instance.orientation = 3.14
49
- } else if (instance.position[X] < left) {
50
- instance.velocity[X] = instance.maxSpeed
51
- instance.orientation = 0
52
- }
53
-
54
- instance.position[X] += instance.velocity[X] * dt
55
- },
56
- },
57
- },
58
-
59
- instances: {
60
- character: {
61
- type: "character",
62
- maxSpeed: 250,
63
- position: [400, 0, 300],
64
- velocity: [250, 0, 0],
65
- orientation: 0,
66
- },
67
- },
68
- }
@@ -1,37 +0,0 @@
1
- import { bounce } from "@inglorious/game/bounds.js"
2
- import { enableCharacter } from "@inglorious/game/decorators/character.js"
3
- import { enableFps } from "@inglorious/game/decorators/fps.js"
4
- import { merge } from "@inglorious/utils/data-structures/objects.js"
5
- import { zero } from "@inglorious/utils/math/linear-algebra/vector.js"
6
- import { pi } from "@inglorious/utils/math/trigonometry.js"
7
-
8
- export default {
9
- loop: { type: "fixed", fps: 10 },
10
-
11
- types: {
12
- character: [
13
- enableCharacter(),
14
- {
15
- "game:update"(instance, event, options) {
16
- merge(instance, bounce(instance, options))
17
- },
18
- },
19
- ],
20
-
21
- fps: [enableFps()],
22
- },
23
-
24
- instances: {
25
- character: {
26
- type: "character",
27
- maxSpeed: 250,
28
- orientation: pi() / 6,
29
- position: zero(),
30
- },
31
-
32
- fps: {
33
- type: "fps",
34
- position: [0, 0, 600],
35
- },
36
- },
37
- }
package/src/docs/game.jsx DELETED
@@ -1,15 +0,0 @@
1
- import { start } from "@inglorious/ui/canvas"
2
- import { useRef } from "react"
3
- import { useEffect } from "react"
4
-
5
- export default function Game({ config }) {
6
- const canvas = useRef()
7
-
8
- useEffect(() => {
9
- if (canvas.current) {
10
- start(config, canvas.current)
11
- }
12
- }, [config])
13
-
14
- return <canvas id="canvas" ref={canvas} />
15
- }
@@ -1,19 +0,0 @@
1
- import { enableImage } from "@inglorious/game/decorators/image/image"
2
-
3
- export default {
4
- types: {
5
- image: [enableImage()],
6
- },
7
-
8
- instances: {
9
- logo: {
10
- type: "image",
11
- position: [400 - 128 / 2, 0, 300 + 128 / 2],
12
- image: {
13
- id: "logo",
14
- src: "/logo.png",
15
- imageSize: [128, 128],
16
- },
17
- },
18
- },
19
- }
@@ -1,22 +0,0 @@
1
- import UiChooser from "@inglorious/docs/ui-chooser.jsx"
2
-
3
- import image from "./image.js"
4
- import sprite from "./sprite.js"
5
- import tilemap from "./tilemap.js"
6
-
7
- export default {
8
- title: "Engine/Image",
9
- component: UiChooser,
10
- }
11
-
12
- export const Image = {
13
- args: { config: image },
14
- }
15
-
16
- export const Tilemap = {
17
- args: { config: tilemap },
18
- }
19
-
20
- export const Sprite = {
21
- args: { config: sprite },
22
- }
@@ -1,39 +0,0 @@
1
- import { enableSprite } from "@inglorious/game/decorators/image/sprite.js"
2
- import { Sprite } from "@inglorious/game/sprite.js"
3
-
4
- export default {
5
- types: {
6
- cat: [
7
- enableSprite(),
8
- {
9
- "game:update"(instance, event, options) {
10
- Sprite.play("sleepy", instance, options)
11
- },
12
- },
13
- ],
14
- },
15
-
16
- instances: {
17
- game: {
18
- pixelated: true,
19
- },
20
-
21
- neko: {
22
- type: "cat",
23
- position: [400, 0, 300],
24
- sprite: {
25
- image: {
26
- id: "neko",
27
- src: "/sprites/neko.png",
28
- imageSize: [192, 192],
29
- tileSize: [32, 32],
30
- scale: 2,
31
- },
32
- speed: 0.2,
33
- frames: {
34
- sleepy: [4, 10, 10, 3, 9, 15, 9, 15, 15],
35
- },
36
- },
37
- },
38
- },
39
- }