@inglorious/engine 0.1.1 → 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 +10 -22
- 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/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
package/src/game/sprite.js
DELETED
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
/* eslint-disable no-magic-numbers */
|
|
2
|
-
import { Animation } from "@inglorious/game/animation.js"
|
|
3
|
-
import { mod } from "@inglorious/utils/math/numbers.js"
|
|
4
|
-
import { pi, toRange } from "@inglorious/utils/math/trigonometry.js"
|
|
5
|
-
|
|
6
|
-
const BEFORE = -1
|
|
7
|
-
const AFTER = 1
|
|
8
|
-
|
|
9
|
-
export const Sprite = {
|
|
10
|
-
move2,
|
|
11
|
-
move4,
|
|
12
|
-
move6,
|
|
13
|
-
move8,
|
|
14
|
-
play,
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function move2(instance) {
|
|
18
|
-
const directions = 2
|
|
19
|
-
const multiple = pi() / directions
|
|
20
|
-
const theta = toRange(instance.orientation) / multiple
|
|
21
|
-
|
|
22
|
-
if (theta > 0 + BEFORE && theta < 0 + AFTER) {
|
|
23
|
-
return "right"
|
|
24
|
-
} else if (theta < 0 + BEFORE || theta > 0 + AFTER) {
|
|
25
|
-
return "left"
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
return instance.sprite.state ?? "right"
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function move4(instance) {
|
|
32
|
-
const directions = 4
|
|
33
|
-
const multiple = pi() / directions
|
|
34
|
-
const theta = toRange(instance.orientation) / multiple
|
|
35
|
-
|
|
36
|
-
if (theta >= -2 + BEFORE && theta < -2 + AFTER) {
|
|
37
|
-
return "down"
|
|
38
|
-
} else if (theta >= 0 + BEFORE && theta < 0 + AFTER) {
|
|
39
|
-
return "right"
|
|
40
|
-
} else if (theta >= 2 + BEFORE && theta < 2 + AFTER) {
|
|
41
|
-
return "up"
|
|
42
|
-
} else if (theta < 0 + BEFORE || theta > 0 + AFTER) {
|
|
43
|
-
return "left"
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
return instance.sprite.state ?? "down"
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function move6(instance) {
|
|
50
|
-
const directions = 6
|
|
51
|
-
const multiple = pi() / directions
|
|
52
|
-
const theta = toRange(instance.orientation) / multiple
|
|
53
|
-
|
|
54
|
-
if (theta >= -6 + BEFORE && theta < -6 + AFTER) {
|
|
55
|
-
return "leftDown"
|
|
56
|
-
} else if (theta >= -4 + BEFORE && theta < -4 + AFTER) {
|
|
57
|
-
return "down"
|
|
58
|
-
} else if (theta >= -2 + BEFORE && theta < -2 + AFTER) {
|
|
59
|
-
return "rightDown"
|
|
60
|
-
} else if (theta >= 0 + BEFORE && theta < 0 + AFTER) {
|
|
61
|
-
return "right"
|
|
62
|
-
} else if (theta >= 2 + BEFORE && theta < 2 + AFTER) {
|
|
63
|
-
return "rightUp"
|
|
64
|
-
} else if (theta >= 4 + BEFORE && theta < 4 + AFTER) {
|
|
65
|
-
return "up"
|
|
66
|
-
} else if (theta >= 6 + BEFORE && theta < 6 + AFTER) {
|
|
67
|
-
return "leftUp"
|
|
68
|
-
} else if (theta < 0 + BEFORE || theta > 0 + AFTER) {
|
|
69
|
-
return "left"
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
return instance.sprite.state ?? "down"
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
function move8(instance) {
|
|
76
|
-
const directions = 8
|
|
77
|
-
const multiple = pi() / directions
|
|
78
|
-
const theta = toRange(instance.orientation) / multiple
|
|
79
|
-
|
|
80
|
-
if (theta >= -6 + BEFORE && theta < -6 + AFTER) {
|
|
81
|
-
return "leftDown"
|
|
82
|
-
} else if (theta >= -4 + BEFORE && theta < -4 + AFTER) {
|
|
83
|
-
return "down"
|
|
84
|
-
} else if (theta >= -2 + BEFORE && theta < -2 + AFTER) {
|
|
85
|
-
return "rightDown"
|
|
86
|
-
} else if (theta >= 0 + BEFORE && theta < 0 + AFTER) {
|
|
87
|
-
return "right"
|
|
88
|
-
} else if (theta >= 2 + BEFORE && theta < 2 + AFTER) {
|
|
89
|
-
return "rightUp"
|
|
90
|
-
} else if (theta >= 4 + BEFORE && theta < 4 + AFTER) {
|
|
91
|
-
return "up"
|
|
92
|
-
} else if (theta >= 6 + BEFORE && theta < 6 + AFTER) {
|
|
93
|
-
return "leftUp"
|
|
94
|
-
} else if (theta < 0 + BEFORE || theta > 0 + AFTER) {
|
|
95
|
-
return "left"
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
return instance.sprite.state ?? "down"
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
function play(spriteState, instance, options) {
|
|
102
|
-
Animation.play("sprite", spriteState, instance, { ...options, onTick })
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
function onTick(instance, options) {
|
|
106
|
-
const { notify } = options
|
|
107
|
-
|
|
108
|
-
const { frames, state } = instance.sprite
|
|
109
|
-
|
|
110
|
-
const framesLength = frames[state].length
|
|
111
|
-
|
|
112
|
-
instance.sprite.value = mod(instance.sprite.value + 1, framesLength)
|
|
113
|
-
if (instance.sprite.value === framesLength - 1) {
|
|
114
|
-
notify({
|
|
115
|
-
id: `sprite:animationEnd`,
|
|
116
|
-
payload: { id: instance.id, spriteState: state },
|
|
117
|
-
})
|
|
118
|
-
}
|
|
119
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { snap, zero } from "@inglorious/utils/math/linear-algebra/vector.js"
|
|
2
|
-
|
|
3
|
-
export function absolutePosition(draw) {
|
|
4
|
-
return (ctx, instance, options = {}) => {
|
|
5
|
-
const { position = zero() } = instance
|
|
6
|
-
const { instances } = options
|
|
7
|
-
const [, , , screenHeight] = instances.game.bounds
|
|
8
|
-
const [x, y, z] = snap(position)
|
|
9
|
-
|
|
10
|
-
ctx.save()
|
|
11
|
-
|
|
12
|
-
ctx.translate(x, screenHeight - y - z)
|
|
13
|
-
draw(ctx, instance, options)
|
|
14
|
-
|
|
15
|
-
ctx.restore()
|
|
16
|
-
}
|
|
17
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import drawRectangle from "@inglorious/ui/canvas/shapes/rectangle.js"
|
|
2
|
-
import { max } from "@inglorious/utils/data-structures/array.js"
|
|
3
|
-
|
|
4
|
-
const NO_Y = 0
|
|
5
|
-
const MAX_HUE = 255
|
|
6
|
-
|
|
7
|
-
export default function draw(ctx, instance, options) {
|
|
8
|
-
const { tileSize, columns, heights } = instance
|
|
9
|
-
|
|
10
|
-
const [tileWidth, tileHeight] = tileSize
|
|
11
|
-
const rows = Math.ceil(heights.length / columns)
|
|
12
|
-
const height = rows * tileHeight
|
|
13
|
-
|
|
14
|
-
const minH = 0
|
|
15
|
-
const maxH = max(heights)
|
|
16
|
-
|
|
17
|
-
heights.forEach((h, index) => {
|
|
18
|
-
const x = (index % columns) * tileWidth
|
|
19
|
-
const z = Math.floor(index / columns) * tileHeight - height
|
|
20
|
-
|
|
21
|
-
ctx.save()
|
|
22
|
-
|
|
23
|
-
const normalizedH = (h - minH) / (maxH - minH)
|
|
24
|
-
const hue = MAX_HUE - normalizedH * MAX_HUE
|
|
25
|
-
|
|
26
|
-
const instance = {
|
|
27
|
-
offset: [x, NO_Y, z],
|
|
28
|
-
size: [tileWidth, NO_Y, tileHeight],
|
|
29
|
-
color: "transparent",
|
|
30
|
-
backgroundColor: `hsla(${hue}, 100%, 50%, 0.2)`,
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
drawRectangle(ctx, instance, options)
|
|
34
|
-
|
|
35
|
-
ctx.restore()
|
|
36
|
-
})
|
|
37
|
-
}
|
package/src/ui/canvas.js
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import Engine from "@inglorious/engine.js"
|
|
2
|
-
import { track } from "@inglorious/game/decorators/input/mouse.js"
|
|
3
|
-
|
|
4
|
-
import { absolutePosition } from "./canvas/absolute-position.js"
|
|
5
|
-
|
|
6
|
-
const Y = 1
|
|
7
|
-
const Z = 2
|
|
8
|
-
|
|
9
|
-
export function start(config, canvas) {
|
|
10
|
-
const ctx = canvas.getContext("2d")
|
|
11
|
-
const engine = new Engine(config, { render: render(ctx) })
|
|
12
|
-
|
|
13
|
-
const { game } = engine._store.getState().instances
|
|
14
|
-
const [, , width, height] = game.bounds
|
|
15
|
-
|
|
16
|
-
canvas.style.width = `${width}px`
|
|
17
|
-
canvas.style.height = `${height}px`
|
|
18
|
-
const dpi = window.devicePixelRatio
|
|
19
|
-
canvas.width = Math.floor(width * dpi)
|
|
20
|
-
canvas.height = Math.floor(height * dpi)
|
|
21
|
-
ctx.scale(dpi, dpi)
|
|
22
|
-
|
|
23
|
-
if (game.pixelated) {
|
|
24
|
-
canvas.style.imageRendering = "pixelated"
|
|
25
|
-
ctx.textRendering = "geometricPrecision"
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
document.addEventListener("keypress", (event) => {
|
|
29
|
-
if (event.key === "p") {
|
|
30
|
-
engine.isRunning ? engine.stop() : engine.start()
|
|
31
|
-
}
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
const { onMouseMove, onClick } = track(canvas, {
|
|
35
|
-
notify: engine.notify,
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
canvas.addEventListener("mousemove", onMouseMove)
|
|
39
|
-
canvas.addEventListener("click", onClick)
|
|
40
|
-
|
|
41
|
-
engine.start()
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function render(ctx) {
|
|
45
|
-
return (options) => {
|
|
46
|
-
const { types, instances } = options
|
|
47
|
-
|
|
48
|
-
const { game, mouse, ...rest } = instances
|
|
49
|
-
|
|
50
|
-
const [x, y, width, height] = game.bounds
|
|
51
|
-
ctx.fillStyle = "lightgrey"
|
|
52
|
-
ctx.fillRect(x, y, width, height)
|
|
53
|
-
if (game.pixelated) {
|
|
54
|
-
ctx.imageSmoothingEnabled = false
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
Object.values(rest)
|
|
58
|
-
.filter(({ position }) => position)
|
|
59
|
-
.toSorted(
|
|
60
|
-
(a, b) =>
|
|
61
|
-
a.layer - b.layer ||
|
|
62
|
-
a.position[Y] - b.position[Y] ||
|
|
63
|
-
b.position[Z] - a.position[Z],
|
|
64
|
-
)
|
|
65
|
-
.forEach((instance) =>
|
|
66
|
-
draw(ctx, instance, { ...options, type: types[instance.type] }),
|
|
67
|
-
)
|
|
68
|
-
|
|
69
|
-
if (mouse) {
|
|
70
|
-
draw(ctx, mouse, { ...options, type: types[mouse.type] })
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
function draw(ctx, instance, options) {
|
|
76
|
-
const draw = options.type.draw
|
|
77
|
-
|
|
78
|
-
if (draw) {
|
|
79
|
-
absolutePosition(draw)(ctx, instance, options)
|
|
80
|
-
}
|
|
81
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { useDispatch } from "react-redux"
|
|
2
|
-
|
|
3
|
-
import classes from "./character.module.scss"
|
|
4
|
-
|
|
5
|
-
const DEFAULT_SIZE = 24
|
|
6
|
-
const DEFAULT_ORIENTATION = 0
|
|
7
|
-
|
|
8
|
-
export default function Character({ id, type, instance, className, style }) {
|
|
9
|
-
const notify = useDispatch()
|
|
10
|
-
|
|
11
|
-
const size = type.size ?? DEFAULT_SIZE
|
|
12
|
-
const { orientation = DEFAULT_ORIENTATION } = instance
|
|
13
|
-
|
|
14
|
-
const handleClick = (event) => {
|
|
15
|
-
event.stopPropagation()
|
|
16
|
-
notify({ id: "instance:click", payload: id })
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
return (
|
|
20
|
-
<div
|
|
21
|
-
className={`${classes.character} ${className}`}
|
|
22
|
-
style={{
|
|
23
|
-
...style,
|
|
24
|
-
"--size": `${size}px`,
|
|
25
|
-
"--angle": `${-orientation}rad`,
|
|
26
|
-
}}
|
|
27
|
-
onClick={handleClick}
|
|
28
|
-
/>
|
|
29
|
-
)
|
|
30
|
-
}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Checks if a platform intersects with a circle in 3D space.
|
|
3
|
-
* @param {Platform} platform - The platform to check.
|
|
4
|
-
* @param {Circle} circle - The circle to check.
|
|
5
|
-
* @returns {boolean} True if the platform intersects the circle, false otherwise.
|
|
6
|
-
*/
|
|
7
|
-
export function intersectsCircle(platform, circle) {
|
|
8
|
-
const [left, top, front] = platform.position
|
|
9
|
-
const [extension, elevation, thickness] = platform.size
|
|
10
|
-
|
|
11
|
-
const [x, y, z] = circle.position
|
|
12
|
-
|
|
13
|
-
const lowestPoint = y - circle.radius
|
|
14
|
-
const isAbove = lowestPoint <= top && lowestPoint >= top - elevation
|
|
15
|
-
|
|
16
|
-
const isOverlappingX = x >= left && x <= left + extension
|
|
17
|
-
const isOverlappingZ = z >= front && z <= front + thickness
|
|
18
|
-
|
|
19
|
-
return isAbove && isOverlappingX && isOverlappingZ
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Determines whether platform intersects with a rectangle in 3D space.
|
|
24
|
-
*
|
|
25
|
-
* @param {Platform} platform - The platform defined by its position (top-left-front corner) and size (extension, elevation, thickness).
|
|
26
|
-
* @param {Rectangle} rectangle - The rectangle defined by its position (top-left-front corner) and size (width, height, depth).
|
|
27
|
-
* @returns {boolean} True if the platform intersects the rectangle, false otherwise.
|
|
28
|
-
*/
|
|
29
|
-
export function intersectsRectangle(platform, rectangle) {
|
|
30
|
-
const [left, top, front] = platform.position
|
|
31
|
-
const [extension, elevation, thickness] = platform.size
|
|
32
|
-
|
|
33
|
-
const [x, y, z] = rectangle.position
|
|
34
|
-
const [width, , depth] = rectangle.size
|
|
35
|
-
|
|
36
|
-
const isAbove = y >= top && y <= top + elevation
|
|
37
|
-
|
|
38
|
-
const isOverlappingX = x + width >= left && x <= left + extension
|
|
39
|
-
const isOverlappingZ = z + depth >= front && z <= front + thickness
|
|
40
|
-
|
|
41
|
-
return isAbove && isOverlappingX && isOverlappingZ
|
|
42
|
-
}
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import { expect, test } from "vitest"
|
|
2
|
-
|
|
3
|
-
import { intersectsCircle, intersectsRectangle } from "./platform"
|
|
4
|
-
|
|
5
|
-
test("it should prove that a circle right above a platform intersects with it", () => {
|
|
6
|
-
const platform = {
|
|
7
|
-
position: [-1, 0, 0],
|
|
8
|
-
size: [2, 1, 0],
|
|
9
|
-
}
|
|
10
|
-
const circle = {
|
|
11
|
-
position: [1, 1, 0],
|
|
12
|
-
radius: 1,
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
expect(intersectsCircle(platform, circle)).toBe(true)
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
test("it should prove that a circle way above a platform intersects with it", () => {
|
|
19
|
-
const platform = {
|
|
20
|
-
position: [0, 0, -2],
|
|
21
|
-
size: [2, 1, 0],
|
|
22
|
-
}
|
|
23
|
-
const circle = {
|
|
24
|
-
position: [1, 1, 0],
|
|
25
|
-
radius: 1,
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
expect(intersectsCircle(platform, circle)).toBe(false)
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
test("it should prove that a circle crossing a platform does not intersect with it", () => {
|
|
32
|
-
const platform = {
|
|
33
|
-
position: [-1, -1, 0],
|
|
34
|
-
size: [2, 2, 0],
|
|
35
|
-
}
|
|
36
|
-
const circle = {
|
|
37
|
-
position: [1, 1, 0],
|
|
38
|
-
radius: 1,
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
expect(intersectsCircle(platform, circle)).toBe(false)
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
test("it should prove that a circle below a platform does not intersect with it", () => {
|
|
45
|
-
const platform = {
|
|
46
|
-
position: [0, 2, 0],
|
|
47
|
-
size: [2, 1, 0],
|
|
48
|
-
}
|
|
49
|
-
const circle = {
|
|
50
|
-
position: [1, 1, 0],
|
|
51
|
-
radius: 1,
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
expect(intersectsCircle(platform, circle)).toBe(false)
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
test("it should prove that a circle not crossing a platform horizontally does not intersect with it", () => {
|
|
58
|
-
const platform = {
|
|
59
|
-
position: [-3, -1, 0],
|
|
60
|
-
size: [2, 1, 0],
|
|
61
|
-
}
|
|
62
|
-
const circle = {
|
|
63
|
-
position: [1, 1, 0],
|
|
64
|
-
radius: 1,
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
expect(intersectsCircle(platform, circle)).toBe(false)
|
|
68
|
-
})
|
|
69
|
-
|
|
70
|
-
test("it should prove that a rectangle crossing a platform from above intersects with it", () => {
|
|
71
|
-
const platform = {
|
|
72
|
-
position: [0, -1, 0],
|
|
73
|
-
size: [2, 2, 0],
|
|
74
|
-
}
|
|
75
|
-
const rectangle = {
|
|
76
|
-
position: [0, 0, 0],
|
|
77
|
-
size: [2, 2, 0],
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
expect(intersectsRectangle(platform, rectangle)).toBe(true)
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
test("it should prove that a rectangle right on top of a platform intersects with it", () => {
|
|
84
|
-
const platform = {
|
|
85
|
-
position: [0, -2, 0],
|
|
86
|
-
size: [2, 2, 0],
|
|
87
|
-
}
|
|
88
|
-
const rectangle = {
|
|
89
|
-
position: [0, 0, 0],
|
|
90
|
-
size: [2, 2, 0],
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
expect(intersectsRectangle(platform, rectangle)).toBe(true)
|
|
94
|
-
})
|
|
95
|
-
|
|
96
|
-
test("it should prove that a rectangle crossing a platform from below does not intersect with it", () => {
|
|
97
|
-
const platform = {
|
|
98
|
-
position: [0, 1, 0],
|
|
99
|
-
size: [2, 2, 0],
|
|
100
|
-
}
|
|
101
|
-
const rectangle = {
|
|
102
|
-
position: [0, 0, 0],
|
|
103
|
-
size: [2, 2, 0],
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
expect(intersectsRectangle(platform, rectangle)).toBe(false)
|
|
107
|
-
})
|
|
108
|
-
|
|
109
|
-
test("it should prove that a rectangle below a platform does not intersect with it", () => {
|
|
110
|
-
const platform = {
|
|
111
|
-
position: [0, -3, 0],
|
|
112
|
-
size: [2, 2, 0],
|
|
113
|
-
}
|
|
114
|
-
const rectangle = {
|
|
115
|
-
position: [0, 0, 0],
|
|
116
|
-
size: [2, 2, 0],
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
expect(intersectsRectangle(platform, rectangle)).toBe(false)
|
|
120
|
-
})
|
|
121
|
-
|
|
122
|
-
test("it should prove that a rectangle not crossing a platform horizontally does not intersect with it", () => {
|
|
123
|
-
const platform = {
|
|
124
|
-
position: [-3, 0, 0],
|
|
125
|
-
size: [2, 2, 0],
|
|
126
|
-
}
|
|
127
|
-
const rectangle = {
|
|
128
|
-
position: [0, 0, 0],
|
|
129
|
-
size: [2, 2, 0],
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
expect(intersectsRectangle(platform, rectangle)).toBe(false)
|
|
133
|
-
})
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/src/{ui → renderers}/react/hocs/with-absolute-position/with-absolute-position.module.scss
RENAMED
|
File without changes
|