@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,71 +1,69 @@
1
- /**
2
- * @typedef {import('@inglorious/utils/math/linear-algebra/types').Vector3} Vector3
3
- */
4
-
5
- /* eslint-disable no-magic-numbers */
6
-
7
- import { zero } from "@inglorious/utils/math/linear-algebra/vector.js"
8
-
9
- const DEFAULT_OPTIONS = { dt: 0 } // Default options for the applyGravity function.
10
- const DEFAULT_JUMP = 0 // Default maximum jump height.
11
- const DEFAULT_LEAP = 0 // Default maximum leap distance.
12
- const DEFAULT_SPEED = 0 // Default maximum speed.
13
- const NO_VELOCITY = 0 // No initial velocity.
14
-
15
- /**
16
- * Applies gravity to an object based on its current velocity and position.
17
- *
18
- * @see https://youtu.be/hG9SzQxaCm8
19
- *
20
- * Projectile equations:
21
- * 1. a(t) = g
22
- * 2. v(t) = g*t + v_0
23
- * 3. y(t) = 1/2*g*t^2 + v_0*t + y_0
24
- *
25
- * Known values:
26
- * 1. y_0 = 0
27
- * 2. v(t_h) = 0 -> 2. 0 = g*t_h + v_0 -> v_0 = -g*t_h
28
- * 3. y_h = h -> 3. h = 1/2*g*t_h^2 (-g*t_h)*t_h = -1/2*g*t_h^2 -> g = -2*h/t_h^2
29
- * 4. v_0 = -g*t_h = (-2*h/t_h^2)*t_h = 2*h/t_h
30
- *
31
- * Transforming time into space:
32
- * 1. t_h = x_h/v_x
33
- * 2. v0 = 2*h/t_h = 2*h*v_x/x_h
34
- * 3. g = -2*h/t_h^2 = -2*h*v_x^2/x_h^2
35
- *
36
- * Euler's Integration:
37
- * 1. v += a * dt
38
- * 2. p += v * dt + 1/2 * a * dt * dt
39
- *
40
- * @param {Object} params - Parameters for gravity calculation.
41
- * @param {number} params.maxJump - Maximum jump height. Defaults to 0.
42
- * @param {number} params.maxLeap - Maximum leap distance. Defaults to 0.
43
- * @param {number} params.maxSpeed - Maximum speed. Defaults to 0.
44
- * @param {number} params.vy - Current vertical velocity. Defaults to 0.
45
- * @param {Vector3} params.position - Current position vector.
46
- * @param {Object} [options=DEFAULT_OPTIONS] - Additional options.
47
- * @param {number} options.dt - Time delta for the calculation.
48
- * @returns {Object} Updated acceleration, velocity, and position.
49
- * @throws {Error} If maxLeap is not provided.
50
- */
51
- export function applyGravity(params, options = DEFAULT_OPTIONS) {
52
- let {
53
- maxJump = DEFAULT_JUMP,
54
- maxLeap = DEFAULT_LEAP,
55
- maxSpeed = DEFAULT_SPEED,
56
- vy = NO_VELOCITY,
57
- position = zero(),
58
- } = params
59
-
60
- if (!maxLeap) {
61
- throw new Error("Missing maxLeap")
62
- }
63
-
64
- const { dt } = options
65
- const ay = (-2 * maxJump * maxSpeed ** 2) / maxLeap ** 2
66
- vy += ay * dt
67
- const [x, y, z] = position
68
- const py = y + vy * dt + 0.5 * ay * dt * dt
69
-
70
- return { ay, vy, position: [x, py, z] }
71
- }
1
+ /**
2
+ * @typedef {import('@inglorious/utils/math/linear-algebra/types').Vector3} Vector3
3
+ */
4
+
5
+ /* eslint-disable no-magic-numbers */
6
+
7
+ import { zero } from "@inglorious/utils/math/linear-algebra/vector.js"
8
+
9
+ const DEFAULT_DT = 1 // Default delta time for the applyGravity function.
10
+ const DEFAULT_JUMP = 0 // Default maximum jump height.
11
+ const DEFAULT_LEAP = 0 // Default maximum leap distance.
12
+ const DEFAULT_SPEED = 0 // Default maximum speed.
13
+ const NO_VELOCITY = 0 // No initial velocity.
14
+
15
+ /**
16
+ * Applies gravity to an object based on its current velocity and position.
17
+ *
18
+ * @see https://youtu.be/hG9SzQxaCm8
19
+ *
20
+ * Projectile equations:
21
+ * 1. a(t) = g
22
+ * 2. v(t) = g*t + v_0
23
+ * 3. y(t) = 1/2*g*t^2 + v_0*t + y_0
24
+ *
25
+ * Known values:
26
+ * 1. y_0 = 0
27
+ * 2. v(t_h) = 0 -> 2. 0 = g*t_h + v_0 -> v_0 = -g*t_h
28
+ * 3. y_h = h -> 3. h = 1/2*g*t_h^2 (-g*t_h)*t_h = -1/2*g*t_h^2 -> g = -2*h/t_h^2
29
+ * 4. v_0 = -g*t_h = (-2*h/t_h^2)*t_h = 2*h/t_h
30
+ *
31
+ * Transforming time into space:
32
+ * 1. t_h = x_h/v_x
33
+ * 2. v0 = 2*h/t_h = 2*h*v_x/x_h
34
+ * 3. g = -2*h/t_h^2 = -2*h*v_x^2/x_h^2
35
+ *
36
+ * Euler's Integration:
37
+ * 1. v += a * dt
38
+ * 2. p += v * dt + 1/2 * a * dt * dt
39
+ *
40
+ * @param {Object} params - Parameters for gravity calculation.
41
+ * @param {number} params.maxJump - Maximum jump height. Defaults to 0.
42
+ * @param {number} params.maxLeap - Maximum leap distance. Defaults to 0.
43
+ * @param {number} params.maxSpeed - Maximum speed. Defaults to 0.
44
+ * @param {number} params.vy - Current vertical velocity. Defaults to 0.
45
+ * @param {Vector3} params.position - Current position vector. Defaults to a zero vector.
46
+ * @param {number} dt - Time delta for the calculation. Defaults to 1.
47
+ * @returns {Object} Updated acceleration, velocity, and position.
48
+ * @throws {Error} If maxLeap is not provided.
49
+ */
50
+ export function applyGravity(params, dt = DEFAULT_DT) {
51
+ let {
52
+ maxJump = DEFAULT_JUMP,
53
+ maxLeap = DEFAULT_LEAP,
54
+ maxSpeed = DEFAULT_SPEED,
55
+ vy = NO_VELOCITY,
56
+ position = zero(),
57
+ } = params
58
+
59
+ if (!maxLeap) {
60
+ throw new Error("Missing maxLeap")
61
+ }
62
+
63
+ const ay = (-2 * maxJump * maxSpeed ** 2) / maxLeap ** 2
64
+ vy += ay * dt
65
+ const [x, y, z] = position
66
+ const py = y + vy * dt + 0.5 * ay * dt * dt
67
+
68
+ return { ay, vy, position: [x, py, z] }
69
+ }
@@ -1,80 +1,77 @@
1
- import { expect, test } from "vitest"
2
-
3
- import { applyGravity } from "./gravity.js"
4
-
5
- test("it should compute no gravity when max jump height is not set", () => {
6
- const params = {
7
- maxLeap: 10,
8
- maxSpeed: 10,
9
- vy: 10,
10
- position: [0, 10, 0],
11
- }
12
- const dt = 1
13
-
14
- expect(applyGravity(params, { dt })).toStrictEqual({
15
- ay: -0,
16
- vy: 10,
17
- position: [0, 20, 0],
18
- })
19
- })
20
-
21
- test("it should throw an error when max leap distance is not set", () => {
22
- const params = {
23
- maxJump: 10,
24
- maxSpeed: 10,
25
- vy: 10,
26
- position: [0, 10, 0],
27
- }
28
- const dt = 1
29
-
30
- expect(() => applyGravity(params, { dt })).toThrow()
31
- })
32
-
33
- test("it should compute no gravity when max movement speed is not set", () => {
34
- const params = {
35
- maxJump: 10,
36
- maxLeap: 10,
37
- vy: 10,
38
- position: [0, 10, 0],
39
- }
40
- const dt = 1
41
-
42
- expect(applyGravity(params, { dt })).toStrictEqual({
43
- ay: -0,
44
- vy: 10,
45
- position: [0, 20, 0],
46
- })
47
- })
48
-
49
- test("it should apply no gravity when no time has passed (gravity is calculated but not applied)", () => {
50
- const params = {
51
- maxJump: 10,
52
- maxLeap: 10,
53
- maxSpeed: 10,
54
- vy: 10,
55
- position: [0, 10, 0],
56
- }
57
-
58
- expect(applyGravity(params)).toStrictEqual({
59
- ay: -20,
60
- vy: 10,
61
- position: [0, 10, 0],
62
- })
63
- })
64
-
65
- test("it should apply gravity based on input parameters", () => {
66
- const params = {
67
- maxJump: 10,
68
- maxLeap: 10,
69
- maxSpeed: 10,
70
- vy: 10,
71
- position: [0, 10, 0],
72
- }
73
- const dt = 1
74
-
75
- expect(applyGravity(params, { dt })).toStrictEqual({
76
- ay: -20,
77
- vy: -10,
78
- position: [0, -10, 0],
79
- })
80
- })
1
+ import { expect, test } from "vitest"
2
+
3
+ import { applyGravity } from "./gravity.js"
4
+
5
+ test("it should apply gravity based on input parameters", () => {
6
+ const params = {
7
+ maxJump: 10,
8
+ maxLeap: 10,
9
+ maxSpeed: 10,
10
+ vy: 10,
11
+ position: [0, 10, 0],
12
+ }
13
+
14
+ expect(applyGravity(params)).toStrictEqual({
15
+ ay: -20,
16
+ vy: -10,
17
+ position: [0, -10, 0],
18
+ })
19
+ })
20
+
21
+ test("it should compute no gravity when max jump height is not set", () => {
22
+ const params = {
23
+ maxLeap: 10,
24
+ maxSpeed: 10,
25
+ vy: 10,
26
+ position: [0, 10, 0],
27
+ }
28
+
29
+ expect(applyGravity(params)).toStrictEqual({
30
+ ay: -0,
31
+ vy: 10,
32
+ position: [0, 20, 0],
33
+ })
34
+ })
35
+
36
+ test("it should compute no gravity when max movement speed is not set", () => {
37
+ const params = {
38
+ maxJump: 10,
39
+ maxLeap: 10,
40
+ vy: 10,
41
+ position: [0, 10, 0],
42
+ }
43
+
44
+ expect(applyGravity(params)).toStrictEqual({
45
+ ay: -0,
46
+ vy: 10,
47
+ position: [0, 20, 0],
48
+ })
49
+ })
50
+
51
+ test("it should apply no gravity when no time has passed", () => {
52
+ const params = {
53
+ maxJump: 10,
54
+ maxLeap: 10,
55
+ maxSpeed: 10,
56
+ vy: 10,
57
+ position: [0, 10, 0],
58
+ }
59
+ const dt = 0
60
+
61
+ expect(applyGravity(params, dt)).toStrictEqual({
62
+ ay: -20,
63
+ vy: 10,
64
+ position: [0, 10, 0],
65
+ })
66
+ })
67
+
68
+ test("it should throw an error when max leap distance is not set", () => {
69
+ const params = {
70
+ maxJump: 10,
71
+ maxSpeed: 10,
72
+ vy: 10,
73
+ position: [0, 10, 0],
74
+ }
75
+
76
+ expect(() => applyGravity(params)).toThrow()
77
+ })
@@ -1,41 +1,31 @@
1
- /**
2
- * @typedef {import('@inglorious/utils/math/linear-algebra/types').Vector3} Vector3
3
- */
4
-
5
- /* eslint-disable no-magic-numbers */
6
-
7
- import { zero } from "@inglorious/utils/math/linear-algebra/vector.js"
8
-
9
- const DEFAULT_OPTIONS = { dt: 0 } // Default options for the jump function.
10
- const DEFAULT_MAX_JUMP = 0 // Default maximum jump height.
11
- const DEFAULT_MAX_LEAP = 0 // Default maximum leap distance.
12
- const DEFAULT_MAX_SPEED = 0 // Default maximum speed.
13
-
14
- /**
15
- * Calculates the vertical velocity (vy) and updates the Y position
16
- * based on the provided parameters and options.
17
- *
18
- * @param {Object} params - Parameters for the jump calculation.
19
- * @param {number} params.maxJump - Maximum jump height. Defaults to 0.
20
- * @param {number} params.maxLeap - Maximum leap distance. Defaults to 0.
21
- * @param {number} params.maxSpeed - Maximum speed. Defaults to 0.
22
- * @param {Vector3} params.position - Current position vector.
23
- * @param {Object} [options=DEFAULT_OPTIONS] - Options for the jump calculation.
24
- * @param {number} options.dt - Delta time for the calculation. Defaults to 0.
25
- * @returns {Object} An object containing the vertical velocity (vy) and updated position.
26
- */
27
- export function jump(params, options = DEFAULT_OPTIONS) {
28
- let {
29
- maxJump = DEFAULT_MAX_JUMP,
30
- maxLeap = DEFAULT_MAX_LEAP,
31
- maxSpeed = DEFAULT_MAX_SPEED,
32
- position = zero(),
33
- } = params
34
- const { dt } = options
35
-
36
- const vy = (2 * maxJump * maxSpeed) / maxLeap
37
- const [x, y, z] = position
38
- const py = y + vy * dt
39
-
40
- return { vy, position: [x, py, z] }
41
- }
1
+ /**
2
+ * @typedef {import('@inglorious/utils/math/linear-algebra/types').Vector3} Vector3
3
+ */
4
+
5
+ /* eslint-disable no-magic-numbers */
6
+
7
+ const DEFAULT_MAX_JUMP = 0 // Default maximum jump height.
8
+ const DEFAULT_MAX_LEAP = 0 // Default maximum leap distance.
9
+ const DEFAULT_MAX_SPEED = 0 // Default maximum speed.
10
+
11
+ /**
12
+ * Calculates the vertical velocity (vy) of a jump
13
+ * based on the provided parameters.
14
+ *
15
+ * @param {Object} params - Parameters for the jump calculation.
16
+ * @param {number} params.maxJump - Maximum jump height. Defaults to 0.
17
+ * @param {number} params.maxLeap - Maximum leap distance. Defaults to 0.
18
+ * @param {number} params.maxSpeed - Maximum speed. Defaults to 0.
19
+ * @returns {number} The computed vertical velocity (vy).
20
+ */
21
+ export function jump(params) {
22
+ let {
23
+ maxJump = DEFAULT_MAX_JUMP,
24
+ maxLeap = DEFAULT_MAX_LEAP,
25
+ maxSpeed = DEFAULT_MAX_SPEED,
26
+ } = params
27
+
28
+ const vy = (2 * maxJump * maxSpeed) / maxLeap
29
+
30
+ return vy
31
+ }
@@ -1,38 +1,36 @@
1
- /**
2
- * @typedef {import('@inglorious/utils/math/linear-algebra/types').Vector3} Vector3
3
- */
4
-
5
- import {
6
- clamp,
7
- multiply,
8
- zero,
9
- } from "@inglorious/utils/math/linear-algebra/vector.js"
10
- import { sum } from "@inglorious/utils/math/linear-algebra/vectors.js"
11
-
12
- const DEFAULT_OPTIONS = { dt: 0 } // Default options for the applyVelocity function.
13
- const DEFAULT_MAX_SPEED = 0 // Default maximum speed for velocity clamping.
14
-
15
- /**
16
- * Applies velocity to a position based on the given parameters and options.
17
- *
18
- * @param {Object} params - The parameters for velocity application.
19
- * @param {number} [params.maxSpeed] - The maximum speed for clamping the velocity. Defaults to 0.
20
- * @param {Vector3} [params.velocity] - The current velocity vector. Defaults to a zero vector.
21
- * @param {Vector3} [params.position] - The current position vector. Defaults to a zero vector.
22
- * @param {Object} [options=DEFAULT_OPTIONS] - Additional options for velocity application.
23
- * @param {number} [options.dt=0] - The time delta for the calculation. Defaults to 0.
24
- * @returns {Object} The updated velocity and position.
25
- */
26
- export function applyVelocity(params, options = DEFAULT_OPTIONS) {
27
- let {
28
- maxSpeed = DEFAULT_MAX_SPEED,
29
- velocity = zero(),
30
- position = zero(),
31
- } = params
32
- const { dt } = options
33
-
34
- velocity = clamp(velocity, -maxSpeed, maxSpeed)
35
-
36
- position = sum(position, multiply(velocity, dt))
37
- return { velocity, position }
38
- }
1
+ /**
2
+ * @typedef {import('@inglorious/utils/math/linear-algebra/types').Vector3} Vector3
3
+ */
4
+
5
+ import {
6
+ clamp,
7
+ multiply,
8
+ zero,
9
+ } from "@inglorious/utils/math/linear-algebra/vector.js"
10
+ import { sum } from "@inglorious/utils/math/linear-algebra/vectors.js"
11
+
12
+ const DEFAULT_DT = 1 // Default time delta for the applyVelocity function.
13
+ const DEFAULT_MAX_SPEED = 0 // Default maximum speed for velocity clamping.
14
+
15
+ /**
16
+ * Applies velocity to a position based on the given parameters and options.
17
+ *
18
+ * @param {Object} params - The parameters for velocity application.
19
+ * @param {number} [params.maxSpeed] - The maximum speed for clamping the velocity. Defaults to 0.
20
+ * @param {Vector3} [params.velocity] - The current velocity vector. Defaults to a zero vector.
21
+ * @param {Vector3} [params.position] - The current position vector. Defaults to a zero vector.
22
+ * @param {number} [dt=0] - The time delta for the calculation. Defaults to 0.
23
+ * @returns {Object} The updated velocity and position.
24
+ */
25
+ export function applyVelocity(params, dt = DEFAULT_DT) {
26
+ let {
27
+ maxSpeed = DEFAULT_MAX_SPEED,
28
+ velocity = zero(),
29
+ position = zero(),
30
+ } = params
31
+
32
+ velocity = clamp(velocity, -maxSpeed, maxSpeed)
33
+
34
+ position = sum(position, multiply(velocity, dt))
35
+ return { velocity, position }
36
+ }
@@ -1,131 +0,0 @@
1
- import align, {
2
- DEFAULT_SLOW_RADIUS,
3
- DEFAULT_TARGET_RADIUS,
4
- DEFAULT_TIME_TO_TARGET,
5
- } from "@inglorious/engine/ai/movement/dynamic/align.js"
6
- import { clampToBounds } from "@inglorious/game/bounds.js"
7
- import { enableCharacter } from "@inglorious/game/decorators/character.js"
8
- import {
9
- createControls,
10
- enableControls,
11
- } from "@inglorious/game/decorators/input/controls.js"
12
- import { enableMouse } from "@inglorious/game/decorators/input/mouse.js"
13
- import { merge } from "@inglorious/utils/data-structures/objects.js"
14
- import { clamp } from "@inglorious/utils/math/numbers.js"
15
- import { pi } from "@inglorious/utils/math/trigonometry.js"
16
-
17
- export default {
18
- types: {
19
- mouse: [
20
- enableMouse(),
21
- {
22
- "field:change"(instance, event) {
23
- const { id, value } = event.payload
24
- if (id === "targetOrientation") {
25
- instance.orientation = -value * pi()
26
- }
27
- },
28
-
29
- "game:update"(instance, event, options) {
30
- const { input0 } = options.instances
31
-
32
- if (input0.left || input0.up) {
33
- instance.orientation += 0.1
34
- } else if (input0.right || input0.down) {
35
- instance.orientation -= 0.1
36
- }
37
- instance.orientation = clamp(instance.orientation, -pi(), pi())
38
- },
39
- },
40
- ],
41
-
42
- ...enableControls(),
43
-
44
- character: [
45
- enableCharacter(),
46
- {
47
- "game:update"(instance, event, { dt, instances }) {
48
- const target = instances.mouse
49
- const { fields } = instances.parameters.groups.align
50
-
51
- merge(
52
- instance,
53
- align(instance, target, {
54
- dt,
55
- targetRadius: fields.targetRadius.value,
56
- slowRadius: fields.slowRadius.value,
57
- timeToTarget: fields.timeToTarget.value,
58
- }),
59
- )
60
-
61
- clampToBounds(instance, instances.game.bounds)
62
- },
63
- },
64
- ],
65
-
66
- form: {
67
- "field:change"(instance, event) {
68
- const { id, value } = event.payload
69
- instance.groups.align.fields[id].value = value
70
- },
71
- },
72
- },
73
-
74
- instances: {
75
- mouse: {
76
- type: "mouse",
77
- position: [400, 0, 300],
78
- orientation: 0,
79
- },
80
-
81
- ...createControls("input0", {
82
- ArrowLeft: "left",
83
- ArrowRight: "right",
84
- ArrowDown: "down",
85
- ArrowUp: "up",
86
- }),
87
-
88
- character: {
89
- type: "character",
90
- maxAngularSpeed: pi() / 4,
91
- maxAngularAcceleration: 10,
92
- position: [400, 0, 300],
93
- },
94
-
95
- parameters: {
96
- type: "form",
97
- position: [800 - 328, 0, 600],
98
- groups: {
99
- align: {
100
- title: "Dynamic Align",
101
- fields: {
102
- targetRadius: {
103
- label: "Target Radius",
104
- inputType: "number",
105
- defaultValue: DEFAULT_TARGET_RADIUS,
106
- },
107
- slowRadius: {
108
- label: "Slow Radius",
109
- inputType: "number",
110
- defaultValue: DEFAULT_SLOW_RADIUS,
111
- },
112
- timeToTarget: {
113
- label: "Time To Target",
114
- inputType: "number",
115
- step: 0.1,
116
- defaultValue: DEFAULT_TIME_TO_TARGET,
117
- },
118
- targetOrientation: {
119
- label: "Target Orientation",
120
- inputType: "number",
121
- step: 0.25,
122
- min: -1,
123
- max: 1,
124
- defaultValue: 0,
125
- },
126
- },
127
- },
128
- },
129
- },
130
- },
131
- }
@@ -1,88 +0,0 @@
1
- import arrive, {
2
- DEFAULT_SLOW_RADIUS,
3
- DEFAULT_TARGET_RADIUS,
4
- DEFAULT_TIME_TO_TARGET,
5
- } from "@inglorious/engine/ai/movement/dynamic/arrive.js"
6
- import { clampToBounds } from "@inglorious/game/bounds.js"
7
- import { enableCharacter } from "@inglorious/game/decorators/character.js"
8
- import { enableMouse } from "@inglorious/game/decorators/input/mouse.js"
9
- import { merge } from "@inglorious/utils/data-structures/objects.js"
10
-
11
- export default {
12
- types: {
13
- mouse: [enableMouse()],
14
-
15
- character: [
16
- enableCharacter(),
17
- {
18
- "game:update"(instance, event, { dt, instances }) {
19
- const target = instances.mouse
20
- const { fields } = instances.parameters.groups.arrive
21
-
22
- merge(
23
- instance,
24
- arrive(instance, target, {
25
- dt,
26
- targetRadius: fields.targetRadius.value,
27
- slowRadius: fields.slowRadius.value,
28
- timeToTarget: fields.timeToTarget.value,
29
- }),
30
- )
31
-
32
- clampToBounds(instance, instances.game.bounds)
33
- },
34
- },
35
- ],
36
-
37
- form: {
38
- "field:change"(instance, event) {
39
- const { id, value } = event.payload
40
- instance.groups.arrive.fields[id].value = value
41
- },
42
- },
43
- },
44
-
45
- instances: {
46
- mouse: {
47
- type: "mouse",
48
- position: [400, 0, 300],
49
- },
50
-
51
- character: {
52
- type: "character",
53
- maxAcceleration: 1000,
54
- maxSpeed: 250,
55
- position: [400, 0, 300],
56
- },
57
-
58
- parameters: {
59
- type: "form",
60
- position: [800 - 328, 0, 600],
61
- groups: {
62
- arrive: {
63
- title: "Dynamic Arrive",
64
- fields: {
65
- targetRadius: {
66
- label: "Target Radius",
67
- inputType: "number",
68
- step: 0.1,
69
- defaultValue: DEFAULT_TARGET_RADIUS,
70
- },
71
- slowRadius: {
72
- label: "Slow Radius",
73
- inputType: "number",
74
- step: 0.1,
75
- defaultValue: DEFAULT_SLOW_RADIUS,
76
- },
77
- timeToTarget: {
78
- label: "Time To Target",
79
- inputType: "number",
80
- step: 0.1,
81
- defaultValue: DEFAULT_TIME_TO_TARGET,
82
- },
83
- },
84
- },
85
- },
86
- },
87
- },
88
- }