@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.
- package/README.md +39 -36
- package/package.json +20 -33
- package/src/engine/ai/movement/dynamic/align.js +63 -63
- package/src/engine/ai/movement/dynamic/arrive.js +42 -43
- package/src/engine/ai/movement/dynamic/evade.js +38 -38
- package/src/engine/ai/movement/dynamic/face.js +19 -20
- package/src/engine/ai/movement/dynamic/flee.js +45 -45
- package/src/engine/ai/movement/dynamic/look-where-youre-going.js +16 -17
- package/src/engine/ai/movement/dynamic/match-velocity.js +51 -50
- package/src/engine/ai/movement/dynamic/pursue.js +38 -38
- package/src/engine/ai/movement/dynamic/seek.js +44 -44
- package/src/engine/ai/movement/dynamic/wander.js +31 -32
- package/src/engine/ai/movement/kinematic/align.js +37 -37
- package/src/engine/ai/movement/kinematic/arrive.js +42 -42
- package/src/engine/ai/movement/kinematic/face.js +19 -20
- package/src/engine/ai/movement/kinematic/flee.js +26 -26
- package/src/engine/ai/movement/kinematic/seek.js +26 -26
- package/src/engine/ai/movement/kinematic/seek.test.js +42 -42
- package/src/engine/ai/movement/kinematic/wander-as-seek.js +31 -31
- package/src/engine/ai/movement/kinematic/wander.js +27 -27
- package/src/engine/animation/sprite.js +101 -0
- package/src/engine/animation/ticker.js +38 -0
- package/src/engine/behaviors/camera.js +68 -0
- package/src/engine/behaviors/controls/dynamic/modern.js +76 -0
- package/src/engine/behaviors/controls/dynamic/shooter.js +84 -0
- package/src/engine/behaviors/controls/dynamic/tank.js +69 -0
- package/src/engine/behaviors/controls/event-handlers.js +17 -0
- package/src/engine/behaviors/controls/kinematic/modern.js +76 -0
- package/src/engine/behaviors/controls/kinematic/shooter.js +82 -0
- package/src/engine/behaviors/controls/kinematic/tank.js +67 -0
- package/src/engine/behaviors/debug/collision.js +35 -0
- package/src/engine/behaviors/fps.js +29 -0
- package/src/engine/behaviors/fsm.js +33 -0
- package/src/{game/decorators → engine/behaviors}/fsm.test.js +49 -56
- package/src/engine/behaviors/game.js +15 -0
- package/src/engine/behaviors/input/controls.js +37 -0
- package/src/engine/behaviors/input/gamepad.js +114 -0
- package/src/engine/behaviors/input/input.js +48 -0
- package/src/engine/behaviors/input/keyboard.js +64 -0
- package/src/engine/behaviors/input/mouse.js +91 -0
- package/src/engine/behaviors/physics/bouncy.js +25 -0
- package/src/engine/behaviors/physics/clamped.js +36 -0
- package/src/{game/decorators/collisions.js → engine/behaviors/physics/collidable.js} +20 -24
- package/src/engine/behaviors/physics/jumpable.js +145 -0
- package/src/engine/behaviors/ui/button.js +17 -0
- package/src/engine/collision/detection.js +110 -115
- package/src/engine/core/api.js +34 -0
- package/src/engine/core/dev-tools.js +135 -0
- package/src/engine/core/engine.js +119 -0
- package/src/engine/core/loop.js +15 -0
- package/src/engine/{loop → core/loops}/animation-frame.js +25 -26
- package/src/engine/{loop → core/loops}/elapsed.js +22 -23
- package/src/engine/{loop → core/loops}/fixed.js +27 -28
- package/src/engine/{loop → core/loops}/flash.js +13 -14
- package/src/engine/{loop → core/loops}/lag.js +26 -27
- package/src/engine/core/select.js +26 -0
- package/src/engine/core/store.js +178 -0
- package/src/engine/core/store.test.js +110 -0
- package/src/engine/movement/dynamic/modern.js +21 -24
- package/src/engine/movement/dynamic/tank.js +43 -43
- package/src/engine/movement/kinematic/modern.js +16 -16
- package/src/engine/movement/kinematic/modern.test.js +27 -27
- package/src/engine/movement/kinematic/tank.js +27 -27
- package/src/engine/physics/bounds.js +138 -0
- package/src/engine/physics/position.js +43 -0
- package/src/engine/physics/position.test.js +80 -0
- package/src/engine/systems/sprite-animation.js +27 -0
- package/src/main.js +10 -5
- package/src/renderers/canvas/absolute-position.js +18 -0
- package/src/renderers/canvas/camera.js +13 -0
- package/src/renderers/canvas/canvas-renderer.js +68 -0
- package/src/{ui → renderers}/canvas/character.js +38 -35
- package/src/{ui → renderers}/canvas/form/button.js +25 -25
- package/src/{ui → renderers}/canvas/fps.js +18 -18
- package/src/renderers/canvas/image/hitmask.js +51 -0
- package/src/{ui → renderers}/canvas/image/image.js +34 -37
- package/src/{ui → renderers}/canvas/image/sprite.js +49 -49
- package/src/{ui → renderers}/canvas/image/tilemap.js +66 -64
- package/src/{ui → renderers}/canvas/mouse.js +37 -37
- package/src/renderers/canvas/rendering-system.js +79 -0
- package/src/{ui → renderers}/canvas/shapes/circle.js +29 -31
- package/src/{ui → renderers}/canvas/shapes/rectangle.js +27 -31
- package/src/renderers/react/game/character/index.jsx +20 -0
- package/src/{ui → renderers}/react/game/cursor/index.jsx +20 -20
- package/src/{ui → renderers}/react/game/form/fields/field/index.jsx +56 -56
- package/src/{ui → renderers}/react/game/form/fields/index.jsx +12 -12
- package/src/{ui → renderers}/react/game/form/index.jsx +22 -22
- package/src/{ui → renderers}/react/game/fps/index.jsx +16 -16
- package/src/{ui → renderers}/react/game/game.jsx +72 -71
- package/src/{ui → renderers}/react/game/index.jsx +29 -29
- package/src/{ui → renderers}/react/game/platform/index.jsx +30 -30
- package/src/{ui → renderers}/react/game/scene/index.jsx +27 -25
- package/src/{ui → renderers}/react/game/sprite/index.jsx +60 -58
- package/src/{ui → renderers}/react/game/stats/index.jsx +22 -22
- package/src/{ui → renderers}/react/hocs/with-absolute-position/index.jsx +20 -20
- package/src/{ui → renderers}/react/index.jsx +9 -9
- package/src/utils/algorithms/decision-tree.js +24 -24
- package/src/utils/algorithms/decision-tree.test.js +153 -102
- package/src/utils/algorithms/path-finding.js +155 -155
- package/src/utils/algorithms/path-finding.test.js +151 -151
- package/src/utils/data-structures/array.js +83 -83
- package/src/utils/data-structures/array.test.js +173 -173
- package/src/utils/data-structures/board.js +159 -159
- package/src/utils/data-structures/board.test.js +242 -242
- package/src/utils/data-structures/boolean.js +9 -9
- package/src/utils/data-structures/heap.js +164 -164
- package/src/utils/data-structures/heap.test.js +103 -103
- package/src/utils/data-structures/object.js +138 -102
- package/src/utils/data-structures/object.test.js +218 -121
- package/src/utils/data-structures/objects.js +66 -48
- package/src/utils/data-structures/objects.test.js +99 -99
- package/src/utils/data-structures/tree.js +36 -36
- package/src/utils/data-structures/tree.test.js +33 -33
- package/src/utils/functions/functions.js +19 -19
- package/src/utils/functions/functions.test.js +23 -23
- package/src/utils/math/geometry/circle.js +70 -117
- package/src/utils/math/geometry/circle.test.js +97 -97
- package/src/utils/math/geometry/hitmask.js +70 -39
- package/src/utils/math/geometry/hitmask.test.js +155 -84
- package/src/utils/math/geometry/line.js +35 -35
- package/src/utils/math/geometry/line.test.js +49 -49
- package/src/utils/math/geometry/point.js +78 -71
- package/src/utils/math/geometry/point.test.js +81 -81
- package/src/utils/math/geometry/rectangle.js +76 -45
- package/src/utils/math/geometry/rectangle.test.js +42 -42
- package/src/utils/math/geometry/segment.js +80 -80
- package/src/utils/math/geometry/segment.test.js +183 -183
- package/src/utils/math/geometry/triangle.js +15 -15
- package/src/utils/math/geometry/triangle.test.js +11 -11
- package/src/utils/math/linear-algebra/2d.js +28 -28
- package/src/utils/math/linear-algebra/2d.test.js +17 -17
- package/src/utils/math/linear-algebra/quaternion.js +22 -22
- package/src/utils/math/linear-algebra/quaternion.test.js +25 -25
- package/src/utils/math/linear-algebra/quaternions.js +20 -20
- package/src/utils/math/linear-algebra/quaternions.test.js +29 -29
- package/src/utils/math/linear-algebra/vector.js +327 -302
- package/src/utils/math/linear-algebra/vector.test.js +265 -257
- package/src/utils/math/linear-algebra/vectors.js +122 -122
- package/src/utils/math/linear-algebra/vectors.test.js +65 -65
- package/src/utils/math/linear-interpolation.js +9 -0
- package/src/utils/math/numbers.js +90 -90
- package/src/utils/math/numbers.test.js +137 -137
- package/src/utils/math/rng.js +44 -44
- package/src/utils/math/rng.test.js +39 -39
- package/src/utils/math/statistics.js +43 -43
- package/src/utils/math/statistics.test.js +47 -47
- package/src/utils/math/trigonometry.js +89 -89
- package/src/utils/math/trigonometry.test.js +52 -52
- package/src/utils/physics/acceleration.js +61 -63
- package/src/utils/physics/friction.js +28 -30
- package/src/utils/physics/friction.test.js +42 -44
- package/src/utils/physics/gravity.js +69 -71
- package/src/utils/physics/gravity.test.js +77 -80
- package/src/utils/physics/jump.js +31 -41
- package/src/utils/physics/velocity.js +36 -38
- package/src/docs/ai/movement/dynamic/align.js +0 -131
- package/src/docs/ai/movement/dynamic/arrive.js +0 -88
- package/src/docs/ai/movement/dynamic/dynamic.mdx +0 -99
- package/src/docs/ai/movement/dynamic/dynamic.stories.js +0 -58
- package/src/docs/ai/movement/dynamic/evade.js +0 -72
- package/src/docs/ai/movement/dynamic/face.js +0 -90
- package/src/docs/ai/movement/dynamic/flee.js +0 -38
- package/src/docs/ai/movement/dynamic/look-where-youre-going.js +0 -114
- package/src/docs/ai/movement/dynamic/match-velocity.js +0 -92
- package/src/docs/ai/movement/dynamic/pursue.js +0 -72
- package/src/docs/ai/movement/dynamic/seek.js +0 -37
- package/src/docs/ai/movement/dynamic/wander.js +0 -71
- package/src/docs/ai/movement/kinematic/align.js +0 -122
- package/src/docs/ai/movement/kinematic/arrive.js +0 -78
- package/src/docs/ai/movement/kinematic/face.js +0 -82
- package/src/docs/ai/movement/kinematic/flee.js +0 -36
- package/src/docs/ai/movement/kinematic/kinematic.mdx +0 -67
- package/src/docs/ai/movement/kinematic/kinematic.stories.js +0 -42
- package/src/docs/ai/movement/kinematic/seek.js +0 -34
- package/src/docs/ai/movement/kinematic/wander-as-seek.js +0 -62
- package/src/docs/ai/movement/kinematic/wander.js +0 -28
- package/src/docs/bounds.js +0 -7
- package/src/docs/code-reuse.js +0 -35
- package/src/docs/collision/circles.js +0 -58
- package/src/docs/collision/collision.mdx +0 -27
- package/src/docs/collision/collision.stories.js +0 -22
- package/src/docs/collision/platform.js +0 -76
- package/src/docs/collision/tilemap.js +0 -181
- package/src/docs/empty.js +0 -1
- package/src/docs/engine.mdx +0 -81
- package/src/docs/engine.stories.js +0 -37
- package/src/docs/event-handlers.js +0 -68
- package/src/docs/framerate.js +0 -37
- package/src/docs/game.jsx +0 -15
- package/src/docs/image/image.js +0 -19
- package/src/docs/image/image.stories.js +0 -22
- package/src/docs/image/sprite.js +0 -39
- package/src/docs/image/tilemap.js +0 -84
- package/src/docs/input/controls.js +0 -67
- package/src/docs/input/gamepad.js +0 -67
- package/src/docs/input/input.mdx +0 -55
- package/src/docs/input/input.stories.js +0 -27
- package/src/docs/input/keyboard.js +0 -58
- package/src/docs/input/mouse.js +0 -32
- package/src/docs/instances.js +0 -49
- package/src/docs/player/dynamic/double-jump.js +0 -90
- package/src/docs/player/dynamic/dynamic.stories.js +0 -32
- package/src/docs/player/dynamic/jump.js +0 -83
- package/src/docs/player/dynamic/modern-controls.js +0 -57
- package/src/docs/player/dynamic/shooter-controls.js +0 -51
- package/src/docs/player/dynamic/tank-controls.js +0 -44
- package/src/docs/player/kinematic/double-jump.js +0 -90
- package/src/docs/player/kinematic/jump.js +0 -82
- package/src/docs/player/kinematic/kinematic.stories.js +0 -32
- package/src/docs/player/kinematic/modern-controls.js +0 -56
- package/src/docs/player/kinematic/shooter-controls.js +0 -48
- package/src/docs/player/kinematic/tank-controls.js +0 -42
- package/src/docs/quick-start/first-game.js +0 -49
- package/src/docs/quick-start/hello-world.js +0 -1
- package/src/docs/quick-start.mdx +0 -127
- package/src/docs/quick-start.stories.js +0 -17
- package/src/docs/recipes/add-and-remove.js +0 -71
- package/src/docs/recipes/add-instance.js +0 -42
- package/src/docs/recipes/decision-tree.js +0 -169
- package/src/docs/recipes/random-instances.js +0 -25
- package/src/docs/recipes/recipes.mdx +0 -81
- package/src/docs/recipes/recipes.stories.js +0 -37
- package/src/docs/recipes/remove-instance.js +0 -52
- package/src/docs/recipes/states.js +0 -64
- package/src/docs/ui/button.js +0 -28
- package/src/docs/ui/form.stories.js +0 -55
- package/src/docs/ui-chooser.jsx +0 -6
- package/src/docs/utils/data-structures/object.mdx +0 -47
- package/src/docs/utils/data-structures/objects.mdx +0 -30
- package/src/docs/utils/functions/functions.mdx +0 -34
- package/src/docs/utils/math/geometry/circle.mdx +0 -55
- package/src/docs/utils/math/geometry/point.mdx +0 -38
- package/src/docs/utils/math/geometry/rectangle.mdx +0 -24
- package/src/docs/utils/math/geometry/segment.mdx +0 -55
- package/src/docs/utils/math/geometry/triangle.mdx +0 -22
- package/src/docs/utils/math/linear-algebra/2d.mdx +0 -22
- package/src/docs/utils/math/linear-algebra/quaternion.mdx +0 -21
- package/src/docs/utils/math/linear-algebra/quaternions.mdx +0 -22
- package/src/docs/utils/math/linear-algebra/vector.mdx +0 -177
- package/src/docs/utils/math/linear-algebra/vectors.mdx +0 -58
- package/src/docs/utils/math/numbers.mdx +0 -76
- package/src/docs/utils/math/random.mdx +0 -35
- package/src/docs/utils/math/statistics.mdx +0 -38
- package/src/docs/utils/math/trigonometry.mdx +0 -85
- package/src/docs/utils/physics/friction.mdx +0 -20
- package/src/docs/utils/physics/gravity.mdx +0 -28
- package/src/engine/loop.js +0 -15
- package/src/engine/store.js +0 -174
- package/src/engine/store.test.js +0 -256
- package/src/engine.js +0 -74
- package/src/game/animation.js +0 -26
- package/src/game/bounds.js +0 -66
- package/src/game/decorators/character.js +0 -5
- package/src/game/decorators/clamp-to-bounds.js +0 -15
- package/src/game/decorators/controls/dynamic/modern.js +0 -48
- package/src/game/decorators/controls/dynamic/shooter.js +0 -47
- package/src/game/decorators/controls/dynamic/tank.js +0 -55
- package/src/game/decorators/controls/kinematic/modern.js +0 -49
- package/src/game/decorators/controls/kinematic/shooter.js +0 -45
- package/src/game/decorators/controls/kinematic/tank.js +0 -52
- package/src/game/decorators/debug/collisions.js +0 -32
- package/src/game/decorators/double-jump.js +0 -70
- package/src/game/decorators/fps.js +0 -30
- package/src/game/decorators/fsm.js +0 -27
- package/src/game/decorators/game.js +0 -11
- package/src/game/decorators/image/image.js +0 -5
- package/src/game/decorators/image/sprite.js +0 -5
- package/src/game/decorators/image/tilemap.js +0 -5
- package/src/game/decorators/input/controls.js +0 -27
- package/src/game/decorators/input/gamepad.js +0 -74
- package/src/game/decorators/input/input.js +0 -41
- package/src/game/decorators/input/keyboard.js +0 -49
- package/src/game/decorators/input/mouse.js +0 -65
- package/src/game/decorators/jump.js +0 -72
- package/src/game/decorators/platform.js +0 -5
- package/src/game/decorators/ui/button.js +0 -21
- package/src/game/sprite.js +0 -119
- package/src/ui/canvas/absolute-position.js +0 -17
- package/src/ui/canvas/image/hitmask.js +0 -37
- package/src/ui/canvas.js +0 -81
- package/src/ui/react/game/character/index.jsx +0 -30
- package/src/utils/math/geometry/platform.js +0 -42
- package/src/utils/math/geometry/platform.test.js +0 -133
- /package/src/{ui → renderers}/react/game/character/character.module.scss +0 -0
- /package/src/{ui → renderers}/react/game/cursor/cursor.module.scss +0 -0
- /package/src/{ui → renderers}/react/game/form/fields/field/field.module.scss +0 -0
- /package/src/{ui → renderers}/react/game/form/fields/fields.module.scss +0 -0
- /package/src/{ui → renderers}/react/game/form/form.module.scss +0 -0
- /package/src/{ui → renderers}/react/game/platform/platform.module.scss +0 -0
- /package/src/{ui → renderers}/react/game/scene/scene.module.scss +0 -0
- /package/src/{ui → renderers}/react/game/sprite/sprite.module.css +0 -0
- /package/src/{ui → renderers}/react/hocs/with-absolute-position/with-absolute-position.module.scss +0 -0
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { Meta } from '@storybook/blocks'
|
|
2
|
-
|
|
3
|
-
import { random, randomBinomial } from '@inglorious/utils/math/rng'
|
|
4
|
-
|
|
5
|
-
<Meta title="Utils/Math/Rng" />
|
|
6
|
-
|
|
7
|
-
# Rng
|
|
8
|
-
|
|
9
|
-
Random number generators.
|
|
10
|
-
|
|
11
|
-
## Random
|
|
12
|
-
|
|
13
|
-
Generates a random number with optional parameters that specify range and step.
|
|
14
|
-
|
|
15
|
-
No parameters will generate a random number in the range `[0, 1)` (zero included, one excluded).
|
|
16
|
-
|
|
17
|
-
<code>random() == {random()}</code>
|
|
18
|
-
|
|
19
|
-
A parameter `n` means the random number will be an integer in the range `[0, n]` (zero and `n` included).
|
|
20
|
-
|
|
21
|
-
<code>random(6) == {random(6)}</code>
|
|
22
|
-
|
|
23
|
-
Two parameters `n` and `m` means the random number will be an integer in the range `[n, m]` (both numbers included).
|
|
24
|
-
|
|
25
|
-
<code>random(1, 6) == {random(1, 6)}</code>
|
|
26
|
-
|
|
27
|
-
A third parameter allows to specify the step.
|
|
28
|
-
|
|
29
|
-
<code>random(2, 6, 2) == {random(2, 6, 2)}</code>
|
|
30
|
-
|
|
31
|
-
## Random Binomial
|
|
32
|
-
|
|
33
|
-
Generates a random number in the range `(-1, 1)` (minus one excluded, one excluded), with probability following the [Binomial Distribution](https://en.wikipedia.org/wiki/Binomial_distribution).
|
|
34
|
-
|
|
35
|
-
<code>randomBinomial() == {randomBinomial()}</code>
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { Meta } from '@storybook/blocks'
|
|
2
|
-
|
|
3
|
-
import { mean, median, mode } from '@inglorious/utils/math/statistics'
|
|
4
|
-
import { toString } from '@inglorious/utils/data-structures/object'
|
|
5
|
-
|
|
6
|
-
<Meta title="Utils/Math/Statistics" />
|
|
7
|
-
|
|
8
|
-
# Statistics
|
|
9
|
-
|
|
10
|
-
Basic statistics functions.
|
|
11
|
-
|
|
12
|
-
## Average
|
|
13
|
-
|
|
14
|
-
Alias of `mean`.
|
|
15
|
-
|
|
16
|
-
## Mean
|
|
17
|
-
|
|
18
|
-
Returns the mathematical mean of a list of numbers.
|
|
19
|
-
|
|
20
|
-
<code>mean(1, 3, 2) == {mean(1, 3, 2)}</code>
|
|
21
|
-
|
|
22
|
-
## Median
|
|
23
|
-
|
|
24
|
-
Returns the median value from a list of numbers.
|
|
25
|
-
|
|
26
|
-
When the list has odd length, the median is whatever value sits in between:
|
|
27
|
-
|
|
28
|
-
<code>median(1, 3, 2) == {median(1, 3, 2)}</code>
|
|
29
|
-
|
|
30
|
-
When the list has an even length, the median is the average of its two values in between (in this case, 2 and 3):
|
|
31
|
-
|
|
32
|
-
<code>median(1, 3, 2, 4) == {median(1, 3, 2, 4)}</code>
|
|
33
|
-
|
|
34
|
-
## Mode
|
|
35
|
-
|
|
36
|
-
Returns the most frequent item in a list of values.
|
|
37
|
-
|
|
38
|
-
<code>mode("rarely", "sometimes", "sometimes", "always") == {toString(mode("rarely", "sometimes", "sometimes", "always"))}</code>
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import { Meta } from '@storybook/blocks'
|
|
2
|
-
|
|
3
|
-
import { atan2, cos, cosine, pi, sin, sine, toDegrees, toRadians, toRange } from '@inglorious/utils/math/trigonometry'
|
|
4
|
-
|
|
5
|
-
<Meta title="Utils/Math/Trigonometry" />
|
|
6
|
-
|
|
7
|
-
# Trigonometry
|
|
8
|
-
|
|
9
|
-
Basic trigonometry functions.
|
|
10
|
-
|
|
11
|
-
## Atan2
|
|
12
|
-
|
|
13
|
-
Returns the atan2 of y and x.
|
|
14
|
-
|
|
15
|
-
<code>atan2(0, 0) == {atan2(0, 0)}</code>
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
<code>atan2(0, pi() / 2) == {atan2(0, pi() / 2)}</code>
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
<code>atan2(pi() / 2, 0) == {atan2(pi() / 2, 0)}</code>
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
<code>atan2(pi() / 2, pi() / 2) == {atan2(pi() / 2, pi() / 2)}</code>
|
|
25
|
-
|
|
26
|
-
## Cos
|
|
27
|
-
|
|
28
|
-
Returns the cosine of an angle in radians (alias `cosine`).
|
|
29
|
-
|
|
30
|
-
<code>cos(0) == {cos(0)}</code>
|
|
31
|
-
|
|
32
|
-
<code>cos(pi() / 4) == {cos(pi() / 4).toFixed(3)}</code>
|
|
33
|
-
|
|
34
|
-
<code>cos(pi() / 2) == {cos(pi() / 2)}</code> (≈0)
|
|
35
|
-
|
|
36
|
-
## Cosine
|
|
37
|
-
|
|
38
|
-
Alias of `cos`.
|
|
39
|
-
|
|
40
|
-
## Pi
|
|
41
|
-
|
|
42
|
-
Returns an approximation of π.
|
|
43
|
-
|
|
44
|
-
<code>pi() == {pi()}</code> (≈π)
|
|
45
|
-
|
|
46
|
-
## Sin
|
|
47
|
-
|
|
48
|
-
Return the sine of an angle in degrees (alias `sine`).
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
<code>sin(0) == {sin(0)}</code>
|
|
52
|
-
|
|
53
|
-
<code>sin(pi() / 4) == {sin(pi() / 4).toFixed(3)}</code>
|
|
54
|
-
|
|
55
|
-
<code>sin(pi() / 2) == {sin(pi() / 2)}</code>
|
|
56
|
-
|
|
57
|
-
## Sine
|
|
58
|
-
|
|
59
|
-
Alias of `sin`.
|
|
60
|
-
|
|
61
|
-
## To Degrees
|
|
62
|
-
|
|
63
|
-
Converts radians into degrees.
|
|
64
|
-
|
|
65
|
-
<code>toDegrees(pi() / 4) == {toDegrees(pi() / 4)}</code>
|
|
66
|
-
|
|
67
|
-
## To Radians
|
|
68
|
-
|
|
69
|
-
Converts degrees into radians.
|
|
70
|
-
|
|
71
|
-
<code>toRadians(45) == {toRadians(45)}</code> (≈π/4)
|
|
72
|
-
|
|
73
|
-
## To Range
|
|
74
|
-
|
|
75
|
-
Clamps any angle into the range [-π, π].
|
|
76
|
-
|
|
77
|
-
<code>toRange(5 / 4 * pi()) == {toRange((5 / 4) * pi())}</code> (≈-3/4π)
|
|
78
|
-
|
|
79
|
-
<code>toRange(13 / 4 * pi()) == {toRange((13 / 4) * pi())}</code> (≈-3/4π)
|
|
80
|
-
|
|
81
|
-
<code>toRange(-5 / 4 * pi()) == {toRange((-5 / 4) * pi())}</code> (≈3/4π)
|
|
82
|
-
|
|
83
|
-
<code>toRange(-13 / 4 * pi()) == {toRange((-13 / 4) * pi())}</code> (≈3/4π)
|
|
84
|
-
|
|
85
|
-
<code>toRange(3 / 4 * pi()) == {toRange((3 / 4) * pi())}</code> (≈3/4π)
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { Meta } from '@storybook/blocks'
|
|
2
|
-
|
|
3
|
-
import { applyFriction } from '@inglorious/utils/physics/friction'
|
|
4
|
-
import { toString } from '@inglorious/utils/math/linear-algebra/vector'
|
|
5
|
-
|
|
6
|
-
<Meta title="Utils/Physics/Friction" />
|
|
7
|
-
|
|
8
|
-
# Friction
|
|
9
|
-
|
|
10
|
-
Friction is a force that resists movement. It is directly related to the body's momentum, which is mass times velocity, but for our purposes we can safely ignore mass and apply it directly to velocity.
|
|
11
|
-
|
|
12
|
-
A friction that is equal to the velocity's magnitude will eventually stop the body after some time.
|
|
13
|
-
|
|
14
|
-
<code>applyFriction(\{ velocity: [8, 0, 6], friction: 5 \}, \{ dt: 1 \}) == {toString(applyFriction({ velocity: [8, 0, 6], friction: 5 }, { dt: 1 }))}</code>
|
|
15
|
-
|
|
16
|
-
<code>applyFriction(\{ velocity: [8, 0, 6], friction: 5 \}, \{ dt: 2 \}) == {toString(applyFriction({ velocity: [8, 0, 6], friction: 5 }, { dt: 2 }))}</code>
|
|
17
|
-
|
|
18
|
-
When the body is still then no friction will be applied:
|
|
19
|
-
|
|
20
|
-
<code>applyFriction(\{ velocity: [0, 0, 0], friction: 5 \}, \{ dt: 1 \}) == {toString(applyFriction({ velocity: [0, 0, 0], friction: 5 }, { dt: 1 }))}</code>
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { Meta } from '@storybook/blocks'
|
|
2
|
-
|
|
3
|
-
import { applyGravity } from '@inglorious/utils/physics/gravity'
|
|
4
|
-
import { toString } from '@inglorious/utils/data-structures/object'
|
|
5
|
-
|
|
6
|
-
<Meta title="Utils/Physics/Gravity" />
|
|
7
|
-
|
|
8
|
-
# Gravity
|
|
9
|
-
|
|
10
|
-
We can consider gravity as a constant acceleration downards. [This video](https://youtu.be/hG9SzQxaCm8) shows how to calculate this acceleration based on the curve that we want our character to draw when jumping. Also, it rightfully warns to keep jump parameters separate from our world coordinates. That's why we need a specific acceleration and velocity to model our jumps, while directly integrating into the position vector.
|
|
11
|
-
|
|
12
|
-
- `maxJump` is the maximum height that we want to achieve;
|
|
13
|
-
- `maxLeap` is the maximum distance we want to cover with a jump;
|
|
14
|
-
- `maxSpeed` is the maximum horizontal speed when running;
|
|
15
|
-
- `vy` is the current jump velocity;
|
|
16
|
-
- `position[Y]` is the current world height.
|
|
17
|
-
|
|
18
|
-
<code>applyGravity(\{ maxJump: 10, maxLeap: 10, maxSpeed: 10, vy: 10, position: [0,10,0] \}, \{ dt: 1 \}) == {toString(applyGravity({ maxJump: 10, maxLeap: 10, maxSpeed: 10, vy: 10, position: [0,10,0] }, { dt: 1 }))}</code>
|
|
19
|
-
|
|
20
|
-
Not specifying `maxJump` and `maxSpeed` will result in no gravity being applied:
|
|
21
|
-
|
|
22
|
-
<code>applyGravity(\{ maxLeap: 10, maxSpeed: 10, vy: 10, position: [0,10,0] \}, \{ dt: 1 \}) == {toString(applyGravity({ maxLeap: 10, maxSpeed: 10, vy: 10, position: [0,10,0] }, { dt: 1 }))}</code>
|
|
23
|
-
|
|
24
|
-
<code>applyGravity(\{ maxJump: 10, maxSpeed: 10, vy: 10, position: [0,10,0] \}, \{ dt: 1 \}) == {toString(applyGravity({ maxJump: 10, maxLeap: 10, vy: 10, position: [0,10,0] }, { dt: 1 }))}</code>
|
|
25
|
-
|
|
26
|
-
While not specifying `maxLeap` will result in an error, since we have to divide by this quantity:
|
|
27
|
-
|
|
28
|
-
<code>applyGravity(\{ maxJump: 10, maxSpeed: 10, vy: 10, position: [0,10,0] \}, \{ dt: 1 \}) == Error(['maxLeap'])</code>
|
package/src/engine/loop.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import AnimationFrameLoop from "./loop/animation-frame.js"
|
|
2
|
-
import ElapsedLoop from "./loop/elapsed.js"
|
|
3
|
-
import FixedLoop from "./loop/fixed.js"
|
|
4
|
-
import FlashLoop from "./loop/flash.js"
|
|
5
|
-
import LagLoop from "./loop/lag.js"
|
|
6
|
-
|
|
7
|
-
// @see https://gameprogrammingpatterns.com/game-loop.html
|
|
8
|
-
|
|
9
|
-
export default {
|
|
10
|
-
flash: FlashLoop,
|
|
11
|
-
fixed: FixedLoop,
|
|
12
|
-
elapsed: ElapsedLoop,
|
|
13
|
-
lag: LagLoop,
|
|
14
|
-
animationFrame: AnimationFrameLoop,
|
|
15
|
-
}
|
package/src/engine/store.js
DELETED
|
@@ -1,174 +0,0 @@
|
|
|
1
|
-
import { enableGame } from "@inglorious/game/decorators/game.js"
|
|
2
|
-
import { map } from "@inglorious/utils/data-structures/object.js"
|
|
3
|
-
import { extend } from "@inglorious/utils/data-structures/objects.js"
|
|
4
|
-
import { pipe } from "@inglorious/utils/functions/functions.js"
|
|
5
|
-
import { produce } from "immer"
|
|
6
|
-
|
|
7
|
-
const DEFAULT_TYPES = {
|
|
8
|
-
game: [enableGame()],
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const DEFAULT_INSTANCES = {
|
|
12
|
-
// eslint-disable-next-line no-magic-numbers
|
|
13
|
-
game: { type: "game", bounds: [0, 0, 800, 600] }, // Default game instance with bounds.
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const DEFAULT_LAYER = 0
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Creates a store to manage state and events.
|
|
20
|
-
* @param {Object} options - Configuration options for the store.
|
|
21
|
-
* @param {Object} options.instances - Initial instances to include in the store.
|
|
22
|
-
* @param {Object} options.originalConfig - Additional configuration for the store.
|
|
23
|
-
* @returns {Object} The store with methods to interact with state and events.
|
|
24
|
-
*/
|
|
25
|
-
export function createStore({
|
|
26
|
-
types: originalTypes,
|
|
27
|
-
instances: originalInstances,
|
|
28
|
-
}) {
|
|
29
|
-
const listeners = new Set()
|
|
30
|
-
let incomingEvents = []
|
|
31
|
-
|
|
32
|
-
let types = extend(DEFAULT_TYPES, originalTypes)
|
|
33
|
-
types = augmentTypes(types)
|
|
34
|
-
|
|
35
|
-
let instances = extend(DEFAULT_INSTANCES, originalInstances)
|
|
36
|
-
instances = augmentInstances(instances)
|
|
37
|
-
|
|
38
|
-
let state = { events: [], instances }
|
|
39
|
-
|
|
40
|
-
return {
|
|
41
|
-
subscribe,
|
|
42
|
-
update,
|
|
43
|
-
notify,
|
|
44
|
-
dispatch: notify, // needed for react-redux
|
|
45
|
-
getTypes,
|
|
46
|
-
getState,
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Subscribes a listener to state updates.
|
|
51
|
-
* @param {Function} listener - The listener function to call on updates.
|
|
52
|
-
* @returns {Function} A function to unsubscribe the listener.
|
|
53
|
-
*/
|
|
54
|
-
function subscribe(listener) {
|
|
55
|
-
listeners.add(listener)
|
|
56
|
-
|
|
57
|
-
return function unsubscribe() {
|
|
58
|
-
listeners.delete(listener)
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Updates the state based on elapsed time and processes events.
|
|
64
|
-
* @param {number} dt - The delta time since the last update.
|
|
65
|
-
*/
|
|
66
|
-
function update(dt) {
|
|
67
|
-
state = { ...state }
|
|
68
|
-
|
|
69
|
-
state.events.push(...incomingEvents, { id: "game:update" })
|
|
70
|
-
incomingEvents = []
|
|
71
|
-
|
|
72
|
-
while (state.events.length) {
|
|
73
|
-
const event = state.events.shift()
|
|
74
|
-
|
|
75
|
-
if (event.id === "instance:add") {
|
|
76
|
-
add(event.payload.id, event.payload)
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
state.instances = map(state.instances, (_, instance, instances) => {
|
|
80
|
-
const type = types[instance.type]
|
|
81
|
-
const handle = type[event.id]
|
|
82
|
-
return (
|
|
83
|
-
handle?.(instance, event, {
|
|
84
|
-
dt,
|
|
85
|
-
type: originalTypes[instance.type],
|
|
86
|
-
instances,
|
|
87
|
-
notify,
|
|
88
|
-
}) ?? instance
|
|
89
|
-
)
|
|
90
|
-
})
|
|
91
|
-
|
|
92
|
-
if (event.id === "instance:remove") {
|
|
93
|
-
remove(event.payload)
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
listeners.forEach((onUpdate) => onUpdate())
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Adds a new instance to the state.
|
|
102
|
-
* @param {string} id - The ID of the instance to add.
|
|
103
|
-
* @param {Object} instance - The instance object to add.
|
|
104
|
-
*/
|
|
105
|
-
function add(id, instance) {
|
|
106
|
-
state = { ...state }
|
|
107
|
-
state.instances[id] = augmentInstance(id, instance)
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Removes an instance from the state.
|
|
112
|
-
* @param {string} id - The ID of the instance to remove.
|
|
113
|
-
*/
|
|
114
|
-
function remove(id) {
|
|
115
|
-
state = { ...state }
|
|
116
|
-
delete state.instances[id]
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Notifies the store of a new event.
|
|
121
|
-
* @param {Object} event - The event object to notify.
|
|
122
|
-
*/
|
|
123
|
-
function notify(event) {
|
|
124
|
-
incomingEvents.push(event)
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Retrieves the types configuration.
|
|
129
|
-
* @returns {Object} The types configuration.
|
|
130
|
-
*/
|
|
131
|
-
function getTypes() {
|
|
132
|
-
return types
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Retrieves the current state.
|
|
137
|
-
* @returns {Object} The current state.
|
|
138
|
-
*/
|
|
139
|
-
function getState() {
|
|
140
|
-
return state
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
function augmentTypes(types) {
|
|
145
|
-
return pipe(applyDecorators, enableMutability)(types)
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
function applyDecorators(types) {
|
|
149
|
-
return map(types, (_, type) => {
|
|
150
|
-
if (!Array.isArray(type)) {
|
|
151
|
-
return type
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
const decorators = type.map((fn) =>
|
|
155
|
-
typeof fn !== "function" ? (type) => extend(type, fn) : fn,
|
|
156
|
-
)
|
|
157
|
-
return pipe(...decorators)({})
|
|
158
|
-
})
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
function enableMutability(types) {
|
|
162
|
-
return map(types, (_, { draw, ...events }) => ({
|
|
163
|
-
draw,
|
|
164
|
-
...map(events, (_, event) => produce(event)),
|
|
165
|
-
}))
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
function augmentInstances(instances) {
|
|
169
|
-
return map(instances, augmentInstance)
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
function augmentInstance(id, instance) {
|
|
173
|
-
return { ...instance, layer: instance.layer ?? DEFAULT_LAYER, id }
|
|
174
|
-
}
|
package/src/engine/store.test.js
DELETED
|
@@ -1,256 +0,0 @@
|
|
|
1
|
-
import { expect, test } from "vitest"
|
|
2
|
-
|
|
3
|
-
import { createStore } from "./store.js"
|
|
4
|
-
|
|
5
|
-
test("it should add an event to the event queue", () => {
|
|
6
|
-
const event = { id: "something:happened" }
|
|
7
|
-
const config = {
|
|
8
|
-
types: {
|
|
9
|
-
kitty: {
|
|
10
|
-
[event.id](instance) {
|
|
11
|
-
return { ...instance, wasNotified: true }
|
|
12
|
-
},
|
|
13
|
-
},
|
|
14
|
-
},
|
|
15
|
-
instances: {
|
|
16
|
-
instance1: { type: "kitty" },
|
|
17
|
-
},
|
|
18
|
-
}
|
|
19
|
-
const store = createStore(config)
|
|
20
|
-
const afterState = {
|
|
21
|
-
events: [],
|
|
22
|
-
instances: {
|
|
23
|
-
game: {
|
|
24
|
-
id: "game",
|
|
25
|
-
type: "game",
|
|
26
|
-
layer: 0,
|
|
27
|
-
bounds: [0, 0, 800, 600],
|
|
28
|
-
},
|
|
29
|
-
instance1: {
|
|
30
|
-
id: "instance1",
|
|
31
|
-
type: "kitty",
|
|
32
|
-
layer: 0,
|
|
33
|
-
wasNotified: true,
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
store.notify(event)
|
|
39
|
-
store.update()
|
|
40
|
-
|
|
41
|
-
const state = store.getState()
|
|
42
|
-
expect(state).toStrictEqual(afterState)
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
test("it should process the event queue", () => {
|
|
46
|
-
const event = { id: "something:happened" }
|
|
47
|
-
const config = {
|
|
48
|
-
types: {
|
|
49
|
-
kitty: {
|
|
50
|
-
"game:update"(instance) {
|
|
51
|
-
return { ...instance, wasUpdated: true }
|
|
52
|
-
},
|
|
53
|
-
|
|
54
|
-
[event.id](instance) {
|
|
55
|
-
return { ...instance, wasNotified: true }
|
|
56
|
-
},
|
|
57
|
-
},
|
|
58
|
-
},
|
|
59
|
-
instances: {
|
|
60
|
-
instance1: { type: "kitty" },
|
|
61
|
-
},
|
|
62
|
-
}
|
|
63
|
-
const store = createStore(config)
|
|
64
|
-
store.notify(event)
|
|
65
|
-
const afterState = {
|
|
66
|
-
events: [],
|
|
67
|
-
instances: {
|
|
68
|
-
game: {
|
|
69
|
-
id: "game",
|
|
70
|
-
type: "game",
|
|
71
|
-
layer: 0,
|
|
72
|
-
bounds: [0, 0, 800, 600],
|
|
73
|
-
},
|
|
74
|
-
instance1: {
|
|
75
|
-
id: "instance1",
|
|
76
|
-
type: "kitty",
|
|
77
|
-
layer: 0,
|
|
78
|
-
wasNotified: true,
|
|
79
|
-
wasUpdated: true,
|
|
80
|
-
},
|
|
81
|
-
},
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
store.update()
|
|
85
|
-
|
|
86
|
-
const state = store.getState()
|
|
87
|
-
expect(state).toStrictEqual(afterState)
|
|
88
|
-
})
|
|
89
|
-
|
|
90
|
-
test("it should send an event from an instance", () => {
|
|
91
|
-
const event = {
|
|
92
|
-
id: "doge:message",
|
|
93
|
-
payload: { id: "inu", message: "Woof!" },
|
|
94
|
-
}
|
|
95
|
-
const config = {
|
|
96
|
-
types: {
|
|
97
|
-
doge: {
|
|
98
|
-
"game:update"(instance, event, { instances, notify }) {
|
|
99
|
-
if (instances.instance2.position === "near") {
|
|
100
|
-
notify(event)
|
|
101
|
-
}
|
|
102
|
-
},
|
|
103
|
-
},
|
|
104
|
-
kitty: {
|
|
105
|
-
[event.id](instance) {
|
|
106
|
-
if (event.payload.id === "inu" && event.payload.message === "Woof!") {
|
|
107
|
-
instance.position = "far"
|
|
108
|
-
}
|
|
109
|
-
},
|
|
110
|
-
},
|
|
111
|
-
},
|
|
112
|
-
|
|
113
|
-
instances: {
|
|
114
|
-
instance1: {
|
|
115
|
-
type: "doge",
|
|
116
|
-
},
|
|
117
|
-
instance2: {
|
|
118
|
-
type: "kitty",
|
|
119
|
-
position: "near",
|
|
120
|
-
},
|
|
121
|
-
},
|
|
122
|
-
}
|
|
123
|
-
const store = createStore(config)
|
|
124
|
-
const afterState = {
|
|
125
|
-
events: [],
|
|
126
|
-
instances: {
|
|
127
|
-
game: {
|
|
128
|
-
id: "game",
|
|
129
|
-
type: "game",
|
|
130
|
-
layer: 0,
|
|
131
|
-
bounds: [0, 0, 800, 600],
|
|
132
|
-
},
|
|
133
|
-
instance1: {
|
|
134
|
-
id: "instance1",
|
|
135
|
-
type: "doge",
|
|
136
|
-
layer: 0,
|
|
137
|
-
},
|
|
138
|
-
instance2: {
|
|
139
|
-
id: "instance2",
|
|
140
|
-
type: "kitty",
|
|
141
|
-
layer: 0,
|
|
142
|
-
position: "near", // should do nothing at first
|
|
143
|
-
},
|
|
144
|
-
},
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
store.update()
|
|
148
|
-
|
|
149
|
-
const state = store.getState()
|
|
150
|
-
expect(state).toStrictEqual(afterState)
|
|
151
|
-
})
|
|
152
|
-
|
|
153
|
-
test("it should receive an event from an instance", () => {
|
|
154
|
-
const event = {
|
|
155
|
-
id: "doge:message",
|
|
156
|
-
payload: { id: "inu", message: "Woof!" },
|
|
157
|
-
}
|
|
158
|
-
const config = {
|
|
159
|
-
types: {
|
|
160
|
-
doge: {
|
|
161
|
-
"game:update"(instance, event, { instances, notify }) {
|
|
162
|
-
if (instances.instance2.position === "near") {
|
|
163
|
-
notify(event)
|
|
164
|
-
}
|
|
165
|
-
},
|
|
166
|
-
},
|
|
167
|
-
kitty: {
|
|
168
|
-
[event.id](instance, event) {
|
|
169
|
-
if (event.payload.id === "inu" && event.payload.message === "Woof!") {
|
|
170
|
-
instance.position = "far"
|
|
171
|
-
}
|
|
172
|
-
},
|
|
173
|
-
},
|
|
174
|
-
},
|
|
175
|
-
|
|
176
|
-
instances: {
|
|
177
|
-
instance1: {
|
|
178
|
-
type: "doge",
|
|
179
|
-
},
|
|
180
|
-
instance2: {
|
|
181
|
-
type: "kitty",
|
|
182
|
-
position: "near",
|
|
183
|
-
},
|
|
184
|
-
},
|
|
185
|
-
}
|
|
186
|
-
const store = createStore(config)
|
|
187
|
-
store.notify(event)
|
|
188
|
-
const afterState = {
|
|
189
|
-
events: [],
|
|
190
|
-
instances: {
|
|
191
|
-
game: {
|
|
192
|
-
id: "game",
|
|
193
|
-
type: "game",
|
|
194
|
-
layer: 0,
|
|
195
|
-
bounds: [0, 0, 800, 600],
|
|
196
|
-
},
|
|
197
|
-
instance1: {
|
|
198
|
-
id: "instance1",
|
|
199
|
-
type: "doge",
|
|
200
|
-
layer: 0,
|
|
201
|
-
},
|
|
202
|
-
instance2: {
|
|
203
|
-
id: "instance2",
|
|
204
|
-
type: "kitty",
|
|
205
|
-
layer: 0,
|
|
206
|
-
position: "far", // position changed
|
|
207
|
-
},
|
|
208
|
-
},
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
store.update()
|
|
212
|
-
|
|
213
|
-
const state = store.getState()
|
|
214
|
-
expect(state).toStrictEqual(afterState)
|
|
215
|
-
})
|
|
216
|
-
|
|
217
|
-
test("it should mutate state in an immutable way", () => {
|
|
218
|
-
const config = {
|
|
219
|
-
types: {
|
|
220
|
-
kitty: {
|
|
221
|
-
"game:update"(instance) {
|
|
222
|
-
instance.wasUpdated = true
|
|
223
|
-
},
|
|
224
|
-
},
|
|
225
|
-
},
|
|
226
|
-
|
|
227
|
-
instances: {
|
|
228
|
-
instance1: {
|
|
229
|
-
type: "kitty",
|
|
230
|
-
},
|
|
231
|
-
},
|
|
232
|
-
}
|
|
233
|
-
const store = createStore(config)
|
|
234
|
-
const afterState = {
|
|
235
|
-
events: [],
|
|
236
|
-
instances: {
|
|
237
|
-
game: {
|
|
238
|
-
id: "game",
|
|
239
|
-
type: "game",
|
|
240
|
-
layer: 0,
|
|
241
|
-
bounds: [0, 0, 800, 600],
|
|
242
|
-
},
|
|
243
|
-
instance1: {
|
|
244
|
-
id: "instance1",
|
|
245
|
-
type: "kitty",
|
|
246
|
-
layer: 0,
|
|
247
|
-
wasUpdated: true,
|
|
248
|
-
},
|
|
249
|
-
},
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
store.update()
|
|
253
|
-
|
|
254
|
-
const state = store.getState()
|
|
255
|
-
expect(state).toStrictEqual(afterState)
|
|
256
|
-
})
|