cubeforge 0.3.14 → 0.3.15
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/dist/index.d.ts +196 -11
- package/dist/index.js +1087 -308
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/components/Game.tsx
|
|
2
|
-
import { useEffect as
|
|
2
|
+
import { useEffect as useEffect4, useRef as useRef4, useState as useState2 } from "react";
|
|
3
3
|
|
|
4
4
|
// ../../packages/core/src/ecs/world.ts
|
|
5
5
|
var ECSWorld = class {
|
|
@@ -734,14 +734,95 @@ var ScriptSystem = class {
|
|
|
734
734
|
// ../../packages/core/src/tween.ts
|
|
735
735
|
var Ease = {
|
|
736
736
|
linear: (t) => t,
|
|
737
|
+
// Quad
|
|
737
738
|
easeInQuad: (t) => t * t,
|
|
738
739
|
easeOutQuad: (t) => t * (2 - t),
|
|
739
740
|
easeInOutQuad: (t) => t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t,
|
|
741
|
+
// Cubic
|
|
742
|
+
easeInCubic: (t) => t * t * t,
|
|
743
|
+
easeOutCubic: (t) => {
|
|
744
|
+
const t1 = t - 1;
|
|
745
|
+
return t1 * t1 * t1 + 1;
|
|
746
|
+
},
|
|
747
|
+
easeInOutCubic: (t) => t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1,
|
|
748
|
+
// Quart
|
|
749
|
+
easeInQuart: (t) => t * t * t * t,
|
|
750
|
+
easeOutQuart: (t) => {
|
|
751
|
+
const t1 = t - 1;
|
|
752
|
+
return 1 - t1 * t1 * t1 * t1;
|
|
753
|
+
},
|
|
754
|
+
easeInOutQuart: (t) => t < 0.5 ? 8 * t * t * t * t : 1 - 8 * (t - 1) * (t - 1) * (t - 1) * (t - 1),
|
|
755
|
+
// Quint
|
|
756
|
+
easeInQuint: (t) => t * t * t * t * t,
|
|
757
|
+
easeOutQuint: (t) => {
|
|
758
|
+
const t1 = t - 1;
|
|
759
|
+
return 1 + t1 * t1 * t1 * t1 * t1;
|
|
760
|
+
},
|
|
761
|
+
easeInOutQuint: (t) => t < 0.5 ? 16 * t * t * t * t * t : 1 + 16 * (t - 1) * (t - 1) * (t - 1) * (t - 1) * (t - 1),
|
|
762
|
+
// Sine
|
|
763
|
+
easeInSine: (t) => 1 - Math.cos(t * Math.PI / 2),
|
|
764
|
+
easeOutSine: (t) => Math.sin(t * Math.PI / 2),
|
|
765
|
+
easeInOutSine: (t) => -(Math.cos(Math.PI * t) - 1) / 2,
|
|
766
|
+
// Expo
|
|
767
|
+
easeInExpo: (t) => t === 0 ? 0 : Math.pow(2, 10 * (t - 1)),
|
|
768
|
+
easeOutExpo: (t) => t === 1 ? 1 : 1 - Math.pow(2, -10 * t),
|
|
769
|
+
easeInOutExpo: (t) => {
|
|
770
|
+
if (t === 0) return 0;
|
|
771
|
+
if (t === 1) return 1;
|
|
772
|
+
return t < 0.5 ? Math.pow(2, 20 * t - 10) / 2 : (2 - Math.pow(2, -20 * t + 10)) / 2;
|
|
773
|
+
},
|
|
774
|
+
// Circ
|
|
775
|
+
easeInCirc: (t) => 1 - Math.sqrt(1 - t * t),
|
|
776
|
+
easeOutCirc: (t) => Math.sqrt(1 - (t - 1) * (t - 1)),
|
|
777
|
+
easeInOutCirc: (t) => t < 0.5 ? (1 - Math.sqrt(1 - 4 * t * t)) / 2 : (Math.sqrt(1 - (-2 * t + 2) * (-2 * t + 2)) + 1) / 2,
|
|
778
|
+
// Back
|
|
779
|
+
easeInBack: (t) => {
|
|
780
|
+
const c1 = 1.70158;
|
|
781
|
+
const c3 = c1 + 1;
|
|
782
|
+
return c3 * t * t * t - c1 * t * t;
|
|
783
|
+
},
|
|
740
784
|
easeOutBack: (t) => {
|
|
741
785
|
const c1 = 1.70158;
|
|
742
786
|
const c3 = c1 + 1;
|
|
743
787
|
return 1 + c3 * Math.pow(t - 1, 3) + c1 * Math.pow(t - 1, 2);
|
|
744
|
-
}
|
|
788
|
+
},
|
|
789
|
+
easeInOutBack: (t) => {
|
|
790
|
+
const c1 = 1.70158;
|
|
791
|
+
const c2 = c1 * 1.525;
|
|
792
|
+
return t < 0.5 ? 2 * t * (2 * t) * ((c2 + 1) * 2 * t - c2) / 2 : ((2 * t - 2) * (2 * t - 2) * ((c2 + 1) * (2 * t - 2) + c2) + 2) / 2;
|
|
793
|
+
},
|
|
794
|
+
// Elastic
|
|
795
|
+
easeInElastic: (t) => {
|
|
796
|
+
if (t === 0 || t === 1) return t;
|
|
797
|
+
return -Math.pow(2, 10 * t - 10) * Math.sin((t * 10 - 10.75) * (2 * Math.PI / 3));
|
|
798
|
+
},
|
|
799
|
+
easeOutElastic: (t) => {
|
|
800
|
+
if (t === 0 || t === 1) return t;
|
|
801
|
+
return Math.pow(2, -10 * t) * Math.sin((t * 10 - 0.75) * (2 * Math.PI / 3)) + 1;
|
|
802
|
+
},
|
|
803
|
+
easeInOutElastic: (t) => {
|
|
804
|
+
if (t === 0 || t === 1) return t;
|
|
805
|
+
const c5 = 2 * Math.PI / 4.5;
|
|
806
|
+
return t < 0.5 ? -(Math.pow(2, 20 * t - 10) * Math.sin((20 * t - 11.125) * c5)) / 2 : Math.pow(2, -20 * t + 10) * Math.sin((20 * t - 11.125) * c5) / 2 + 1;
|
|
807
|
+
},
|
|
808
|
+
// Bounce
|
|
809
|
+
easeOutBounce: (t) => {
|
|
810
|
+
const n1 = 7.5625;
|
|
811
|
+
const d1 = 2.75;
|
|
812
|
+
if (t < 1 / d1) return n1 * t * t;
|
|
813
|
+
if (t < 2 / d1) {
|
|
814
|
+
const t22 = t - 1.5 / d1;
|
|
815
|
+
return n1 * t22 * t22 + 0.75;
|
|
816
|
+
}
|
|
817
|
+
if (t < 2.5 / d1) {
|
|
818
|
+
const t22 = t - 2.25 / d1;
|
|
819
|
+
return n1 * t22 * t22 + 0.9375;
|
|
820
|
+
}
|
|
821
|
+
const t2 = t - 2.625 / d1;
|
|
822
|
+
return n1 * t2 * t2 + 0.984375;
|
|
823
|
+
},
|
|
824
|
+
easeInBounce: (t) => 1 - Ease.easeOutBounce(1 - t),
|
|
825
|
+
easeInOutBounce: (t) => t < 0.5 ? (1 - Ease.easeOutBounce(1 - 2 * t)) / 2 : (1 + Ease.easeOutBounce(2 * t - 1)) / 2
|
|
745
826
|
};
|
|
746
827
|
function tween(from, to, duration, ease = Ease.linear, onUpdate, onComplete) {
|
|
747
828
|
let elapsed = 0;
|
|
@@ -767,6 +848,87 @@ function tween(from, to, duration, ease = Ease.linear, onUpdate, onComplete) {
|
|
|
767
848
|
};
|
|
768
849
|
}
|
|
769
850
|
|
|
851
|
+
// ../../packages/core/src/tweenTimeline.ts
|
|
852
|
+
function createTimeline() {
|
|
853
|
+
const entries = [];
|
|
854
|
+
let running = false;
|
|
855
|
+
let currentTween = null;
|
|
856
|
+
let delayTimer = null;
|
|
857
|
+
let rafId = null;
|
|
858
|
+
let lastTime = 0;
|
|
859
|
+
function clearCurrent() {
|
|
860
|
+
if (currentTween) {
|
|
861
|
+
currentTween.stop();
|
|
862
|
+
currentTween = null;
|
|
863
|
+
}
|
|
864
|
+
if (delayTimer !== null) {
|
|
865
|
+
clearTimeout(delayTimer);
|
|
866
|
+
delayTimer = null;
|
|
867
|
+
}
|
|
868
|
+
if (rafId !== null) {
|
|
869
|
+
cancelAnimationFrame(rafId);
|
|
870
|
+
rafId = null;
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
function tick(now) {
|
|
874
|
+
if (!running || !currentTween) return;
|
|
875
|
+
const dt = (now - lastTime) / 1e3;
|
|
876
|
+
lastTime = now;
|
|
877
|
+
currentTween.update(dt);
|
|
878
|
+
if (!currentTween.isComplete) {
|
|
879
|
+
rafId = requestAnimationFrame(tick);
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
function playEntry(index) {
|
|
883
|
+
if (index >= entries.length) {
|
|
884
|
+
running = false;
|
|
885
|
+
return;
|
|
886
|
+
}
|
|
887
|
+
const entry = entries[index];
|
|
888
|
+
const delay = entry.delay ?? 0;
|
|
889
|
+
const startTween = () => {
|
|
890
|
+
if (!running) return;
|
|
891
|
+
currentTween = tween(
|
|
892
|
+
entry.from,
|
|
893
|
+
entry.to,
|
|
894
|
+
entry.duration,
|
|
895
|
+
entry.ease ?? Ease.linear,
|
|
896
|
+
entry.onUpdate,
|
|
897
|
+
() => {
|
|
898
|
+
entry.onComplete?.();
|
|
899
|
+
playEntry(index + 1);
|
|
900
|
+
}
|
|
901
|
+
);
|
|
902
|
+
lastTime = performance.now();
|
|
903
|
+
rafId = requestAnimationFrame(tick);
|
|
904
|
+
};
|
|
905
|
+
if (delay > 0) {
|
|
906
|
+
delayTimer = setTimeout(startTween, delay * 1e3);
|
|
907
|
+
} else {
|
|
908
|
+
startTween();
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
const timeline = {
|
|
912
|
+
add(entry) {
|
|
913
|
+
entries.push(entry);
|
|
914
|
+
return timeline;
|
|
915
|
+
},
|
|
916
|
+
start() {
|
|
917
|
+
clearCurrent();
|
|
918
|
+
running = true;
|
|
919
|
+
playEntry(0);
|
|
920
|
+
},
|
|
921
|
+
stop() {
|
|
922
|
+
running = false;
|
|
923
|
+
clearCurrent();
|
|
924
|
+
},
|
|
925
|
+
isRunning() {
|
|
926
|
+
return running;
|
|
927
|
+
}
|
|
928
|
+
};
|
|
929
|
+
return timeline;
|
|
930
|
+
}
|
|
931
|
+
|
|
770
932
|
// ../../packages/core/src/timer.ts
|
|
771
933
|
function createTimer(duration, onComplete, autoStart = false) {
|
|
772
934
|
let _duration = duration;
|
|
@@ -831,6 +993,48 @@ function hotReloadPlugin(engine, oldPlugin, newPlugin, oldSystems) {
|
|
|
831
993
|
newPlugin.onInit?.(engine);
|
|
832
994
|
}
|
|
833
995
|
|
|
996
|
+
// ../../packages/core/src/tilemapMerge.ts
|
|
997
|
+
function mergeTileColliders(solidGrid, tileWidth, tileHeight, originX, originY) {
|
|
998
|
+
const rows = solidGrid.length;
|
|
999
|
+
if (rows === 0) return [];
|
|
1000
|
+
const cols = solidGrid[0].length;
|
|
1001
|
+
const visited = [];
|
|
1002
|
+
for (let r = 0; r < rows; r++) {
|
|
1003
|
+
visited[r] = new Array(cols).fill(false);
|
|
1004
|
+
}
|
|
1005
|
+
const rects = [];
|
|
1006
|
+
for (let row = 0; row < rows; row++) {
|
|
1007
|
+
for (let col = 0; col < cols; col++) {
|
|
1008
|
+
if (!solidGrid[row][col] || visited[row][col]) continue;
|
|
1009
|
+
let maxCol = col;
|
|
1010
|
+
while (maxCol + 1 < cols && solidGrid[row][maxCol + 1] && !visited[row][maxCol + 1]) {
|
|
1011
|
+
maxCol++;
|
|
1012
|
+
}
|
|
1013
|
+
let maxRow = row;
|
|
1014
|
+
outer:
|
|
1015
|
+
for (let r = row + 1; r < rows; r++) {
|
|
1016
|
+
for (let c = col; c <= maxCol; c++) {
|
|
1017
|
+
if (!solidGrid[r][c] || visited[r][c]) break outer;
|
|
1018
|
+
}
|
|
1019
|
+
maxRow = r;
|
|
1020
|
+
}
|
|
1021
|
+
for (let r = row; r <= maxRow; r++) {
|
|
1022
|
+
for (let c = col; c <= maxCol; c++) {
|
|
1023
|
+
visited[r][c] = true;
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
const spanCols = maxCol - col + 1;
|
|
1027
|
+
const spanRows = maxRow - row + 1;
|
|
1028
|
+
const width = spanCols * tileWidth;
|
|
1029
|
+
const height = spanRows * tileHeight;
|
|
1030
|
+
const x = originX + col * tileWidth + width / 2;
|
|
1031
|
+
const y = originY + row * tileHeight + height / 2;
|
|
1032
|
+
rects.push({ x, y, width, height });
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
return rects;
|
|
1036
|
+
}
|
|
1037
|
+
|
|
834
1038
|
// ../../packages/input/src/keyboard.ts
|
|
835
1039
|
var Keyboard = class {
|
|
836
1040
|
held = /* @__PURE__ */ new Set();
|
|
@@ -1156,13 +1360,36 @@ function createSprite(opts) {
|
|
|
1156
1360
|
zIndex: 0,
|
|
1157
1361
|
visible: true,
|
|
1158
1362
|
flipX: false,
|
|
1363
|
+
flipY: false,
|
|
1159
1364
|
anchorX: 0.5,
|
|
1160
1365
|
anchorY: 0.5,
|
|
1161
1366
|
frameIndex: 0,
|
|
1367
|
+
blendMode: "normal",
|
|
1368
|
+
layer: "default",
|
|
1162
1369
|
...opts
|
|
1163
1370
|
};
|
|
1164
1371
|
}
|
|
1165
1372
|
|
|
1373
|
+
// ../../packages/renderer/src/renderLayers.ts
|
|
1374
|
+
var defaultLayers = [
|
|
1375
|
+
{ name: "background", order: -100 },
|
|
1376
|
+
{ name: "default", order: 0 },
|
|
1377
|
+
{ name: "foreground", order: 100 },
|
|
1378
|
+
{ name: "ui", order: 200 }
|
|
1379
|
+
];
|
|
1380
|
+
function createRenderLayerManager(layers = defaultLayers) {
|
|
1381
|
+
const map = /* @__PURE__ */ new Map();
|
|
1382
|
+
for (const l of layers) map.set(l.name, l.order);
|
|
1383
|
+
return {
|
|
1384
|
+
addLayer(name, order) {
|
|
1385
|
+
map.set(name, order);
|
|
1386
|
+
},
|
|
1387
|
+
getOrder(name) {
|
|
1388
|
+
return map.get(name) ?? 0;
|
|
1389
|
+
}
|
|
1390
|
+
};
|
|
1391
|
+
}
|
|
1392
|
+
|
|
1166
1393
|
// ../../packages/renderer/src/textureFilter.ts
|
|
1167
1394
|
var TextureFilter = {
|
|
1168
1395
|
/** Nearest-neighbor — sharp pixels, ideal for pixel art */
|
|
@@ -1269,8 +1496,9 @@ layout(location = 4) in float i_rot;
|
|
|
1269
1496
|
layout(location = 5) in vec2 i_anchor;
|
|
1270
1497
|
layout(location = 6) in vec2 i_offset;
|
|
1271
1498
|
layout(location = 7) in float i_flipX;
|
|
1272
|
-
layout(location = 8) in
|
|
1273
|
-
layout(location = 9) in vec4
|
|
1499
|
+
layout(location = 8) in float i_flipY;
|
|
1500
|
+
layout(location = 9) in vec4 i_color;
|
|
1501
|
+
layout(location = 10) in vec4 i_uvRect;
|
|
1274
1502
|
|
|
1275
1503
|
uniform vec2 u_camPos;
|
|
1276
1504
|
uniform float u_zoom;
|
|
@@ -1286,6 +1514,8 @@ void main() {
|
|
|
1286
1514
|
|
|
1287
1515
|
// Horizontal flip
|
|
1288
1516
|
if (i_flipX > 0.5) local.x = -local.x;
|
|
1517
|
+
// Vertical flip
|
|
1518
|
+
if (i_flipY > 0.5) local.y = -local.y;
|
|
1289
1519
|
|
|
1290
1520
|
// Rotate around local origin
|
|
1291
1521
|
float c = cos(i_rot);
|
|
@@ -1397,9 +1627,9 @@ function parseCSSColor(css) {
|
|
|
1397
1627
|
}
|
|
1398
1628
|
|
|
1399
1629
|
// ../../packages/renderer/src/webglRenderSystem.ts
|
|
1400
|
-
var FLOATS_PER_INSTANCE =
|
|
1401
|
-
var MAX_INSTANCES =
|
|
1402
|
-
var MAX_SPRITE_TEXTURES =
|
|
1630
|
+
var FLOATS_PER_INSTANCE = 19;
|
|
1631
|
+
var MAX_INSTANCES = 16384;
|
|
1632
|
+
var MAX_SPRITE_TEXTURES = 1024;
|
|
1403
1633
|
var MAX_TEXT_CACHE = 200;
|
|
1404
1634
|
function compileShader(gl, type, src) {
|
|
1405
1635
|
const shader = gl.createShader(type);
|
|
@@ -1531,8 +1761,9 @@ var RenderSystem = class {
|
|
|
1531
1761
|
addAttr(5, 2);
|
|
1532
1762
|
addAttr(6, 2);
|
|
1533
1763
|
addAttr(7, 1);
|
|
1534
|
-
addAttr(8,
|
|
1764
|
+
addAttr(8, 1);
|
|
1535
1765
|
addAttr(9, 4);
|
|
1766
|
+
addAttr(10, 4);
|
|
1536
1767
|
gl.bindVertexArray(null);
|
|
1537
1768
|
gl.useProgram(this.program);
|
|
1538
1769
|
this.uCamPos = gl.getUniformLocation(this.program, "u_camPos");
|
|
@@ -1604,6 +1835,8 @@ var RenderSystem = class {
|
|
|
1604
1835
|
textureCache = /* @__PURE__ */ new Map();
|
|
1605
1836
|
/** Insertion-order key list for LRU-style eviction. */
|
|
1606
1837
|
textureCacheKeys = [];
|
|
1838
|
+
// ── Render layer manager ────────────────────────────────────────────────
|
|
1839
|
+
layers = createRenderLayerManager();
|
|
1607
1840
|
// ── Texture sampling ────────────────────────────────────────────────────
|
|
1608
1841
|
_defaultSampling = DEFAULT_SAMPLING;
|
|
1609
1842
|
/** Set the global default texture sampling mode for all sprites that don't specify their own. */
|
|
@@ -1768,10 +2001,29 @@ var RenderSystem = class {
|
|
|
1768
2001
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, toGLMinFilter(gl, min));
|
|
1769
2002
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, toGLMagFilter(gl, mag));
|
|
1770
2003
|
}
|
|
2004
|
+
// ── Blend mode helper ────────────────────────────────────────────────────
|
|
2005
|
+
applyBlendMode(mode) {
|
|
2006
|
+
const { gl } = this;
|
|
2007
|
+
switch (mode) {
|
|
2008
|
+
case "additive":
|
|
2009
|
+
gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
|
|
2010
|
+
break;
|
|
2011
|
+
case "multiply":
|
|
2012
|
+
gl.blendFunc(gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA);
|
|
2013
|
+
break;
|
|
2014
|
+
case "screen":
|
|
2015
|
+
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_COLOR);
|
|
2016
|
+
break;
|
|
2017
|
+
default:
|
|
2018
|
+
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
|
2019
|
+
break;
|
|
2020
|
+
}
|
|
2021
|
+
}
|
|
1771
2022
|
// ── Instanced draw call ────────────────────────────────────────────────────
|
|
1772
|
-
flush(count, textureKey, sampling) {
|
|
2023
|
+
flush(count, textureKey, sampling, blendMode) {
|
|
1773
2024
|
if (count === 0) return;
|
|
1774
2025
|
const { gl } = this;
|
|
2026
|
+
if (blendMode && blendMode !== "normal") this.applyBlendMode(blendMode);
|
|
1775
2027
|
const isColor = textureKey.startsWith("__color__");
|
|
1776
2028
|
const tex = isColor ? this.whiteTexture : this.loadTexture(textureKey);
|
|
1777
2029
|
gl.bindTexture(gl.TEXTURE_2D, tex);
|
|
@@ -1781,6 +2033,7 @@ var RenderSystem = class {
|
|
|
1781
2033
|
gl.bindBuffer(gl.ARRAY_BUFFER, this.instanceBuffer);
|
|
1782
2034
|
gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.instanceData, 0, count * FLOATS_PER_INSTANCE);
|
|
1783
2035
|
gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, count);
|
|
2036
|
+
if (blendMode && blendMode !== "normal") this.applyBlendMode("normal");
|
|
1784
2037
|
}
|
|
1785
2038
|
flushWithTex(count, tex, useTexture) {
|
|
1786
2039
|
if (count === 0) return;
|
|
@@ -1793,7 +2046,7 @@ var RenderSystem = class {
|
|
|
1793
2046
|
gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, count);
|
|
1794
2047
|
}
|
|
1795
2048
|
// ── Write one sprite instance into instanceData ───────────────────────────
|
|
1796
|
-
writeInstance(base, x, y, w, h, rot, anchorX, anchorY, offsetX, offsetY, flipX, r, g, b, a, u, v, uw, vh) {
|
|
2049
|
+
writeInstance(base, x, y, w, h, rot, anchorX, anchorY, offsetX, offsetY, flipX, flipY, r, g, b, a, u, v, uw, vh) {
|
|
1797
2050
|
const d = this.instanceData;
|
|
1798
2051
|
d[base + 0] = x;
|
|
1799
2052
|
d[base + 1] = y;
|
|
@@ -1805,14 +2058,15 @@ var RenderSystem = class {
|
|
|
1805
2058
|
d[base + 7] = offsetX;
|
|
1806
2059
|
d[base + 8] = offsetY;
|
|
1807
2060
|
d[base + 9] = flipX ? 1 : 0;
|
|
1808
|
-
d[base + 10] =
|
|
1809
|
-
d[base + 11] =
|
|
1810
|
-
d[base + 12] =
|
|
1811
|
-
d[base + 13] =
|
|
1812
|
-
d[base + 14] =
|
|
1813
|
-
d[base + 15] =
|
|
1814
|
-
d[base + 16] =
|
|
1815
|
-
d[base + 17] =
|
|
2061
|
+
d[base + 10] = flipY ? 1 : 0;
|
|
2062
|
+
d[base + 11] = r;
|
|
2063
|
+
d[base + 12] = g;
|
|
2064
|
+
d[base + 13] = b;
|
|
2065
|
+
d[base + 14] = a;
|
|
2066
|
+
d[base + 15] = u;
|
|
2067
|
+
d[base + 16] = v;
|
|
2068
|
+
d[base + 17] = uw;
|
|
2069
|
+
d[base + 18] = vh;
|
|
1816
2070
|
}
|
|
1817
2071
|
// ── Main update loop ───────────────────────────────────────────────────────
|
|
1818
2072
|
update(world, dt) {
|
|
@@ -1947,6 +2201,8 @@ var RenderSystem = class {
|
|
|
1947
2201
|
renderables.sort((a, b) => {
|
|
1948
2202
|
const sa = world.getComponent(a, "Sprite");
|
|
1949
2203
|
const sb = world.getComponent(b, "Sprite");
|
|
2204
|
+
const ld = this.layers.getOrder(sa.layer) - this.layers.getOrder(sb.layer);
|
|
2205
|
+
if (ld !== 0) return ld;
|
|
1950
2206
|
const zd = sa.zIndex - sb.zIndex;
|
|
1951
2207
|
if (zd !== 0) return zd;
|
|
1952
2208
|
const ka = getTextureKey(sa), kb = getTextureKey(sb);
|
|
@@ -1955,9 +2211,10 @@ var RenderSystem = class {
|
|
|
1955
2211
|
let batchCount = 0;
|
|
1956
2212
|
let batchKey = "";
|
|
1957
2213
|
let batchSampling;
|
|
2214
|
+
let batchBlendMode = "normal";
|
|
1958
2215
|
for (let i = 0; i <= renderables.length; i++) {
|
|
1959
2216
|
if (i === renderables.length) {
|
|
1960
|
-
this.flush(batchCount, batchKey, batchSampling);
|
|
2217
|
+
this.flush(batchCount, batchKey, batchSampling, batchBlendMode);
|
|
1961
2218
|
break;
|
|
1962
2219
|
}
|
|
1963
2220
|
const id = renderables[i];
|
|
@@ -2006,12 +2263,14 @@ var RenderSystem = class {
|
|
|
2006
2263
|
sprite.image = img;
|
|
2007
2264
|
}
|
|
2008
2265
|
const key = getTextureKey(sprite);
|
|
2009
|
-
|
|
2010
|
-
|
|
2266
|
+
const spriteBlend = sprite.blendMode ?? "normal";
|
|
2267
|
+
if ((key !== batchKey || spriteBlend !== batchBlendMode) && batchCount > 0 || batchCount >= MAX_INSTANCES) {
|
|
2268
|
+
this.flush(batchCount, batchKey, batchSampling, batchBlendMode);
|
|
2011
2269
|
batchCount = 0;
|
|
2012
2270
|
}
|
|
2013
2271
|
batchKey = key;
|
|
2014
2272
|
batchSampling = sprite.sampling;
|
|
2273
|
+
batchBlendMode = spriteBlend;
|
|
2015
2274
|
const ss = world.getComponent(id, "SquashStretch");
|
|
2016
2275
|
const scaleXMod = ss ? ss.currentScaleX : 1;
|
|
2017
2276
|
const scaleYMod = ss ? ss.currentScaleY : 1;
|
|
@@ -2030,6 +2289,7 @@ var RenderSystem = class {
|
|
|
2030
2289
|
sprite.offsetX,
|
|
2031
2290
|
sprite.offsetY,
|
|
2032
2291
|
sprite.flipX,
|
|
2292
|
+
sprite.flipY ?? false,
|
|
2033
2293
|
r,
|
|
2034
2294
|
g,
|
|
2035
2295
|
b,
|
|
@@ -2053,10 +2313,11 @@ var RenderSystem = class {
|
|
|
2053
2313
|
if (!text.visible) continue;
|
|
2054
2314
|
const entry = this.getOrCreateTextTexture(text);
|
|
2055
2315
|
if (!entry) continue;
|
|
2056
|
-
this.flush(batchCount, batchKey, batchSampling);
|
|
2316
|
+
this.flush(batchCount, batchKey, batchSampling, batchBlendMode);
|
|
2057
2317
|
batchCount = 0;
|
|
2058
2318
|
batchKey = "";
|
|
2059
2319
|
batchSampling = void 0;
|
|
2320
|
+
batchBlendMode = "normal";
|
|
2060
2321
|
this.writeInstance(
|
|
2061
2322
|
0,
|
|
2062
2323
|
transform.x + text.offsetX,
|
|
@@ -2070,6 +2331,9 @@ var RenderSystem = class {
|
|
|
2070
2331
|
0,
|
|
2071
2332
|
0,
|
|
2072
2333
|
false,
|
|
2334
|
+
// flipX
|
|
2335
|
+
false,
|
|
2336
|
+
// flipY
|
|
2073
2337
|
1,
|
|
2074
2338
|
1,
|
|
2075
2339
|
1,
|
|
@@ -2093,15 +2357,33 @@ var RenderSystem = class {
|
|
|
2093
2357
|
return p.life > 0;
|
|
2094
2358
|
});
|
|
2095
2359
|
if (pool.active && pool.particles.length < pool.maxParticles) {
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2360
|
+
let spawnCount;
|
|
2361
|
+
if (pool.burstCount != null && pool.burstCount > 0) {
|
|
2362
|
+
spawnCount = pool.burstCount;
|
|
2363
|
+
pool.active = false;
|
|
2364
|
+
} else {
|
|
2365
|
+
pool.timer += dt;
|
|
2366
|
+
spawnCount = Math.floor(pool.timer * pool.rate);
|
|
2367
|
+
pool.timer -= spawnCount / pool.rate;
|
|
2368
|
+
}
|
|
2099
2369
|
for (let i = 0; i < spawnCount && pool.particles.length < pool.maxParticles; i++) {
|
|
2100
2370
|
const angle = pool.angle + (world.rng() - 0.5) * pool.spread;
|
|
2101
2371
|
const speed = pool.speed * (0.5 + world.rng() * 0.5);
|
|
2372
|
+
let ox = 0;
|
|
2373
|
+
let oy = 0;
|
|
2374
|
+
const shape = pool.emitShape ?? "point";
|
|
2375
|
+
if (shape === "circle") {
|
|
2376
|
+
const r = (pool.emitRadius ?? 0) * Math.sqrt(world.rng());
|
|
2377
|
+
const a = world.rng() * Math.PI * 2;
|
|
2378
|
+
ox = Math.cos(a) * r;
|
|
2379
|
+
oy = Math.sin(a) * r;
|
|
2380
|
+
} else if (shape === "box") {
|
|
2381
|
+
ox = (world.rng() - 0.5) * (pool.emitWidth ?? 0);
|
|
2382
|
+
oy = (world.rng() - 0.5) * (pool.emitHeight ?? 0);
|
|
2383
|
+
}
|
|
2102
2384
|
pool.particles.push({
|
|
2103
|
-
x: t.x,
|
|
2104
|
-
y: t.y,
|
|
2385
|
+
x: t.x + ox,
|
|
2386
|
+
y: t.y + oy,
|
|
2105
2387
|
vx: Math.cos(angle) * speed,
|
|
2106
2388
|
vy: Math.sin(angle) * speed,
|
|
2107
2389
|
life: pool.particleLife,
|
|
@@ -2133,6 +2415,7 @@ var RenderSystem = class {
|
|
|
2133
2415
|
0,
|
|
2134
2416
|
0,
|
|
2135
2417
|
false,
|
|
2418
|
+
false,
|
|
2136
2419
|
r,
|
|
2137
2420
|
g,
|
|
2138
2421
|
b,
|
|
@@ -2173,6 +2456,7 @@ var RenderSystem = class {
|
|
|
2173
2456
|
0,
|
|
2174
2457
|
0,
|
|
2175
2458
|
false,
|
|
2459
|
+
false,
|
|
2176
2460
|
tr,
|
|
2177
2461
|
tg,
|
|
2178
2462
|
tb,
|
|
@@ -2210,6 +2494,7 @@ var RenderSystem = class {
|
|
|
2210
2494
|
0,
|
|
2211
2495
|
0,
|
|
2212
2496
|
false,
|
|
2497
|
+
false,
|
|
2213
2498
|
walkable ? 0 : 1,
|
|
2214
2499
|
walkable ? 1 : 0,
|
|
2215
2500
|
0,
|
|
@@ -2243,6 +2528,7 @@ var RenderSystem = class {
|
|
|
2243
2528
|
0,
|
|
2244
2529
|
0,
|
|
2245
2530
|
false,
|
|
2531
|
+
false,
|
|
2246
2532
|
1,
|
|
2247
2533
|
0.3,
|
|
2248
2534
|
0.3,
|
|
@@ -2292,6 +2578,72 @@ var Canvas2DRenderer = class {
|
|
|
2292
2578
|
}
|
|
2293
2579
|
};
|
|
2294
2580
|
|
|
2581
|
+
// ../../packages/renderer/src/postProcess.ts
|
|
2582
|
+
function createPostProcessStack() {
|
|
2583
|
+
const effects = [];
|
|
2584
|
+
return {
|
|
2585
|
+
add(effect) {
|
|
2586
|
+
if (!effects.includes(effect)) {
|
|
2587
|
+
effects.push(effect);
|
|
2588
|
+
}
|
|
2589
|
+
},
|
|
2590
|
+
remove(effect) {
|
|
2591
|
+
const idx = effects.indexOf(effect);
|
|
2592
|
+
if (idx !== -1) effects.splice(idx, 1);
|
|
2593
|
+
},
|
|
2594
|
+
apply(ctx, width, height, dt) {
|
|
2595
|
+
for (const effect of effects) {
|
|
2596
|
+
ctx.save();
|
|
2597
|
+
effect(ctx, width, height, dt);
|
|
2598
|
+
ctx.restore();
|
|
2599
|
+
}
|
|
2600
|
+
},
|
|
2601
|
+
clear() {
|
|
2602
|
+
effects.length = 0;
|
|
2603
|
+
}
|
|
2604
|
+
};
|
|
2605
|
+
}
|
|
2606
|
+
function vignetteEffect(intensity = 0.4) {
|
|
2607
|
+
return (ctx, width, height) => {
|
|
2608
|
+
const cx = width / 2;
|
|
2609
|
+
const cy = height / 2;
|
|
2610
|
+
const radius = Math.sqrt(cx * cx + cy * cy);
|
|
2611
|
+
const gradient = ctx.createRadialGradient(cx, cy, radius * 0.3, cx, cy, radius);
|
|
2612
|
+
gradient.addColorStop(0, "rgba(0,0,0,0)");
|
|
2613
|
+
gradient.addColorStop(1, `rgba(0,0,0,${intensity})`);
|
|
2614
|
+
ctx.fillStyle = gradient;
|
|
2615
|
+
ctx.fillRect(0, 0, width, height);
|
|
2616
|
+
};
|
|
2617
|
+
}
|
|
2618
|
+
function scanlineEffect(gap = 3, opacity = 0.15) {
|
|
2619
|
+
return (ctx, width, height) => {
|
|
2620
|
+
ctx.fillStyle = `rgba(0,0,0,${opacity})`;
|
|
2621
|
+
for (let y = 0; y < height; y += gap) {
|
|
2622
|
+
ctx.fillRect(0, y, width, 1);
|
|
2623
|
+
}
|
|
2624
|
+
};
|
|
2625
|
+
}
|
|
2626
|
+
function chromaticAberrationEffect(offset = 2) {
|
|
2627
|
+
return (ctx, width, height) => {
|
|
2628
|
+
if (width === 0 || height === 0) return;
|
|
2629
|
+
const imageData = ctx.getImageData(0, 0, width, height);
|
|
2630
|
+
const { data } = imageData;
|
|
2631
|
+
const copy = new Uint8ClampedArray(data);
|
|
2632
|
+
for (let y = 0; y < height; y++) {
|
|
2633
|
+
for (let x = 0; x < width; x++) {
|
|
2634
|
+
const i = (y * width + x) * 4;
|
|
2635
|
+
const srcR = Math.min(x + offset, width - 1);
|
|
2636
|
+
const iR = (y * width + srcR) * 4;
|
|
2637
|
+
data[i] = copy[iR];
|
|
2638
|
+
const srcB = Math.max(x - offset, 0);
|
|
2639
|
+
const iB = (y * width + srcB) * 4;
|
|
2640
|
+
data[i + 2] = copy[iB + 2];
|
|
2641
|
+
}
|
|
2642
|
+
}
|
|
2643
|
+
ctx.putImageData(imageData, 0, 0);
|
|
2644
|
+
};
|
|
2645
|
+
}
|
|
2646
|
+
|
|
2295
2647
|
// ../../packages/physics/src/components/rigidbody.ts
|
|
2296
2648
|
function createRigidBody(opts) {
|
|
2297
2649
|
return {
|
|
@@ -2310,6 +2662,9 @@ function createRigidBody(opts) {
|
|
|
2310
2662
|
isKinematic: false,
|
|
2311
2663
|
dropThrough: 0,
|
|
2312
2664
|
ccd: false,
|
|
2665
|
+
angularVelocity: 0,
|
|
2666
|
+
angularDamping: 0,
|
|
2667
|
+
linearDamping: 0,
|
|
2313
2668
|
...opts
|
|
2314
2669
|
};
|
|
2315
2670
|
}
|
|
@@ -2644,6 +2999,15 @@ var PhysicsSystem = class {
|
|
|
2644
2999
|
if (!rb.lockY) rb.vy += this.gravity * rb.gravityScale * dt;
|
|
2645
3000
|
if (rb.lockX) rb.vx = 0;
|
|
2646
3001
|
if (rb.lockY) rb.vy = 0;
|
|
3002
|
+
if (rb.linearDamping > 0) {
|
|
3003
|
+
rb.vx *= 1 - rb.linearDamping;
|
|
3004
|
+
rb.vy *= 1 - rb.linearDamping;
|
|
3005
|
+
}
|
|
3006
|
+
if (rb.angularVelocity !== 0) {
|
|
3007
|
+
const transform = world.getComponent(id, "Transform");
|
|
3008
|
+
transform.rotation += rb.angularVelocity * dt;
|
|
3009
|
+
if (rb.angularDamping > 0) rb.angularVelocity *= 1 - rb.angularDamping;
|
|
3010
|
+
}
|
|
2647
3011
|
if (rb.dropThrough > 0) rb.dropThrough--;
|
|
2648
3012
|
}
|
|
2649
3013
|
const ccdPrev = /* @__PURE__ */ new Map();
|
|
@@ -2662,6 +3026,15 @@ var PhysicsSystem = class {
|
|
|
2662
3026
|
if (!rb.lockY) rb.vy += this.gravity * rb.gravityScale * dt;
|
|
2663
3027
|
if (rb.lockX) rb.vx = 0;
|
|
2664
3028
|
if (rb.lockY) rb.vy = 0;
|
|
3029
|
+
if (rb.linearDamping > 0) {
|
|
3030
|
+
rb.vx *= 1 - rb.linearDamping;
|
|
3031
|
+
rb.vy *= 1 - rb.linearDamping;
|
|
3032
|
+
}
|
|
3033
|
+
if (rb.angularVelocity !== 0) {
|
|
3034
|
+
const transform = world.getComponent(id, "Transform");
|
|
3035
|
+
transform.rotation += rb.angularVelocity * dt;
|
|
3036
|
+
if (rb.angularDamping > 0) rb.angularVelocity *= 1 - rb.angularDamping;
|
|
3037
|
+
}
|
|
2665
3038
|
if (rb.dropThrough > 0) rb.dropThrough--;
|
|
2666
3039
|
}
|
|
2667
3040
|
for (const id of dynamics) {
|
|
@@ -3543,10 +3916,48 @@ function useCircleStay(handler, opts) {
|
|
|
3543
3916
|
useContactEvent("circleStay", handler, opts);
|
|
3544
3917
|
}
|
|
3545
3918
|
|
|
3919
|
+
// ../context/src/useCollidingWith.ts
|
|
3920
|
+
import { useContext as useContext2, useEffect as useEffect2, useRef as useRef2 } from "react";
|
|
3921
|
+
function useCollidingWith() {
|
|
3922
|
+
const engine = useContext2(EngineContext);
|
|
3923
|
+
const entityId = useContext2(EntityContext);
|
|
3924
|
+
if (!engine) throw new Error("useCollidingWith hook must be used inside <Game>");
|
|
3925
|
+
if (entityId === null) throw new Error("useCollidingWith hook must be used inside <Entity>");
|
|
3926
|
+
const setRef = useRef2(/* @__PURE__ */ new Set());
|
|
3927
|
+
useEffect2(() => {
|
|
3928
|
+
const set = setRef.current;
|
|
3929
|
+
function handleEnter({ a, b }) {
|
|
3930
|
+
const isA = a === entityId;
|
|
3931
|
+
const isB = b === entityId;
|
|
3932
|
+
if (!isA && !isB) return;
|
|
3933
|
+
set.add(isA ? b : a);
|
|
3934
|
+
}
|
|
3935
|
+
function handleExit({ a, b }) {
|
|
3936
|
+
const isA = a === entityId;
|
|
3937
|
+
const isB = b === entityId;
|
|
3938
|
+
if (!isA && !isB) return;
|
|
3939
|
+
set.delete(isA ? b : a);
|
|
3940
|
+
}
|
|
3941
|
+
const unsubs = [
|
|
3942
|
+
engine.events.on("collisionEnter", handleEnter),
|
|
3943
|
+
engine.events.on("collisionExit", handleExit),
|
|
3944
|
+
engine.events.on("triggerEnter", handleEnter),
|
|
3945
|
+
engine.events.on("triggerExit", handleExit),
|
|
3946
|
+
engine.events.on("circleEnter", handleEnter),
|
|
3947
|
+
engine.events.on("circleExit", handleExit)
|
|
3948
|
+
];
|
|
3949
|
+
return () => {
|
|
3950
|
+
unsubs.forEach((unsub) => unsub());
|
|
3951
|
+
set.clear();
|
|
3952
|
+
};
|
|
3953
|
+
}, [engine.events, entityId]);
|
|
3954
|
+
return setRef.current;
|
|
3955
|
+
}
|
|
3956
|
+
|
|
3546
3957
|
// ../devtools/src/DevTools.tsx
|
|
3547
3958
|
import React from "react";
|
|
3548
3959
|
import { createPortal } from "react-dom";
|
|
3549
|
-
import { useState, useEffect as
|
|
3960
|
+
import { useState, useEffect as useEffect3, useCallback, useRef as useRef3 } from "react";
|
|
3550
3961
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3551
3962
|
var MAX_DEVTOOLS_FRAMES = 600;
|
|
3552
3963
|
var C = {
|
|
@@ -3710,8 +4121,8 @@ function DevToolsOverlay({ handle, loop, ecs, engine }) {
|
|
|
3710
4121
|
const [contactLog, setContactLog] = useState([]);
|
|
3711
4122
|
const [showNavGrid, setShowNavGrid] = useState(false);
|
|
3712
4123
|
const [showContactFlash, setShowContactFlash] = useState(false);
|
|
3713
|
-
const frameRef =
|
|
3714
|
-
|
|
4124
|
+
const frameRef = useRef3(0);
|
|
4125
|
+
useEffect3(() => {
|
|
3715
4126
|
handle.onFrame = () => {
|
|
3716
4127
|
frameRef.current++;
|
|
3717
4128
|
if (!paused) {
|
|
@@ -3723,7 +4134,7 @@ function DevToolsOverlay({ handle, loop, ecs, engine }) {
|
|
|
3723
4134
|
handle.onFrame = void 0;
|
|
3724
4135
|
};
|
|
3725
4136
|
}, [handle, paused]);
|
|
3726
|
-
|
|
4137
|
+
useEffect3(() => {
|
|
3727
4138
|
if (!engine) return;
|
|
3728
4139
|
const events = engine.events;
|
|
3729
4140
|
const types = ["triggerEnter", "triggerExit", "collisionEnter", "collisionExit", "circleEnter", "circleExit"];
|
|
@@ -4234,13 +4645,13 @@ function Game({
|
|
|
4234
4645
|
className,
|
|
4235
4646
|
children
|
|
4236
4647
|
}) {
|
|
4237
|
-
const canvasRef =
|
|
4238
|
-
const debugCanvasRef =
|
|
4239
|
-
const wrapperRef =
|
|
4648
|
+
const canvasRef = useRef4(null);
|
|
4649
|
+
const debugCanvasRef = useRef4(null);
|
|
4650
|
+
const wrapperRef = useRef4(null);
|
|
4240
4651
|
const [engine, setEngine] = useState2(null);
|
|
4241
4652
|
const [assetsReady, setAssetsReady] = useState2(asyncAssets);
|
|
4242
|
-
const devtoolsHandle =
|
|
4243
|
-
|
|
4653
|
+
const devtoolsHandle = useRef4({ buffer: [] });
|
|
4654
|
+
useEffect4(() => {
|
|
4244
4655
|
const canvas = canvasRef.current;
|
|
4245
4656
|
const ecs = new ECSWorld();
|
|
4246
4657
|
if (deterministic) ecs.setDeterministicSeed(seed);
|
|
@@ -4283,6 +4694,7 @@ function Game({
|
|
|
4283
4694
|
handle.onFrame?.();
|
|
4284
4695
|
}
|
|
4285
4696
|
}, deterministic ? { fixedDt: 1 / 60 } : void 0);
|
|
4697
|
+
const postProcessStack = createPostProcessStack();
|
|
4286
4698
|
const state = {
|
|
4287
4699
|
ecs,
|
|
4288
4700
|
input,
|
|
@@ -4293,7 +4705,8 @@ function Game({
|
|
|
4293
4705
|
loop,
|
|
4294
4706
|
canvas,
|
|
4295
4707
|
entityIds,
|
|
4296
|
-
systemTimings
|
|
4708
|
+
systemTimings,
|
|
4709
|
+
postProcessStack
|
|
4297
4710
|
};
|
|
4298
4711
|
setEngine(state);
|
|
4299
4712
|
if (plugins) {
|
|
@@ -4355,7 +4768,7 @@ function Game({
|
|
|
4355
4768
|
}
|
|
4356
4769
|
};
|
|
4357
4770
|
}, []);
|
|
4358
|
-
|
|
4771
|
+
useEffect4(() => {
|
|
4359
4772
|
if (!engine) return;
|
|
4360
4773
|
let cancelled = false;
|
|
4361
4774
|
if (asyncAssets) {
|
|
@@ -4373,13 +4786,13 @@ function Game({
|
|
|
4373
4786
|
cancelled = true;
|
|
4374
4787
|
};
|
|
4375
4788
|
}, [engine]);
|
|
4376
|
-
|
|
4789
|
+
useEffect4(() => {
|
|
4377
4790
|
if (!engine) return;
|
|
4378
4791
|
const canvas = engine.canvas;
|
|
4379
4792
|
if (canvas.width !== width) canvas.width = width;
|
|
4380
4793
|
if (canvas.height !== height) canvas.height = height;
|
|
4381
4794
|
}, [width, height, engine]);
|
|
4382
|
-
|
|
4795
|
+
useEffect4(() => {
|
|
4383
4796
|
engine?.physics.setGravity(gravity);
|
|
4384
4797
|
}, [gravity, engine]);
|
|
4385
4798
|
const canvasStyle = {
|
|
@@ -4460,15 +4873,15 @@ function Game({
|
|
|
4460
4873
|
}
|
|
4461
4874
|
|
|
4462
4875
|
// src/components/World.tsx
|
|
4463
|
-
import { useEffect as
|
|
4876
|
+
import { useEffect as useEffect5, useContext as useContext3 } from "react";
|
|
4464
4877
|
import { Fragment as Fragment2, jsx as jsx3 } from "react/jsx-runtime";
|
|
4465
4878
|
function World({ gravity, background = "#1a1a2e", children }) {
|
|
4466
|
-
const engine =
|
|
4467
|
-
|
|
4879
|
+
const engine = useContext3(EngineContext);
|
|
4880
|
+
useEffect5(() => {
|
|
4468
4881
|
if (!engine) return;
|
|
4469
4882
|
if (gravity !== void 0) engine.physics.setGravity(gravity);
|
|
4470
4883
|
}, [gravity, engine]);
|
|
4471
|
-
|
|
4884
|
+
useEffect5(() => {
|
|
4472
4885
|
if (!engine) return;
|
|
4473
4886
|
const camId = engine.ecs.queryOne("Camera2D");
|
|
4474
4887
|
if (camId !== void 0) {
|
|
@@ -4482,12 +4895,17 @@ function World({ gravity, background = "#1a1a2e", children }) {
|
|
|
4482
4895
|
}
|
|
4483
4896
|
|
|
4484
4897
|
// src/components/Entity.tsx
|
|
4485
|
-
import { useEffect as
|
|
4898
|
+
import { useEffect as useEffect6, useContext as useContext4, useState as useState3 } from "react";
|
|
4486
4899
|
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
4487
4900
|
function Entity({ id, tags = [], children }) {
|
|
4488
|
-
const engine =
|
|
4901
|
+
const engine = useContext4(EngineContext);
|
|
4489
4902
|
const [entityId, setEntityId] = useState3(null);
|
|
4490
|
-
|
|
4903
|
+
if (process.env.NODE_ENV !== "production") {
|
|
4904
|
+
if (!engine) {
|
|
4905
|
+
console.warn("[Cubeforge] <Entity> must be inside a <World>. No EngineContext found.");
|
|
4906
|
+
}
|
|
4907
|
+
}
|
|
4908
|
+
useEffect6(() => {
|
|
4491
4909
|
const eid = engine.ecs.createEntity();
|
|
4492
4910
|
if (id) {
|
|
4493
4911
|
if (engine.entityIds.has(id)) {
|
|
@@ -4507,15 +4925,15 @@ function Entity({ id, tags = [], children }) {
|
|
|
4507
4925
|
}
|
|
4508
4926
|
|
|
4509
4927
|
// src/components/Transform.tsx
|
|
4510
|
-
import { useEffect as
|
|
4928
|
+
import { useEffect as useEffect7, useContext as useContext5 } from "react";
|
|
4511
4929
|
function Transform({ x = 0, y = 0, rotation = 0, scaleX = 1, scaleY = 1 }) {
|
|
4512
|
-
const engine =
|
|
4513
|
-
const entityId =
|
|
4514
|
-
|
|
4930
|
+
const engine = useContext5(EngineContext);
|
|
4931
|
+
const entityId = useContext5(EntityContext);
|
|
4932
|
+
useEffect7(() => {
|
|
4515
4933
|
engine.ecs.addComponent(entityId, createTransform(x, y, rotation, scaleX, scaleY));
|
|
4516
4934
|
return () => engine.ecs.removeComponent(entityId, "Transform");
|
|
4517
4935
|
}, []);
|
|
4518
|
-
|
|
4936
|
+
useEffect7(() => {
|
|
4519
4937
|
const comp = engine.ecs.getComponent(entityId, "Transform");
|
|
4520
4938
|
if (comp) {
|
|
4521
4939
|
comp.x = x;
|
|
@@ -4529,7 +4947,7 @@ function Transform({ x = 0, y = 0, rotation = 0, scaleX = 1, scaleY = 1 }) {
|
|
|
4529
4947
|
}
|
|
4530
4948
|
|
|
4531
4949
|
// src/components/Sprite.tsx
|
|
4532
|
-
import { useEffect as
|
|
4950
|
+
import { useEffect as useEffect8, useContext as useContext6 } from "react";
|
|
4533
4951
|
function Sprite({
|
|
4534
4952
|
width,
|
|
4535
4953
|
height,
|
|
@@ -4540,6 +4958,7 @@ function Sprite({
|
|
|
4540
4958
|
zIndex = 0,
|
|
4541
4959
|
visible = true,
|
|
4542
4960
|
flipX = false,
|
|
4961
|
+
flipY = false,
|
|
4543
4962
|
anchorX = 0.5,
|
|
4544
4963
|
anchorY = 0.5,
|
|
4545
4964
|
frameIndex = 0,
|
|
@@ -4552,12 +4971,22 @@ function Sprite({
|
|
|
4552
4971
|
tileY,
|
|
4553
4972
|
tileSizeX,
|
|
4554
4973
|
tileSizeY,
|
|
4555
|
-
sampling
|
|
4974
|
+
sampling,
|
|
4975
|
+
blendMode = "normal",
|
|
4976
|
+
layer = "default"
|
|
4556
4977
|
}) {
|
|
4557
4978
|
const resolvedFrameIndex = atlas && frame != null ? atlas[frame] ?? 0 : frameIndex;
|
|
4558
|
-
const engine =
|
|
4559
|
-
const entityId =
|
|
4560
|
-
|
|
4979
|
+
const engine = useContext6(EngineContext);
|
|
4980
|
+
const entityId = useContext6(EntityContext);
|
|
4981
|
+
if (process.env.NODE_ENV !== "production") {
|
|
4982
|
+
if (entityId === null) {
|
|
4983
|
+
console.warn("[Cubeforge] <Sprite> must be inside an <Entity>. No EntityContext found.");
|
|
4984
|
+
}
|
|
4985
|
+
if ((frameWidth != null || frameHeight != null || frameColumns != null) && !src) {
|
|
4986
|
+
console.warn("[Cubeforge] <Sprite> has frameWidth/frameHeight/frameColumns but no `src`. Sprite-sheet props require an image source.");
|
|
4987
|
+
}
|
|
4988
|
+
}
|
|
4989
|
+
useEffect8(() => {
|
|
4561
4990
|
const comp = createSprite({
|
|
4562
4991
|
width,
|
|
4563
4992
|
height,
|
|
@@ -4568,6 +4997,7 @@ function Sprite({
|
|
|
4568
4997
|
zIndex,
|
|
4569
4998
|
visible,
|
|
4570
4999
|
flipX,
|
|
5000
|
+
flipY,
|
|
4571
5001
|
anchorX,
|
|
4572
5002
|
anchorY,
|
|
4573
5003
|
frameIndex: resolvedFrameIndex,
|
|
@@ -4578,7 +5008,9 @@ function Sprite({
|
|
|
4578
5008
|
tileY,
|
|
4579
5009
|
tileSizeX,
|
|
4580
5010
|
tileSizeY,
|
|
4581
|
-
sampling
|
|
5011
|
+
sampling,
|
|
5012
|
+
blendMode,
|
|
5013
|
+
layer
|
|
4582
5014
|
});
|
|
4583
5015
|
engine.ecs.addComponent(entityId, comp);
|
|
4584
5016
|
if (src) {
|
|
@@ -4592,20 +5024,23 @@ function Sprite({
|
|
|
4592
5024
|
}
|
|
4593
5025
|
return () => engine.ecs.removeComponent(entityId, "Sprite");
|
|
4594
5026
|
}, []);
|
|
4595
|
-
|
|
5027
|
+
useEffect8(() => {
|
|
4596
5028
|
const comp = engine.ecs.getComponent(entityId, "Sprite");
|
|
4597
5029
|
if (!comp) return;
|
|
4598
5030
|
comp.color = color;
|
|
4599
5031
|
comp.visible = visible;
|
|
4600
5032
|
comp.flipX = flipX;
|
|
5033
|
+
comp.flipY = flipY;
|
|
4601
5034
|
comp.zIndex = zIndex;
|
|
4602
5035
|
comp.frameIndex = resolvedFrameIndex;
|
|
4603
|
-
|
|
5036
|
+
comp.blendMode = blendMode;
|
|
5037
|
+
comp.layer = layer;
|
|
5038
|
+
}, [color, visible, flipX, flipY, zIndex, resolvedFrameIndex, blendMode, layer, engine, entityId]);
|
|
4604
5039
|
return null;
|
|
4605
5040
|
}
|
|
4606
5041
|
|
|
4607
5042
|
// src/components/Text.tsx
|
|
4608
|
-
import { useEffect as
|
|
5043
|
+
import { useEffect as useEffect9, useContext as useContext7 } from "react";
|
|
4609
5044
|
function Text({
|
|
4610
5045
|
text,
|
|
4611
5046
|
fontSize = 16,
|
|
@@ -4619,9 +5054,9 @@ function Text({
|
|
|
4619
5054
|
offsetX = 0,
|
|
4620
5055
|
offsetY = 0
|
|
4621
5056
|
}) {
|
|
4622
|
-
const engine =
|
|
4623
|
-
const entityId =
|
|
4624
|
-
|
|
5057
|
+
const engine = useContext7(EngineContext);
|
|
5058
|
+
const entityId = useContext7(EntityContext);
|
|
5059
|
+
useEffect9(() => {
|
|
4625
5060
|
const comp = {
|
|
4626
5061
|
type: "Text",
|
|
4627
5062
|
text,
|
|
@@ -4639,7 +5074,7 @@ function Text({
|
|
|
4639
5074
|
engine.ecs.addComponent(entityId, comp);
|
|
4640
5075
|
return () => engine.ecs.removeComponent(entityId, "Text");
|
|
4641
5076
|
}, []);
|
|
4642
|
-
|
|
5077
|
+
useEffect9(() => {
|
|
4643
5078
|
const comp = engine.ecs.getComponent(entityId, "Text");
|
|
4644
5079
|
if (!comp) return;
|
|
4645
5080
|
comp.text = text;
|
|
@@ -4651,7 +5086,7 @@ function Text({
|
|
|
4651
5086
|
}
|
|
4652
5087
|
|
|
4653
5088
|
// src/components/RigidBody.tsx
|
|
4654
|
-
import { useEffect as
|
|
5089
|
+
import { useEffect as useEffect10, useContext as useContext8 } from "react";
|
|
4655
5090
|
function RigidBody({
|
|
4656
5091
|
mass = 1,
|
|
4657
5092
|
gravityScale = 1,
|
|
@@ -4662,19 +5097,27 @@ function RigidBody({
|
|
|
4662
5097
|
vy = 0,
|
|
4663
5098
|
lockX = false,
|
|
4664
5099
|
lockY = false,
|
|
4665
|
-
ccd = false
|
|
5100
|
+
ccd = false,
|
|
5101
|
+
angularVelocity = 0,
|
|
5102
|
+
angularDamping = 0,
|
|
5103
|
+
linearDamping = 0
|
|
4666
5104
|
}) {
|
|
4667
|
-
const engine =
|
|
4668
|
-
const entityId =
|
|
4669
|
-
|
|
4670
|
-
|
|
5105
|
+
const engine = useContext8(EngineContext);
|
|
5106
|
+
const entityId = useContext8(EntityContext);
|
|
5107
|
+
if (process.env.NODE_ENV !== "production") {
|
|
5108
|
+
if (entityId === null) {
|
|
5109
|
+
console.warn("[Cubeforge] <RigidBody> must be inside an <Entity>. No EntityContext found.");
|
|
5110
|
+
}
|
|
5111
|
+
}
|
|
5112
|
+
useEffect10(() => {
|
|
5113
|
+
engine.ecs.addComponent(entityId, createRigidBody({ mass, gravityScale, isStatic, bounce, friction, vx, vy, lockX, lockY, ccd, angularVelocity, angularDamping, linearDamping }));
|
|
4671
5114
|
return () => engine.ecs.removeComponent(entityId, "RigidBody");
|
|
4672
5115
|
}, []);
|
|
4673
5116
|
return null;
|
|
4674
5117
|
}
|
|
4675
5118
|
|
|
4676
5119
|
// src/components/BoxCollider.tsx
|
|
4677
|
-
import { useEffect as
|
|
5120
|
+
import { useEffect as useEffect11, useContext as useContext9 } from "react";
|
|
4678
5121
|
function BoxCollider({
|
|
4679
5122
|
width,
|
|
4680
5123
|
height,
|
|
@@ -4685,13 +5128,18 @@ function BoxCollider({
|
|
|
4685
5128
|
mask = "*",
|
|
4686
5129
|
oneWay = false
|
|
4687
5130
|
}) {
|
|
4688
|
-
const engine =
|
|
4689
|
-
const entityId =
|
|
4690
|
-
|
|
5131
|
+
const engine = useContext9(EngineContext);
|
|
5132
|
+
const entityId = useContext9(EntityContext);
|
|
5133
|
+
useEffect11(() => {
|
|
4691
5134
|
engine.ecs.addComponent(entityId, createBoxCollider(width, height, { offsetX, offsetY, isTrigger, layer, mask, oneWay }));
|
|
4692
5135
|
const checkId = setTimeout(() => {
|
|
4693
|
-
if (
|
|
4694
|
-
|
|
5136
|
+
if (process.env.NODE_ENV !== "production") {
|
|
5137
|
+
if (engine.ecs.hasEntity(entityId) && !engine.ecs.hasComponent(entityId, "Transform")) {
|
|
5138
|
+
console.warn(`[Cubeforge] BoxCollider on entity ${entityId} has no Transform. Physics requires Transform.`);
|
|
5139
|
+
}
|
|
5140
|
+
if (engine.ecs.hasEntity(entityId) && !engine.ecs.hasComponent(entityId, "RigidBody")) {
|
|
5141
|
+
console.warn(`[Cubeforge] BoxCollider on entity ${entityId} has no RigidBody. Add a <RigidBody> sibling for physics to work.`);
|
|
5142
|
+
}
|
|
4695
5143
|
}
|
|
4696
5144
|
}, 0);
|
|
4697
5145
|
return () => {
|
|
@@ -4703,7 +5151,7 @@ function BoxCollider({
|
|
|
4703
5151
|
}
|
|
4704
5152
|
|
|
4705
5153
|
// src/components/CircleCollider.tsx
|
|
4706
|
-
import { useEffect as
|
|
5154
|
+
import { useEffect as useEffect12, useContext as useContext10 } from "react";
|
|
4707
5155
|
function CircleCollider({
|
|
4708
5156
|
radius,
|
|
4709
5157
|
offsetX = 0,
|
|
@@ -4712,9 +5160,9 @@ function CircleCollider({
|
|
|
4712
5160
|
layer = "default",
|
|
4713
5161
|
mask = "*"
|
|
4714
5162
|
}) {
|
|
4715
|
-
const engine =
|
|
4716
|
-
const entityId =
|
|
4717
|
-
|
|
5163
|
+
const engine = useContext10(EngineContext);
|
|
5164
|
+
const entityId = useContext10(EntityContext);
|
|
5165
|
+
useEffect12(() => {
|
|
4718
5166
|
engine.ecs.addComponent(entityId, createCircleCollider(radius, { offsetX, offsetY, isTrigger, layer, mask }));
|
|
4719
5167
|
return () => engine.ecs.removeComponent(entityId, "CircleCollider");
|
|
4720
5168
|
}, []);
|
|
@@ -4722,7 +5170,7 @@ function CircleCollider({
|
|
|
4722
5170
|
}
|
|
4723
5171
|
|
|
4724
5172
|
// src/components/CapsuleCollider.tsx
|
|
4725
|
-
import { useEffect as
|
|
5173
|
+
import { useEffect as useEffect13, useContext as useContext11 } from "react";
|
|
4726
5174
|
function CapsuleCollider({
|
|
4727
5175
|
width,
|
|
4728
5176
|
height,
|
|
@@ -4732,9 +5180,9 @@ function CapsuleCollider({
|
|
|
4732
5180
|
layer = "default",
|
|
4733
5181
|
mask = "*"
|
|
4734
5182
|
}) {
|
|
4735
|
-
const engine =
|
|
4736
|
-
const entityId =
|
|
4737
|
-
|
|
5183
|
+
const engine = useContext11(EngineContext);
|
|
5184
|
+
const entityId = useContext11(EntityContext);
|
|
5185
|
+
useEffect13(() => {
|
|
4738
5186
|
engine.ecs.addComponent(entityId, createCapsuleCollider(width, height, { offsetX, offsetY, isTrigger, layer, mask }));
|
|
4739
5187
|
return () => engine.ecs.removeComponent(entityId, "CapsuleCollider");
|
|
4740
5188
|
}, []);
|
|
@@ -4742,16 +5190,16 @@ function CapsuleCollider({
|
|
|
4742
5190
|
}
|
|
4743
5191
|
|
|
4744
5192
|
// src/components/CompoundCollider.tsx
|
|
4745
|
-
import { useEffect as
|
|
5193
|
+
import { useEffect as useEffect14, useContext as useContext12 } from "react";
|
|
4746
5194
|
function CompoundCollider({
|
|
4747
5195
|
shapes,
|
|
4748
5196
|
isTrigger = false,
|
|
4749
5197
|
layer = "default",
|
|
4750
5198
|
mask = "*"
|
|
4751
5199
|
}) {
|
|
4752
|
-
const engine =
|
|
4753
|
-
const entityId =
|
|
4754
|
-
|
|
5200
|
+
const engine = useContext12(EngineContext);
|
|
5201
|
+
const entityId = useContext12(EntityContext);
|
|
5202
|
+
useEffect14(() => {
|
|
4755
5203
|
engine.ecs.addComponent(entityId, createCompoundCollider(shapes, { isTrigger, layer, mask }));
|
|
4756
5204
|
const checkId = setTimeout(() => {
|
|
4757
5205
|
if (engine.ecs.hasEntity(entityId) && !engine.ecs.hasComponent(entityId, "Transform")) {
|
|
@@ -4767,15 +5215,20 @@ function CompoundCollider({
|
|
|
4767
5215
|
}
|
|
4768
5216
|
|
|
4769
5217
|
// src/components/Script.tsx
|
|
4770
|
-
import { useEffect as
|
|
5218
|
+
import { useEffect as useEffect15, useContext as useContext13, useRef as useRef5 } from "react";
|
|
4771
5219
|
function Script({ init, update }) {
|
|
4772
|
-
const engine =
|
|
4773
|
-
const entityId =
|
|
4774
|
-
|
|
5220
|
+
const engine = useContext13(EngineContext);
|
|
5221
|
+
const entityId = useContext13(EntityContext);
|
|
5222
|
+
if (process.env.NODE_ENV !== "production") {
|
|
5223
|
+
if (entityId === null) {
|
|
5224
|
+
console.warn("[Cubeforge] <Script> must be inside an <Entity>. No EntityContext found.");
|
|
5225
|
+
}
|
|
5226
|
+
}
|
|
5227
|
+
const initRef = useRef5(init);
|
|
4775
5228
|
initRef.current = init;
|
|
4776
|
-
const updateRef =
|
|
5229
|
+
const updateRef = useRef5(update);
|
|
4777
5230
|
updateRef.current = update;
|
|
4778
|
-
|
|
5231
|
+
useEffect15(() => {
|
|
4779
5232
|
if (initRef.current) {
|
|
4780
5233
|
try {
|
|
4781
5234
|
initRef.current(entityId, engine.ecs);
|
|
@@ -4791,7 +5244,7 @@ function Script({ init, update }) {
|
|
|
4791
5244
|
}
|
|
4792
5245
|
|
|
4793
5246
|
// src/components/Camera2D.tsx
|
|
4794
|
-
import { useEffect as
|
|
5247
|
+
import { useEffect as useEffect16, useContext as useContext14 } from "react";
|
|
4795
5248
|
function Camera2D({
|
|
4796
5249
|
followEntity,
|
|
4797
5250
|
x = 0,
|
|
@@ -4804,8 +5257,8 @@ function Camera2D({
|
|
|
4804
5257
|
followOffsetX = 0,
|
|
4805
5258
|
followOffsetY = 0
|
|
4806
5259
|
}) {
|
|
4807
|
-
const engine =
|
|
4808
|
-
|
|
5260
|
+
const engine = useContext14(EngineContext);
|
|
5261
|
+
useEffect16(() => {
|
|
4809
5262
|
const entityId = engine.ecs.createEntity();
|
|
4810
5263
|
engine.ecs.addComponent(entityId, createCamera2D({
|
|
4811
5264
|
followEntityId: followEntity,
|
|
@@ -4821,7 +5274,7 @@ function Camera2D({
|
|
|
4821
5274
|
}));
|
|
4822
5275
|
return () => engine.ecs.destroyEntity(entityId);
|
|
4823
5276
|
}, []);
|
|
4824
|
-
|
|
5277
|
+
useEffect16(() => {
|
|
4825
5278
|
const camId = engine.ecs.queryOne("Camera2D");
|
|
4826
5279
|
if (camId === void 0) return;
|
|
4827
5280
|
const cam = engine.ecs.getComponent(camId, "Camera2D");
|
|
@@ -4840,11 +5293,11 @@ function Camera2D({
|
|
|
4840
5293
|
}
|
|
4841
5294
|
|
|
4842
5295
|
// src/components/Animation.tsx
|
|
4843
|
-
import { useEffect as
|
|
5296
|
+
import { useEffect as useEffect17, useContext as useContext15 } from "react";
|
|
4844
5297
|
function Animation({ frames, fps = 12, loop = true, playing = true, onComplete, frameEvents }) {
|
|
4845
|
-
const engine =
|
|
4846
|
-
const entityId =
|
|
4847
|
-
|
|
5298
|
+
const engine = useContext15(EngineContext);
|
|
5299
|
+
const entityId = useContext15(EntityContext);
|
|
5300
|
+
useEffect17(() => {
|
|
4848
5301
|
const state = {
|
|
4849
5302
|
type: "AnimationState",
|
|
4850
5303
|
frames,
|
|
@@ -4862,7 +5315,7 @@ function Animation({ frames, fps = 12, loop = true, playing = true, onComplete,
|
|
|
4862
5315
|
engine.ecs.removeComponent(entityId, "AnimationState");
|
|
4863
5316
|
};
|
|
4864
5317
|
}, []);
|
|
4865
|
-
|
|
5318
|
+
useEffect17(() => {
|
|
4866
5319
|
const anim = engine.ecs.getComponent(entityId, "AnimationState");
|
|
4867
5320
|
if (!anim) return;
|
|
4868
5321
|
const wasFramesChanged = anim.frames !== frames;
|
|
@@ -4881,12 +5334,104 @@ function Animation({ frames, fps = 12, loop = true, playing = true, onComplete,
|
|
|
4881
5334
|
return null;
|
|
4882
5335
|
}
|
|
4883
5336
|
|
|
5337
|
+
// src/components/AnimatedSprite.tsx
|
|
5338
|
+
import { useMemo } from "react";
|
|
5339
|
+
import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
5340
|
+
function defineAnimations(clips) {
|
|
5341
|
+
return clips;
|
|
5342
|
+
}
|
|
5343
|
+
function AnimatedSprite(props) {
|
|
5344
|
+
const {
|
|
5345
|
+
width,
|
|
5346
|
+
height,
|
|
5347
|
+
src,
|
|
5348
|
+
color,
|
|
5349
|
+
offsetX,
|
|
5350
|
+
offsetY,
|
|
5351
|
+
zIndex,
|
|
5352
|
+
visible,
|
|
5353
|
+
flipX,
|
|
5354
|
+
flipY,
|
|
5355
|
+
anchorX,
|
|
5356
|
+
anchorY,
|
|
5357
|
+
frameWidth,
|
|
5358
|
+
frameHeight,
|
|
5359
|
+
frameColumns,
|
|
5360
|
+
atlas,
|
|
5361
|
+
frame,
|
|
5362
|
+
tileX,
|
|
5363
|
+
tileY,
|
|
5364
|
+
tileSizeX,
|
|
5365
|
+
tileSizeY,
|
|
5366
|
+
sampling,
|
|
5367
|
+
blendMode
|
|
5368
|
+
} = props;
|
|
5369
|
+
const animProps = useResolvedAnimation(props);
|
|
5370
|
+
return /* @__PURE__ */ jsxs3(Fragment3, { children: [
|
|
5371
|
+
/* @__PURE__ */ jsx5(
|
|
5372
|
+
Sprite,
|
|
5373
|
+
{
|
|
5374
|
+
width,
|
|
5375
|
+
height,
|
|
5376
|
+
src,
|
|
5377
|
+
color,
|
|
5378
|
+
offsetX,
|
|
5379
|
+
offsetY,
|
|
5380
|
+
zIndex,
|
|
5381
|
+
visible,
|
|
5382
|
+
flipX,
|
|
5383
|
+
flipY,
|
|
5384
|
+
anchorX,
|
|
5385
|
+
anchorY,
|
|
5386
|
+
frameWidth,
|
|
5387
|
+
frameHeight,
|
|
5388
|
+
frameColumns,
|
|
5389
|
+
atlas,
|
|
5390
|
+
frame,
|
|
5391
|
+
tileX,
|
|
5392
|
+
tileY,
|
|
5393
|
+
tileSizeX,
|
|
5394
|
+
tileSizeY,
|
|
5395
|
+
sampling,
|
|
5396
|
+
blendMode
|
|
5397
|
+
}
|
|
5398
|
+
),
|
|
5399
|
+
/* @__PURE__ */ jsx5(Animation, { ...animProps })
|
|
5400
|
+
] });
|
|
5401
|
+
}
|
|
5402
|
+
function useResolvedAnimation(props) {
|
|
5403
|
+
const clip = props.animations ? props.animations[props.current] ?? Object.values(props.animations)[0] : null;
|
|
5404
|
+
const frames = useMemo(
|
|
5405
|
+
() => clip ? clip.frames : props.frames,
|
|
5406
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
5407
|
+
[clip ? props.current : props.frames]
|
|
5408
|
+
);
|
|
5409
|
+
if (clip) {
|
|
5410
|
+
return {
|
|
5411
|
+
frames,
|
|
5412
|
+
fps: clip.fps,
|
|
5413
|
+
loop: clip.loop,
|
|
5414
|
+
playing: true,
|
|
5415
|
+
onComplete: clip.onComplete,
|
|
5416
|
+
frameEvents: void 0
|
|
5417
|
+
};
|
|
5418
|
+
}
|
|
5419
|
+
return {
|
|
5420
|
+
frames,
|
|
5421
|
+
fps: props.fps,
|
|
5422
|
+
loop: props.loop,
|
|
5423
|
+
playing: props.playing,
|
|
5424
|
+
onComplete: props.onComplete,
|
|
5425
|
+
frameEvents: props.frameEvents
|
|
5426
|
+
};
|
|
5427
|
+
}
|
|
5428
|
+
|
|
4884
5429
|
// src/components/SquashStretch.tsx
|
|
4885
|
-
import { useEffect as
|
|
5430
|
+
import { useEffect as useEffect18, useContext as useContext16 } from "react";
|
|
4886
5431
|
function SquashStretch({ intensity = 0.2, recovery = 8 }) {
|
|
4887
|
-
const engine =
|
|
4888
|
-
const entityId =
|
|
4889
|
-
|
|
5432
|
+
const engine = useContext16(EngineContext);
|
|
5433
|
+
const entityId = useContext16(EntityContext);
|
|
5434
|
+
useEffect18(() => {
|
|
4890
5435
|
engine.ecs.addComponent(entityId, {
|
|
4891
5436
|
type: "SquashStretch",
|
|
4892
5437
|
intensity,
|
|
@@ -4900,7 +5445,7 @@ function SquashStretch({ intensity = 0.2, recovery = 8 }) {
|
|
|
4900
5445
|
}
|
|
4901
5446
|
|
|
4902
5447
|
// src/components/ParticleEmitter.tsx
|
|
4903
|
-
import { useEffect as
|
|
5448
|
+
import { useEffect as useEffect19, useContext as useContext17 } from "react";
|
|
4904
5449
|
|
|
4905
5450
|
// src/components/particlePresets.ts
|
|
4906
5451
|
var PARTICLE_PRESETS = {
|
|
@@ -4973,7 +5518,12 @@ function ParticleEmitter({
|
|
|
4973
5518
|
particleSize,
|
|
4974
5519
|
color,
|
|
4975
5520
|
gravity,
|
|
4976
|
-
maxParticles
|
|
5521
|
+
maxParticles,
|
|
5522
|
+
burstCount,
|
|
5523
|
+
emitShape,
|
|
5524
|
+
emitRadius,
|
|
5525
|
+
emitWidth,
|
|
5526
|
+
emitHeight
|
|
4977
5527
|
}) {
|
|
4978
5528
|
const presetConfig = preset ? PARTICLE_PRESETS[preset] : {};
|
|
4979
5529
|
const resolvedRate = rate ?? presetConfig.rate ?? 20;
|
|
@@ -4985,9 +5535,9 @@ function ParticleEmitter({
|
|
|
4985
5535
|
const resolvedColor = color ?? presetConfig.color ?? "#ffffff";
|
|
4986
5536
|
const resolvedGravity = gravity ?? presetConfig.gravity ?? 200;
|
|
4987
5537
|
const resolvedMaxParticles = maxParticles ?? presetConfig.maxParticles ?? 100;
|
|
4988
|
-
const engine =
|
|
4989
|
-
const entityId =
|
|
4990
|
-
|
|
5538
|
+
const engine = useContext17(EngineContext);
|
|
5539
|
+
const entityId = useContext17(EntityContext);
|
|
5540
|
+
useEffect19(() => {
|
|
4991
5541
|
engine.ecs.addComponent(entityId, {
|
|
4992
5542
|
type: "ParticlePool",
|
|
4993
5543
|
particles: [],
|
|
@@ -5001,11 +5551,16 @@ function ParticleEmitter({
|
|
|
5001
5551
|
particleLife: resolvedParticleLife,
|
|
5002
5552
|
particleSize: resolvedParticleSize,
|
|
5003
5553
|
color: resolvedColor,
|
|
5004
|
-
gravity: resolvedGravity
|
|
5554
|
+
gravity: resolvedGravity,
|
|
5555
|
+
burstCount,
|
|
5556
|
+
emitShape,
|
|
5557
|
+
emitRadius,
|
|
5558
|
+
emitWidth,
|
|
5559
|
+
emitHeight
|
|
5005
5560
|
});
|
|
5006
5561
|
return () => engine.ecs.removeComponent(entityId, "ParticlePool");
|
|
5007
5562
|
}, []);
|
|
5008
|
-
|
|
5563
|
+
useEffect19(() => {
|
|
5009
5564
|
const pool = engine.ecs.getComponent(entityId, "ParticlePool");
|
|
5010
5565
|
if (!pool) return;
|
|
5011
5566
|
pool.active = active;
|
|
@@ -5014,7 +5569,7 @@ function ParticleEmitter({
|
|
|
5014
5569
|
}
|
|
5015
5570
|
|
|
5016
5571
|
// src/components/VirtualJoystick.tsx
|
|
5017
|
-
import { useRef as
|
|
5572
|
+
import { useRef as useRef6 } from "react";
|
|
5018
5573
|
|
|
5019
5574
|
// src/hooks/useVirtualInput.ts
|
|
5020
5575
|
var _axes = { x: 0, y: 0 };
|
|
@@ -5039,7 +5594,7 @@ function useVirtualInput() {
|
|
|
5039
5594
|
}
|
|
5040
5595
|
|
|
5041
5596
|
// src/components/VirtualJoystick.tsx
|
|
5042
|
-
import { Fragment as
|
|
5597
|
+
import { Fragment as Fragment4, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
5043
5598
|
function VirtualJoystick({
|
|
5044
5599
|
size = 120,
|
|
5045
5600
|
position = "left",
|
|
@@ -5048,10 +5603,10 @@ function VirtualJoystick({
|
|
|
5048
5603
|
actionLabel = "A",
|
|
5049
5604
|
actionName = "action"
|
|
5050
5605
|
}) {
|
|
5051
|
-
const baseRef =
|
|
5052
|
-
const stickRef =
|
|
5053
|
-
const activePtr =
|
|
5054
|
-
const baseCenterRef =
|
|
5606
|
+
const baseRef = useRef6(null);
|
|
5607
|
+
const stickRef = useRef6(null);
|
|
5608
|
+
const activePtr = useRef6(null);
|
|
5609
|
+
const baseCenterRef = useRef6({ x: 0, y: 0 });
|
|
5055
5610
|
const radius = size / 2 - 16;
|
|
5056
5611
|
const applyStickPosition = (dx, dy) => {
|
|
5057
5612
|
if (!stickRef.current) return;
|
|
@@ -5096,8 +5651,8 @@ function VirtualJoystick({
|
|
|
5096
5651
|
};
|
|
5097
5652
|
const cornerStyle = position === "left" ? { left: 24, bottom: 24 } : { right: 24, bottom: 24 };
|
|
5098
5653
|
const actionCorner = position === "left" ? { right: 24, bottom: 24 } : { left: 24, bottom: 24 };
|
|
5099
|
-
return /* @__PURE__ */
|
|
5100
|
-
/* @__PURE__ */
|
|
5654
|
+
return /* @__PURE__ */ jsxs4(Fragment4, { children: [
|
|
5655
|
+
/* @__PURE__ */ jsx6(
|
|
5101
5656
|
"div",
|
|
5102
5657
|
{
|
|
5103
5658
|
onPointerDown: handlePointerDown,
|
|
@@ -5118,7 +5673,7 @@ function VirtualJoystick({
|
|
|
5118
5673
|
...style
|
|
5119
5674
|
},
|
|
5120
5675
|
ref: baseRef,
|
|
5121
|
-
children: /* @__PURE__ */
|
|
5676
|
+
children: /* @__PURE__ */ jsx6(
|
|
5122
5677
|
"div",
|
|
5123
5678
|
{
|
|
5124
5679
|
ref: stickRef,
|
|
@@ -5138,7 +5693,7 @@ function VirtualJoystick({
|
|
|
5138
5693
|
)
|
|
5139
5694
|
}
|
|
5140
5695
|
),
|
|
5141
|
-
actionButton && /* @__PURE__ */
|
|
5696
|
+
actionButton && /* @__PURE__ */ jsx6(
|
|
5142
5697
|
"div",
|
|
5143
5698
|
{
|
|
5144
5699
|
onPointerDown: (e) => {
|
|
@@ -5173,7 +5728,7 @@ function VirtualJoystick({
|
|
|
5173
5728
|
}
|
|
5174
5729
|
|
|
5175
5730
|
// src/components/MovingPlatform.tsx
|
|
5176
|
-
import { jsx as
|
|
5731
|
+
import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
5177
5732
|
var platformPhases = /* @__PURE__ */ new Map();
|
|
5178
5733
|
function MovingPlatform({
|
|
5179
5734
|
x1,
|
|
@@ -5185,12 +5740,12 @@ function MovingPlatform({
|
|
|
5185
5740
|
duration = 3,
|
|
5186
5741
|
color = "#37474f"
|
|
5187
5742
|
}) {
|
|
5188
|
-
return /* @__PURE__ */
|
|
5189
|
-
/* @__PURE__ */
|
|
5190
|
-
/* @__PURE__ */
|
|
5191
|
-
/* @__PURE__ */
|
|
5192
|
-
/* @__PURE__ */
|
|
5193
|
-
/* @__PURE__ */
|
|
5743
|
+
return /* @__PURE__ */ jsxs5(Entity, { children: [
|
|
5744
|
+
/* @__PURE__ */ jsx7(Transform, { x: x1, y: y1 }),
|
|
5745
|
+
/* @__PURE__ */ jsx7(Sprite, { width, height, color, zIndex: 5 }),
|
|
5746
|
+
/* @__PURE__ */ jsx7(RigidBody, { isStatic: true }),
|
|
5747
|
+
/* @__PURE__ */ jsx7(BoxCollider, { width, height }),
|
|
5748
|
+
/* @__PURE__ */ jsx7(
|
|
5194
5749
|
Script,
|
|
5195
5750
|
{
|
|
5196
5751
|
init: () => {
|
|
@@ -5212,7 +5767,7 @@ function MovingPlatform({
|
|
|
5212
5767
|
|
|
5213
5768
|
// src/components/Checkpoint.tsx
|
|
5214
5769
|
import { useState as useState4 } from "react";
|
|
5215
|
-
import { jsx as
|
|
5770
|
+
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
5216
5771
|
function CheckpointActivator({ onActivate }) {
|
|
5217
5772
|
const [used, setUsed] = useState4(false);
|
|
5218
5773
|
useTriggerEnter(() => {
|
|
@@ -5230,17 +5785,17 @@ function Checkpoint({
|
|
|
5230
5785
|
color = "#ffd54f",
|
|
5231
5786
|
onActivate
|
|
5232
5787
|
}) {
|
|
5233
|
-
return /* @__PURE__ */
|
|
5234
|
-
/* @__PURE__ */
|
|
5235
|
-
/* @__PURE__ */
|
|
5236
|
-
/* @__PURE__ */
|
|
5237
|
-
/* @__PURE__ */
|
|
5788
|
+
return /* @__PURE__ */ jsxs6(Entity, { tags: ["checkpoint"], children: [
|
|
5789
|
+
/* @__PURE__ */ jsx8(Transform, { x, y }),
|
|
5790
|
+
/* @__PURE__ */ jsx8(Sprite, { width, height, color, zIndex: 5 }),
|
|
5791
|
+
/* @__PURE__ */ jsx8(BoxCollider, { width, height, isTrigger: true }),
|
|
5792
|
+
/* @__PURE__ */ jsx8(CheckpointActivator, { onActivate })
|
|
5238
5793
|
] });
|
|
5239
5794
|
}
|
|
5240
5795
|
|
|
5241
5796
|
// src/components/Tilemap.tsx
|
|
5242
|
-
import { useEffect as
|
|
5243
|
-
import { Fragment as
|
|
5797
|
+
import { useEffect as useEffect20, useState as useState5, useContext as useContext18 } from "react";
|
|
5798
|
+
import { Fragment as Fragment5, jsx as jsx9 } from "react/jsx-runtime";
|
|
5244
5799
|
var animatedTiles = /* @__PURE__ */ new Map();
|
|
5245
5800
|
function getProperty(props, name) {
|
|
5246
5801
|
return props?.find((p) => p.name === name)?.value;
|
|
@@ -5262,11 +5817,12 @@ function Tilemap({
|
|
|
5262
5817
|
collisionLayer = "collision",
|
|
5263
5818
|
triggerLayer: triggerLayerName = "triggers",
|
|
5264
5819
|
onTileProperty,
|
|
5265
|
-
navGrid
|
|
5820
|
+
navGrid,
|
|
5821
|
+
mergeColliders = true
|
|
5266
5822
|
}) {
|
|
5267
|
-
const engine =
|
|
5823
|
+
const engine = useContext18(EngineContext);
|
|
5268
5824
|
const [spawnedNodes, setSpawnedNodes] = useState5([]);
|
|
5269
|
-
|
|
5825
|
+
useEffect20(() => {
|
|
5270
5826
|
if (!engine) return;
|
|
5271
5827
|
const createdEntities = [];
|
|
5272
5828
|
async function load() {
|
|
@@ -5334,32 +5890,54 @@ function Tilemap({
|
|
|
5334
5890
|
}
|
|
5335
5891
|
}
|
|
5336
5892
|
if (collision || trigger) {
|
|
5337
|
-
|
|
5338
|
-
|
|
5339
|
-
|
|
5340
|
-
|
|
5341
|
-
|
|
5342
|
-
|
|
5343
|
-
col++;
|
|
5344
|
-
continue;
|
|
5893
|
+
if (mergeColliders) {
|
|
5894
|
+
const solidGrid = [];
|
|
5895
|
+
for (let row = 0; row < mapData.height; row++) {
|
|
5896
|
+
solidGrid[row] = [];
|
|
5897
|
+
for (let col = 0; col < mapData.width; col++) {
|
|
5898
|
+
solidGrid[row][col] = layer.data[row * mapData.width + col] !== 0;
|
|
5345
5899
|
}
|
|
5346
|
-
|
|
5347
|
-
|
|
5348
|
-
|
|
5349
|
-
}
|
|
5350
|
-
const runWidth = runLength * tilewidth;
|
|
5351
|
-
const x = col * tilewidth + runWidth / 2;
|
|
5352
|
-
const y = row * tileheight + tileheight / 2;
|
|
5900
|
+
}
|
|
5901
|
+
const merged = mergeTileColliders(solidGrid, tilewidth, tileheight, 0, 0);
|
|
5902
|
+
for (const rect of merged) {
|
|
5353
5903
|
const eid = engine.ecs.createEntity();
|
|
5354
5904
|
createdEntities.push(eid);
|
|
5355
|
-
engine.ecs.addComponent(eid, createTransform(x, y));
|
|
5905
|
+
engine.ecs.addComponent(eid, createTransform(rect.x, rect.y));
|
|
5356
5906
|
if (collision) {
|
|
5357
5907
|
engine.ecs.addComponent(eid, createRigidBody({ isStatic: true }));
|
|
5358
|
-
engine.ecs.addComponent(eid, createBoxCollider(
|
|
5908
|
+
engine.ecs.addComponent(eid, createBoxCollider(rect.width, rect.height));
|
|
5359
5909
|
} else {
|
|
5360
|
-
engine.ecs.addComponent(eid, createBoxCollider(
|
|
5910
|
+
engine.ecs.addComponent(eid, createBoxCollider(rect.width, rect.height, { isTrigger: true }));
|
|
5911
|
+
}
|
|
5912
|
+
}
|
|
5913
|
+
} else {
|
|
5914
|
+
for (let row = 0; row < mapData.height; row++) {
|
|
5915
|
+
let col = 0;
|
|
5916
|
+
while (col < mapData.width) {
|
|
5917
|
+
const i = row * mapData.width + col;
|
|
5918
|
+
const gid = layer.data[i];
|
|
5919
|
+
if (gid === 0) {
|
|
5920
|
+
col++;
|
|
5921
|
+
continue;
|
|
5922
|
+
}
|
|
5923
|
+
let runLength = 1;
|
|
5924
|
+
while (col + runLength < mapData.width && layer.data[row * mapData.width + col + runLength] !== 0) {
|
|
5925
|
+
runLength++;
|
|
5926
|
+
}
|
|
5927
|
+
const runWidth = runLength * tilewidth;
|
|
5928
|
+
const x = col * tilewidth + runWidth / 2;
|
|
5929
|
+
const y = row * tileheight + tileheight / 2;
|
|
5930
|
+
const eid = engine.ecs.createEntity();
|
|
5931
|
+
createdEntities.push(eid);
|
|
5932
|
+
engine.ecs.addComponent(eid, createTransform(x, y));
|
|
5933
|
+
if (collision) {
|
|
5934
|
+
engine.ecs.addComponent(eid, createRigidBody({ isStatic: true }));
|
|
5935
|
+
engine.ecs.addComponent(eid, createBoxCollider(runWidth, tileheight));
|
|
5936
|
+
} else {
|
|
5937
|
+
engine.ecs.addComponent(eid, createBoxCollider(runWidth, tileheight, { isTrigger: true }));
|
|
5938
|
+
}
|
|
5939
|
+
col += runLength;
|
|
5361
5940
|
}
|
|
5362
|
-
col += runLength;
|
|
5363
5941
|
}
|
|
5364
5942
|
}
|
|
5365
5943
|
} else {
|
|
@@ -5453,12 +6031,12 @@ function Tilemap({
|
|
|
5453
6031
|
};
|
|
5454
6032
|
}, [src]);
|
|
5455
6033
|
if (spawnedNodes.length === 0) return null;
|
|
5456
|
-
return /* @__PURE__ */
|
|
6034
|
+
return /* @__PURE__ */ jsx9(Fragment5, { children: spawnedNodes });
|
|
5457
6035
|
}
|
|
5458
6036
|
|
|
5459
6037
|
// src/components/ParallaxLayer.tsx
|
|
5460
|
-
import { useEffect as
|
|
5461
|
-
import { jsx as
|
|
6038
|
+
import { useEffect as useEffect21, useContext as useContext19 } from "react";
|
|
6039
|
+
import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
5462
6040
|
function ParallaxLayerInner({
|
|
5463
6041
|
src,
|
|
5464
6042
|
speedX,
|
|
@@ -5469,9 +6047,9 @@ function ParallaxLayerInner({
|
|
|
5469
6047
|
offsetX,
|
|
5470
6048
|
offsetY
|
|
5471
6049
|
}) {
|
|
5472
|
-
const engine =
|
|
5473
|
-
const entityId =
|
|
5474
|
-
|
|
6050
|
+
const engine = useContext19(EngineContext);
|
|
6051
|
+
const entityId = useContext19(EntityContext);
|
|
6052
|
+
useEffect21(() => {
|
|
5475
6053
|
engine.ecs.addComponent(entityId, {
|
|
5476
6054
|
type: "ParallaxLayer",
|
|
5477
6055
|
src,
|
|
@@ -5487,7 +6065,7 @@ function ParallaxLayerInner({
|
|
|
5487
6065
|
});
|
|
5488
6066
|
return () => engine.ecs.removeComponent(entityId, "ParallaxLayer");
|
|
5489
6067
|
}, []);
|
|
5490
|
-
|
|
6068
|
+
useEffect21(() => {
|
|
5491
6069
|
const layer = engine.ecs.getComponent(entityId, "ParallaxLayer");
|
|
5492
6070
|
if (!layer) return;
|
|
5493
6071
|
layer.src = src;
|
|
@@ -5511,9 +6089,9 @@ function ParallaxLayer({
|
|
|
5511
6089
|
offsetX = 0,
|
|
5512
6090
|
offsetY = 0
|
|
5513
6091
|
}) {
|
|
5514
|
-
return /* @__PURE__ */
|
|
5515
|
-
/* @__PURE__ */
|
|
5516
|
-
/* @__PURE__ */
|
|
6092
|
+
return /* @__PURE__ */ jsxs7(Entity, { children: [
|
|
6093
|
+
/* @__PURE__ */ jsx10(Transform, { x: 0, y: 0 }),
|
|
6094
|
+
/* @__PURE__ */ jsx10(
|
|
5517
6095
|
ParallaxLayerInner,
|
|
5518
6096
|
{
|
|
5519
6097
|
src,
|
|
@@ -5530,10 +6108,10 @@ function ParallaxLayer({
|
|
|
5530
6108
|
}
|
|
5531
6109
|
|
|
5532
6110
|
// src/components/ScreenFlash.tsx
|
|
5533
|
-
import { forwardRef, useImperativeHandle, useRef as
|
|
5534
|
-
import { jsx as
|
|
6111
|
+
import { forwardRef, useImperativeHandle, useRef as useRef7 } from "react";
|
|
6112
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
5535
6113
|
var ScreenFlash = forwardRef((_, ref) => {
|
|
5536
|
-
const divRef =
|
|
6114
|
+
const divRef = useRef7(null);
|
|
5537
6115
|
useImperativeHandle(ref, () => ({
|
|
5538
6116
|
flash(color, duration) {
|
|
5539
6117
|
const el = divRef.current;
|
|
@@ -5551,7 +6129,7 @@ var ScreenFlash = forwardRef((_, ref) => {
|
|
|
5551
6129
|
});
|
|
5552
6130
|
}
|
|
5553
6131
|
}));
|
|
5554
|
-
return /* @__PURE__ */
|
|
6132
|
+
return /* @__PURE__ */ jsx11(
|
|
5555
6133
|
"div",
|
|
5556
6134
|
{
|
|
5557
6135
|
ref: divRef,
|
|
@@ -5569,8 +6147,8 @@ var ScreenFlash = forwardRef((_, ref) => {
|
|
|
5569
6147
|
ScreenFlash.displayName = "ScreenFlash";
|
|
5570
6148
|
|
|
5571
6149
|
// src/components/CameraZone.tsx
|
|
5572
|
-
import { useEffect as
|
|
5573
|
-
import { Fragment as
|
|
6150
|
+
import { useEffect as useEffect22, useContext as useContext20, useRef as useRef8 } from "react";
|
|
6151
|
+
import { Fragment as Fragment6, jsx as jsx12 } from "react/jsx-runtime";
|
|
5574
6152
|
function CameraZone({
|
|
5575
6153
|
x,
|
|
5576
6154
|
y,
|
|
@@ -5581,10 +6159,10 @@ function CameraZone({
|
|
|
5581
6159
|
targetY,
|
|
5582
6160
|
children
|
|
5583
6161
|
}) {
|
|
5584
|
-
const engine =
|
|
5585
|
-
const prevFollowRef =
|
|
5586
|
-
const activeRef =
|
|
5587
|
-
|
|
6162
|
+
const engine = useContext20(EngineContext);
|
|
6163
|
+
const prevFollowRef = useRef8(void 0);
|
|
6164
|
+
const activeRef = useRef8(false);
|
|
6165
|
+
useEffect22(() => {
|
|
5588
6166
|
const eid = engine.ecs.createEntity();
|
|
5589
6167
|
engine.ecs.addComponent(eid, createScript(() => {
|
|
5590
6168
|
const cam = engine.ecs.queryOne("Camera2D");
|
|
@@ -5627,15 +6205,15 @@ function CameraZone({
|
|
|
5627
6205
|
if (engine.ecs.hasEntity(eid)) engine.ecs.destroyEntity(eid);
|
|
5628
6206
|
};
|
|
5629
6207
|
}, [engine.ecs, x, y, width, height, watchTag, targetX, targetY]);
|
|
5630
|
-
return /* @__PURE__ */
|
|
6208
|
+
return /* @__PURE__ */ jsx12(Fragment6, { children: children ?? null });
|
|
5631
6209
|
}
|
|
5632
6210
|
|
|
5633
6211
|
// src/components/Trail.tsx
|
|
5634
|
-
import { useEffect as
|
|
6212
|
+
import { useEffect as useEffect23, useContext as useContext21 } from "react";
|
|
5635
6213
|
function Trail({ length = 20, color = "#ffffff", width = 3 }) {
|
|
5636
|
-
const engine =
|
|
5637
|
-
const entityId =
|
|
5638
|
-
|
|
6214
|
+
const engine = useContext21(EngineContext);
|
|
6215
|
+
const entityId = useContext21(EntityContext);
|
|
6216
|
+
useEffect23(() => {
|
|
5639
6217
|
engine.ecs.addComponent(entityId, createTrail({ length, color, width }));
|
|
5640
6218
|
return () => engine.ecs.removeComponent(entityId, "Trail");
|
|
5641
6219
|
}, []);
|
|
@@ -5643,7 +6221,7 @@ function Trail({ length = 20, color = "#ffffff", width = 3 }) {
|
|
|
5643
6221
|
}
|
|
5644
6222
|
|
|
5645
6223
|
// src/components/NineSlice.tsx
|
|
5646
|
-
import { useEffect as
|
|
6224
|
+
import { useEffect as useEffect24, useContext as useContext22 } from "react";
|
|
5647
6225
|
function NineSlice({
|
|
5648
6226
|
src,
|
|
5649
6227
|
width,
|
|
@@ -5654,9 +6232,9 @@ function NineSlice({
|
|
|
5654
6232
|
borderLeft = 8,
|
|
5655
6233
|
zIndex = 0
|
|
5656
6234
|
}) {
|
|
5657
|
-
const engine =
|
|
5658
|
-
const entityId =
|
|
5659
|
-
|
|
6235
|
+
const engine = useContext22(EngineContext);
|
|
6236
|
+
const entityId = useContext22(EntityContext);
|
|
6237
|
+
useEffect24(() => {
|
|
5660
6238
|
engine.ecs.addComponent(
|
|
5661
6239
|
entityId,
|
|
5662
6240
|
createNineSlice(src, width, height, {
|
|
@@ -5673,14 +6251,14 @@ function NineSlice({
|
|
|
5673
6251
|
}
|
|
5674
6252
|
|
|
5675
6253
|
// src/components/AssetLoader.tsx
|
|
5676
|
-
import { useEffect as
|
|
6254
|
+
import { useEffect as useEffect26 } from "react";
|
|
5677
6255
|
|
|
5678
6256
|
// src/hooks/usePreload.ts
|
|
5679
|
-
import { useState as useState6, useEffect as
|
|
6257
|
+
import { useState as useState6, useEffect as useEffect25, useContext as useContext23 } from "react";
|
|
5680
6258
|
function usePreload(assets) {
|
|
5681
|
-
const engine =
|
|
6259
|
+
const engine = useContext23(EngineContext);
|
|
5682
6260
|
const [state, setState] = useState6({ progress: assets.length === 0 ? 1 : 0, loaded: assets.length === 0, error: null });
|
|
5683
|
-
|
|
6261
|
+
useEffect25(() => {
|
|
5684
6262
|
if (assets.length === 0) {
|
|
5685
6263
|
setState({ progress: 1, loaded: true, error: null });
|
|
5686
6264
|
return;
|
|
@@ -5708,31 +6286,31 @@ function usePreload(assets) {
|
|
|
5708
6286
|
}
|
|
5709
6287
|
|
|
5710
6288
|
// src/components/AssetLoader.tsx
|
|
5711
|
-
import { Fragment as
|
|
6289
|
+
import { Fragment as Fragment7, jsx as jsx13 } from "react/jsx-runtime";
|
|
5712
6290
|
function AssetLoader({ assets, fallback = null, onError, children }) {
|
|
5713
6291
|
const { loaded, error } = usePreload(assets);
|
|
5714
|
-
|
|
6292
|
+
useEffect26(() => {
|
|
5715
6293
|
if (error && onError) onError(error);
|
|
5716
6294
|
}, [error, onError]);
|
|
5717
6295
|
if (!loaded) {
|
|
5718
|
-
return /* @__PURE__ */
|
|
6296
|
+
return /* @__PURE__ */ jsx13(Fragment7, { children: fallback });
|
|
5719
6297
|
}
|
|
5720
|
-
return /* @__PURE__ */
|
|
6298
|
+
return /* @__PURE__ */ jsx13(Fragment7, { children });
|
|
5721
6299
|
}
|
|
5722
6300
|
|
|
5723
6301
|
// src/hooks/useGame.ts
|
|
5724
|
-
import { useContext as
|
|
6302
|
+
import { useContext as useContext24 } from "react";
|
|
5725
6303
|
function useGame() {
|
|
5726
|
-
const engine =
|
|
6304
|
+
const engine = useContext24(EngineContext);
|
|
5727
6305
|
if (!engine) throw new Error("useGame must be used inside <Game>");
|
|
5728
6306
|
return engine;
|
|
5729
6307
|
}
|
|
5730
6308
|
|
|
5731
6309
|
// src/hooks/useCamera.ts
|
|
5732
|
-
import { useMemo } from "react";
|
|
6310
|
+
import { useMemo as useMemo2 } from "react";
|
|
5733
6311
|
function useCamera() {
|
|
5734
6312
|
const engine = useGame();
|
|
5735
|
-
return
|
|
6313
|
+
return useMemo2(() => ({
|
|
5736
6314
|
shake(intensity, duration) {
|
|
5737
6315
|
const cams = engine.ecs.query("Camera2D");
|
|
5738
6316
|
if (cams.length === 0) return;
|
|
@@ -5770,28 +6348,28 @@ function useCamera() {
|
|
|
5770
6348
|
}
|
|
5771
6349
|
|
|
5772
6350
|
// src/hooks/useSnapshot.ts
|
|
5773
|
-
import { useMemo as
|
|
6351
|
+
import { useMemo as useMemo3 } from "react";
|
|
5774
6352
|
function useSnapshot() {
|
|
5775
6353
|
const engine = useGame();
|
|
5776
|
-
return
|
|
6354
|
+
return useMemo3(() => ({
|
|
5777
6355
|
save: () => engine.ecs.getSnapshot(),
|
|
5778
6356
|
restore: (snapshot) => engine.ecs.restoreSnapshot(snapshot)
|
|
5779
6357
|
}), [engine]);
|
|
5780
6358
|
}
|
|
5781
6359
|
|
|
5782
6360
|
// src/hooks/useEntity.ts
|
|
5783
|
-
import { useContext as
|
|
6361
|
+
import { useContext as useContext25 } from "react";
|
|
5784
6362
|
function useEntity() {
|
|
5785
|
-
const id =
|
|
6363
|
+
const id = useContext25(EntityContext);
|
|
5786
6364
|
if (id === null) throw new Error("useEntity must be used inside <Entity>");
|
|
5787
6365
|
return id;
|
|
5788
6366
|
}
|
|
5789
6367
|
|
|
5790
6368
|
// src/hooks/useDestroyEntity.ts
|
|
5791
|
-
import { useCallback as useCallback2, useContext as
|
|
6369
|
+
import { useCallback as useCallback2, useContext as useContext26 } from "react";
|
|
5792
6370
|
function useDestroyEntity() {
|
|
5793
|
-
const engine =
|
|
5794
|
-
const entityId =
|
|
6371
|
+
const engine = useContext26(EngineContext);
|
|
6372
|
+
const entityId = useContext26(EntityContext);
|
|
5795
6373
|
if (!engine) throw new Error("useDestroyEntity must be used inside <Game>");
|
|
5796
6374
|
if (entityId === null) throw new Error("useDestroyEntity must be used inside <Entity>");
|
|
5797
6375
|
return useCallback2(() => {
|
|
@@ -5802,19 +6380,19 @@ function useDestroyEntity() {
|
|
|
5802
6380
|
}
|
|
5803
6381
|
|
|
5804
6382
|
// src/hooks/useInput.ts
|
|
5805
|
-
import { useContext as
|
|
6383
|
+
import { useContext as useContext27 } from "react";
|
|
5806
6384
|
function useInput() {
|
|
5807
|
-
const engine =
|
|
6385
|
+
const engine = useContext27(EngineContext);
|
|
5808
6386
|
if (!engine) throw new Error("useInput must be used inside <Game>");
|
|
5809
6387
|
return engine.input;
|
|
5810
6388
|
}
|
|
5811
6389
|
|
|
5812
6390
|
// src/hooks/useInputMap.ts
|
|
5813
|
-
import { useMemo as
|
|
6391
|
+
import { useMemo as useMemo4 } from "react";
|
|
5814
6392
|
function useInputMap(bindings) {
|
|
5815
6393
|
const input = useInput();
|
|
5816
|
-
const map =
|
|
5817
|
-
return
|
|
6394
|
+
const map = useMemo4(() => createInputMap(bindings), [JSON.stringify(bindings)]);
|
|
6395
|
+
return useMemo4(() => ({
|
|
5818
6396
|
isActionDown: (action) => map.isActionDown(input, action),
|
|
5819
6397
|
isActionPressed: (action) => map.isActionPressed(input, action),
|
|
5820
6398
|
isActionReleased: (action) => map.isActionReleased(input, action),
|
|
@@ -5824,25 +6402,25 @@ function useInputMap(bindings) {
|
|
|
5824
6402
|
}
|
|
5825
6403
|
|
|
5826
6404
|
// src/hooks/useEvents.ts
|
|
5827
|
-
import { useContext as
|
|
6405
|
+
import { useContext as useContext28, useEffect as useEffect27, useRef as useRef9 } from "react";
|
|
5828
6406
|
function useEvents() {
|
|
5829
|
-
const engine =
|
|
6407
|
+
const engine = useContext28(EngineContext);
|
|
5830
6408
|
if (!engine) throw new Error("useEvents must be used inside <Game>");
|
|
5831
6409
|
return engine.events;
|
|
5832
6410
|
}
|
|
5833
6411
|
function useEvent(event, handler) {
|
|
5834
6412
|
const events = useEvents();
|
|
5835
|
-
const handlerRef =
|
|
6413
|
+
const handlerRef = useRef9(handler);
|
|
5836
6414
|
handlerRef.current = handler;
|
|
5837
|
-
|
|
6415
|
+
useEffect27(() => {
|
|
5838
6416
|
return events.on(event, (data) => handlerRef.current(data));
|
|
5839
6417
|
}, [events, event]);
|
|
5840
6418
|
}
|
|
5841
6419
|
|
|
5842
6420
|
// src/hooks/useCoordinates.ts
|
|
5843
|
-
import { useCallback as useCallback3, useContext as
|
|
6421
|
+
import { useCallback as useCallback3, useContext as useContext29 } from "react";
|
|
5844
6422
|
function useCoordinates() {
|
|
5845
|
-
const engine =
|
|
6423
|
+
const engine = useContext29(EngineContext);
|
|
5846
6424
|
const worldToScreen = useCallback3((wx, wy) => {
|
|
5847
6425
|
const canvas = engine.canvas;
|
|
5848
6426
|
const camId = engine.ecs.queryOne("Camera2D");
|
|
@@ -5869,14 +6447,14 @@ function useCoordinates() {
|
|
|
5869
6447
|
}
|
|
5870
6448
|
|
|
5871
6449
|
// src/hooks/useInputContext.ts
|
|
5872
|
-
import { useEffect as
|
|
6450
|
+
import { useEffect as useEffect28, useMemo as useMemo5 } from "react";
|
|
5873
6451
|
function useInputContext(ctx) {
|
|
5874
|
-
|
|
6452
|
+
useEffect28(() => {
|
|
5875
6453
|
if (!ctx) return;
|
|
5876
6454
|
globalInputContext.push(ctx);
|
|
5877
6455
|
return () => globalInputContext.pop(ctx);
|
|
5878
6456
|
}, [ctx]);
|
|
5879
|
-
return
|
|
6457
|
+
return useMemo5(() => ({
|
|
5880
6458
|
push: (c) => globalInputContext.push(c),
|
|
5881
6459
|
pop: (c) => globalInputContext.pop(c),
|
|
5882
6460
|
get active() {
|
|
@@ -5886,17 +6464,17 @@ function useInputContext(ctx) {
|
|
|
5886
6464
|
}
|
|
5887
6465
|
|
|
5888
6466
|
// src/hooks/usePlayerInput.ts
|
|
5889
|
-
import { useMemo as
|
|
6467
|
+
import { useMemo as useMemo6 } from "react";
|
|
5890
6468
|
function usePlayerInput(playerId, bindings) {
|
|
5891
6469
|
const input = useInput();
|
|
5892
|
-
return
|
|
6470
|
+
return useMemo6(() => createPlayerInput(playerId, bindings, input), [playerId, input, JSON.stringify(bindings)]);
|
|
5893
6471
|
}
|
|
5894
6472
|
|
|
5895
6473
|
// src/hooks/useLocalMultiplayer.ts
|
|
5896
|
-
import { useMemo as
|
|
6474
|
+
import { useMemo as useMemo7 } from "react";
|
|
5897
6475
|
function useLocalMultiplayer(bindingsPerPlayer) {
|
|
5898
6476
|
const input = useInput();
|
|
5899
|
-
return
|
|
6477
|
+
return useMemo7(
|
|
5900
6478
|
() => bindingsPerPlayer.map((bindings, i) => createPlayerInput(i + 1, bindings, input)),
|
|
5901
6479
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
5902
6480
|
[input, JSON.stringify(bindingsPerPlayer)]
|
|
@@ -5904,18 +6482,18 @@ function useLocalMultiplayer(bindingsPerPlayer) {
|
|
|
5904
6482
|
}
|
|
5905
6483
|
|
|
5906
6484
|
// src/hooks/useInputRecorder.ts
|
|
5907
|
-
import { useMemo as
|
|
6485
|
+
import { useMemo as useMemo8 } from "react";
|
|
5908
6486
|
function useInputRecorder() {
|
|
5909
|
-
return
|
|
6487
|
+
return useMemo8(() => createInputRecorder(), []);
|
|
5910
6488
|
}
|
|
5911
6489
|
|
|
5912
6490
|
// src/hooks/useGamepad.ts
|
|
5913
|
-
import { useEffect as
|
|
6491
|
+
import { useEffect as useEffect29, useRef as useRef10, useState as useState7 } from "react";
|
|
5914
6492
|
var EMPTY_STATE = { connected: false, axes: [], buttons: [] };
|
|
5915
6493
|
function useGamepad(playerIndex = 0) {
|
|
5916
6494
|
const [state, setState] = useState7(EMPTY_STATE);
|
|
5917
|
-
const rafRef =
|
|
5918
|
-
|
|
6495
|
+
const rafRef = useRef10(0);
|
|
6496
|
+
useEffect29(() => {
|
|
5919
6497
|
const poll = () => {
|
|
5920
6498
|
const gp = navigator.getGamepads()[playerIndex];
|
|
5921
6499
|
if (gp) {
|
|
@@ -5936,9 +6514,9 @@ function useGamepad(playerIndex = 0) {
|
|
|
5936
6514
|
}
|
|
5937
6515
|
|
|
5938
6516
|
// src/hooks/usePause.ts
|
|
5939
|
-
import { useContext as
|
|
6517
|
+
import { useContext as useContext30, useState as useState8, useCallback as useCallback4 } from "react";
|
|
5940
6518
|
function usePause() {
|
|
5941
|
-
const engine =
|
|
6519
|
+
const engine = useContext30(EngineContext);
|
|
5942
6520
|
const [paused, setPaused] = useState8(false);
|
|
5943
6521
|
const pause = useCallback4(() => {
|
|
5944
6522
|
engine.loop.pause();
|
|
@@ -5955,10 +6533,75 @@ function usePause() {
|
|
|
5955
6533
|
return { paused, pause, resume, toggle };
|
|
5956
6534
|
}
|
|
5957
6535
|
|
|
6536
|
+
// src/hooks/useProfiler.ts
|
|
6537
|
+
import { useContext as useContext31, useEffect as useEffect30, useRef as useRef11, useState as useState9 } from "react";
|
|
6538
|
+
var EMPTY = {
|
|
6539
|
+
fps: 0,
|
|
6540
|
+
frameTime: 0,
|
|
6541
|
+
entityCount: 0,
|
|
6542
|
+
systemTimings: /* @__PURE__ */ new Map()
|
|
6543
|
+
};
|
|
6544
|
+
function useProfiler() {
|
|
6545
|
+
const engine = useContext31(EngineContext);
|
|
6546
|
+
const [data, setData] = useState9(EMPTY);
|
|
6547
|
+
const frameTimesRef = useRef11([]);
|
|
6548
|
+
const lastUpdateRef = useRef11(0);
|
|
6549
|
+
const prevTimeRef = useRef11(0);
|
|
6550
|
+
useEffect30(() => {
|
|
6551
|
+
if (!engine) return;
|
|
6552
|
+
let rafId;
|
|
6553
|
+
const frameTimes = frameTimesRef.current;
|
|
6554
|
+
const sample = (now) => {
|
|
6555
|
+
if (prevTimeRef.current > 0) {
|
|
6556
|
+
frameTimes.push(now - prevTimeRef.current);
|
|
6557
|
+
}
|
|
6558
|
+
prevTimeRef.current = now;
|
|
6559
|
+
if (now - lastUpdateRef.current >= 500) {
|
|
6560
|
+
lastUpdateRef.current = now;
|
|
6561
|
+
let fps = 0;
|
|
6562
|
+
let avgFrameTime = 0;
|
|
6563
|
+
if (frameTimes.length > 0) {
|
|
6564
|
+
const sum = frameTimes.reduce((a, b) => a + b, 0);
|
|
6565
|
+
avgFrameTime = sum / frameTimes.length;
|
|
6566
|
+
fps = avgFrameTime > 0 ? 1e3 / avgFrameTime : 0;
|
|
6567
|
+
frameTimes.length = 0;
|
|
6568
|
+
}
|
|
6569
|
+
setData({
|
|
6570
|
+
fps: Math.round(fps * 10) / 10,
|
|
6571
|
+
frameTime: Math.round(avgFrameTime * 100) / 100,
|
|
6572
|
+
entityCount: engine.ecs.entityCount,
|
|
6573
|
+
systemTimings: new Map(engine.systemTimings)
|
|
6574
|
+
});
|
|
6575
|
+
}
|
|
6576
|
+
rafId = requestAnimationFrame(sample);
|
|
6577
|
+
};
|
|
6578
|
+
rafId = requestAnimationFrame(sample);
|
|
6579
|
+
return () => {
|
|
6580
|
+
cancelAnimationFrame(rafId);
|
|
6581
|
+
frameTimes.length = 0;
|
|
6582
|
+
prevTimeRef.current = 0;
|
|
6583
|
+
lastUpdateRef.current = 0;
|
|
6584
|
+
};
|
|
6585
|
+
}, [engine]);
|
|
6586
|
+
return data;
|
|
6587
|
+
}
|
|
6588
|
+
|
|
6589
|
+
// src/hooks/usePostProcess.ts
|
|
6590
|
+
import { useEffect as useEffect31 } from "react";
|
|
6591
|
+
function usePostProcess(effect) {
|
|
6592
|
+
const engine = useGame();
|
|
6593
|
+
useEffect31(() => {
|
|
6594
|
+
engine.postProcessStack.add(effect);
|
|
6595
|
+
return () => {
|
|
6596
|
+
engine.postProcessStack.remove(effect);
|
|
6597
|
+
};
|
|
6598
|
+
}, [engine, effect]);
|
|
6599
|
+
}
|
|
6600
|
+
|
|
5958
6601
|
// ../gameplay/src/hooks/useAnimationController.ts
|
|
5959
|
-
import { useState as
|
|
6602
|
+
import { useState as useState10, useCallback as useCallback5 } from "react";
|
|
5960
6603
|
function useAnimationController(states, initial) {
|
|
5961
|
-
const [stateName, setStateName] =
|
|
6604
|
+
const [stateName, setStateName] = useState10(initial);
|
|
5962
6605
|
const setState = useCallback5((next) => {
|
|
5963
6606
|
setStateName((prev) => prev === next ? prev : next);
|
|
5964
6607
|
}, []);
|
|
@@ -6007,19 +6650,19 @@ function useAISteering() {
|
|
|
6007
6650
|
}
|
|
6008
6651
|
|
|
6009
6652
|
// ../gameplay/src/hooks/useDamageZone.ts
|
|
6010
|
-
import { useContext as
|
|
6653
|
+
import { useContext as useContext32 } from "react";
|
|
6011
6654
|
function useDamageZone(damage, opts = {}) {
|
|
6012
|
-
const engine =
|
|
6655
|
+
const engine = useContext32(EngineContext);
|
|
6013
6656
|
useTriggerEnter((other) => {
|
|
6014
6657
|
engine.events.emit(`damage:${other}`, { amount: damage });
|
|
6015
6658
|
}, { tag: opts.tag, layer: opts.layer });
|
|
6016
6659
|
}
|
|
6017
6660
|
|
|
6018
6661
|
// ../gameplay/src/hooks/useDropThrough.ts
|
|
6019
|
-
import { useContext as
|
|
6662
|
+
import { useContext as useContext33, useCallback as useCallback7 } from "react";
|
|
6020
6663
|
function useDropThrough(frames = 8) {
|
|
6021
|
-
const engine =
|
|
6022
|
-
const entityId =
|
|
6664
|
+
const engine = useContext33(EngineContext);
|
|
6665
|
+
const entityId = useContext33(EntityContext);
|
|
6023
6666
|
const dropThrough = useCallback7(() => {
|
|
6024
6667
|
const rb = engine.ecs.getComponent(entityId, "RigidBody");
|
|
6025
6668
|
if (rb) rb.dropThrough = frames;
|
|
@@ -6028,14 +6671,14 @@ function useDropThrough(frames = 8) {
|
|
|
6028
6671
|
}
|
|
6029
6672
|
|
|
6030
6673
|
// ../gameplay/src/hooks/useGameStateMachine.ts
|
|
6031
|
-
import { useState as
|
|
6674
|
+
import { useState as useState11, useRef as useRef12, useCallback as useCallback8, useEffect as useEffect32, useContext as useContext34 } from "react";
|
|
6032
6675
|
function useGameStateMachine(states, initial) {
|
|
6033
|
-
const engine =
|
|
6034
|
-
const [state, setState] =
|
|
6035
|
-
const stateRef =
|
|
6036
|
-
const statesRef =
|
|
6676
|
+
const engine = useContext34(EngineContext);
|
|
6677
|
+
const [state, setState] = useState11(initial);
|
|
6678
|
+
const stateRef = useRef12(initial);
|
|
6679
|
+
const statesRef = useRef12(states);
|
|
6037
6680
|
statesRef.current = states;
|
|
6038
|
-
|
|
6681
|
+
useEffect32(() => {
|
|
6039
6682
|
statesRef.current[initial]?.onEnter?.();
|
|
6040
6683
|
}, []);
|
|
6041
6684
|
const transition = useCallback8((to) => {
|
|
@@ -6046,7 +6689,7 @@ function useGameStateMachine(states, initial) {
|
|
|
6046
6689
|
setState(to);
|
|
6047
6690
|
statesRef.current[to]?.onEnter?.();
|
|
6048
6691
|
}, []);
|
|
6049
|
-
|
|
6692
|
+
useEffect32(() => {
|
|
6050
6693
|
const eid = engine.ecs.createEntity();
|
|
6051
6694
|
engine.ecs.addComponent(eid, createScript((_id, _world, _input, dt) => {
|
|
6052
6695
|
statesRef.current[stateRef.current]?.onUpdate?.(dt);
|
|
@@ -6059,22 +6702,22 @@ function useGameStateMachine(states, initial) {
|
|
|
6059
6702
|
}
|
|
6060
6703
|
|
|
6061
6704
|
// ../gameplay/src/hooks/useHealth.ts
|
|
6062
|
-
import { useRef as
|
|
6705
|
+
import { useRef as useRef13, useEffect as useEffect33, useContext as useContext35, useCallback as useCallback9 } from "react";
|
|
6063
6706
|
function useHealth(maxHp, opts = {}) {
|
|
6064
|
-
const engine =
|
|
6065
|
-
const entityId =
|
|
6066
|
-
const hpRef =
|
|
6067
|
-
const invincibleRef =
|
|
6707
|
+
const engine = useContext35(EngineContext);
|
|
6708
|
+
const entityId = useContext35(EntityContext);
|
|
6709
|
+
const hpRef = useRef13(maxHp);
|
|
6710
|
+
const invincibleRef = useRef13(false);
|
|
6068
6711
|
const iFrameDuration = opts.iFrames ?? 1;
|
|
6069
|
-
const onDeathRef =
|
|
6070
|
-
const onDamageRef =
|
|
6071
|
-
|
|
6712
|
+
const onDeathRef = useRef13(opts.onDeath);
|
|
6713
|
+
const onDamageRef = useRef13(opts.onDamage);
|
|
6714
|
+
useEffect33(() => {
|
|
6072
6715
|
onDeathRef.current = opts.onDeath;
|
|
6073
6716
|
});
|
|
6074
|
-
|
|
6717
|
+
useEffect33(() => {
|
|
6075
6718
|
onDamageRef.current = opts.onDamage;
|
|
6076
6719
|
});
|
|
6077
|
-
const timerRef =
|
|
6720
|
+
const timerRef = useRef13(
|
|
6078
6721
|
createTimer(iFrameDuration, () => {
|
|
6079
6722
|
invincibleRef.current = false;
|
|
6080
6723
|
})
|
|
@@ -6089,11 +6732,11 @@ function useHealth(maxHp, opts = {}) {
|
|
|
6089
6732
|
}
|
|
6090
6733
|
if (hpRef.current <= 0) onDeathRef.current?.();
|
|
6091
6734
|
}, [iFrameDuration]);
|
|
6092
|
-
const takeDamageRef =
|
|
6093
|
-
|
|
6735
|
+
const takeDamageRef = useRef13(takeDamage);
|
|
6736
|
+
useEffect33(() => {
|
|
6094
6737
|
takeDamageRef.current = takeDamage;
|
|
6095
6738
|
}, [takeDamage]);
|
|
6096
|
-
|
|
6739
|
+
useEffect33(() => {
|
|
6097
6740
|
return engine.events.on(`damage:${entityId}`, ({ amount }) => {
|
|
6098
6741
|
takeDamageRef.current(amount);
|
|
6099
6742
|
});
|
|
@@ -6128,10 +6771,10 @@ function useHealth(maxHp, opts = {}) {
|
|
|
6128
6771
|
}
|
|
6129
6772
|
|
|
6130
6773
|
// ../gameplay/src/hooks/useKinematicBody.ts
|
|
6131
|
-
import { useContext as
|
|
6774
|
+
import { useContext as useContext36, useCallback as useCallback10 } from "react";
|
|
6132
6775
|
function useKinematicBody() {
|
|
6133
|
-
const engine =
|
|
6134
|
-
const entityId =
|
|
6776
|
+
const engine = useContext36(EngineContext);
|
|
6777
|
+
const entityId = useContext36(EntityContext);
|
|
6135
6778
|
const moveAndCollide = useCallback10((dx, dy) => {
|
|
6136
6779
|
const transform = engine.ecs.getComponent(entityId, "Transform");
|
|
6137
6780
|
if (!transform) return { dx: 0, dy: 0 };
|
|
@@ -6176,11 +6819,11 @@ function useKinematicBody() {
|
|
|
6176
6819
|
}
|
|
6177
6820
|
|
|
6178
6821
|
// ../gameplay/src/hooks/useLevelTransition.ts
|
|
6179
|
-
import { useState as
|
|
6822
|
+
import { useState as useState12, useRef as useRef14, useCallback as useCallback11 } from "react";
|
|
6180
6823
|
function useLevelTransition(initial) {
|
|
6181
|
-
const [currentLevel, setCurrentLevel] =
|
|
6182
|
-
const [isTransitioning, setIsTransitioning] =
|
|
6183
|
-
const overlayRef =
|
|
6824
|
+
const [currentLevel, setCurrentLevel] = useState12(initial);
|
|
6825
|
+
const [isTransitioning, setIsTransitioning] = useState12(false);
|
|
6826
|
+
const overlayRef = useRef14(null);
|
|
6184
6827
|
const transitionTo = useCallback11((level, opts = {}) => {
|
|
6185
6828
|
const { duration = 0.4, type = "fade" } = opts;
|
|
6186
6829
|
if (type === "instant") {
|
|
@@ -6218,13 +6861,13 @@ function useLevelTransition(initial) {
|
|
|
6218
6861
|
}
|
|
6219
6862
|
|
|
6220
6863
|
// ../gameplay/src/hooks/usePlatformerController.ts
|
|
6221
|
-
import { useContext as
|
|
6864
|
+
import { useContext as useContext37, useEffect as useEffect34 } from "react";
|
|
6222
6865
|
function normalizeKeys(val, defaults) {
|
|
6223
6866
|
if (!val) return defaults;
|
|
6224
6867
|
return Array.isArray(val) ? val : [val];
|
|
6225
6868
|
}
|
|
6226
6869
|
function usePlatformerController(entityId, opts = {}) {
|
|
6227
|
-
const engine =
|
|
6870
|
+
const engine = useContext37(EngineContext);
|
|
6228
6871
|
const {
|
|
6229
6872
|
speed = 200,
|
|
6230
6873
|
jumpForce = -500,
|
|
@@ -6237,7 +6880,7 @@ function usePlatformerController(entityId, opts = {}) {
|
|
|
6237
6880
|
const leftKeys = normalizeKeys(bindings?.left, ["ArrowLeft", "KeyA", "a"]);
|
|
6238
6881
|
const rightKeys = normalizeKeys(bindings?.right, ["ArrowRight", "KeyD", "d"]);
|
|
6239
6882
|
const jumpKeys = normalizeKeys(bindings?.jump, ["Space", "ArrowUp", "KeyW", "w"]);
|
|
6240
|
-
|
|
6883
|
+
useEffect34(() => {
|
|
6241
6884
|
const state = {
|
|
6242
6885
|
coyoteTimer: 0,
|
|
6243
6886
|
jumpBuffer: 0,
|
|
@@ -6301,11 +6944,11 @@ function usePathfinding() {
|
|
|
6301
6944
|
}
|
|
6302
6945
|
|
|
6303
6946
|
// ../gameplay/src/hooks/usePersistedBindings.ts
|
|
6304
|
-
import { useState as
|
|
6947
|
+
import { useState as useState13, useCallback as useCallback13, useMemo as useMemo9, useContext as useContext38 } from "react";
|
|
6305
6948
|
function usePersistedBindings(storageKey, defaults) {
|
|
6306
|
-
const engine =
|
|
6949
|
+
const engine = useContext38(EngineContext);
|
|
6307
6950
|
const input = engine.input;
|
|
6308
|
-
const [bindings, setBindings] =
|
|
6951
|
+
const [bindings, setBindings] = useState13(() => {
|
|
6309
6952
|
try {
|
|
6310
6953
|
const stored = localStorage.getItem(storageKey);
|
|
6311
6954
|
if (stored) return { ...defaults, ...JSON.parse(stored) };
|
|
@@ -6313,7 +6956,7 @@ function usePersistedBindings(storageKey, defaults) {
|
|
|
6313
6956
|
}
|
|
6314
6957
|
return defaults;
|
|
6315
6958
|
});
|
|
6316
|
-
const normalized =
|
|
6959
|
+
const normalized = useMemo9(() => {
|
|
6317
6960
|
const out = {};
|
|
6318
6961
|
for (const [action, keys] of Object.entries(bindings)) {
|
|
6319
6962
|
if (typeof keys === "string") out[action] = [keys];
|
|
@@ -6338,7 +6981,7 @@ function usePersistedBindings(storageKey, defaults) {
|
|
|
6338
6981
|
}
|
|
6339
6982
|
setBindings(defaults);
|
|
6340
6983
|
}, [storageKey]);
|
|
6341
|
-
return
|
|
6984
|
+
return useMemo9(() => ({
|
|
6342
6985
|
bindings,
|
|
6343
6986
|
rebind,
|
|
6344
6987
|
reset,
|
|
@@ -6349,9 +6992,9 @@ function usePersistedBindings(storageKey, defaults) {
|
|
|
6349
6992
|
}
|
|
6350
6993
|
|
|
6351
6994
|
// ../gameplay/src/hooks/useRestart.ts
|
|
6352
|
-
import { useState as
|
|
6995
|
+
import { useState as useState14, useCallback as useCallback14 } from "react";
|
|
6353
6996
|
function useRestart() {
|
|
6354
|
-
const [restartKey, setRestartKey] =
|
|
6997
|
+
const [restartKey, setRestartKey] = useState14(0);
|
|
6355
6998
|
const restart = useCallback14(() => {
|
|
6356
6999
|
setRestartKey((k) => k + 1);
|
|
6357
7000
|
}, []);
|
|
@@ -6359,10 +7002,10 @@ function useRestart() {
|
|
|
6359
7002
|
}
|
|
6360
7003
|
|
|
6361
7004
|
// ../gameplay/src/hooks/useSave.ts
|
|
6362
|
-
import { useCallback as useCallback15, useRef as
|
|
7005
|
+
import { useCallback as useCallback15, useRef as useRef15 } from "react";
|
|
6363
7006
|
function useSave(key, defaultValue, opts = {}) {
|
|
6364
7007
|
const version = opts.version ?? 1;
|
|
6365
|
-
const dataRef =
|
|
7008
|
+
const dataRef = useRef15(defaultValue);
|
|
6366
7009
|
const save = useCallback15((value) => {
|
|
6367
7010
|
dataRef.current = value;
|
|
6368
7011
|
const slot = { version, data: value };
|
|
@@ -6408,11 +7051,11 @@ function useSave(key, defaultValue, opts = {}) {
|
|
|
6408
7051
|
}
|
|
6409
7052
|
|
|
6410
7053
|
// ../gameplay/src/hooks/useTopDownMovement.ts
|
|
6411
|
-
import { useContext as
|
|
7054
|
+
import { useContext as useContext39, useEffect as useEffect35 } from "react";
|
|
6412
7055
|
function useTopDownMovement(entityId, opts = {}) {
|
|
6413
|
-
const engine =
|
|
7056
|
+
const engine = useContext39(EngineContext);
|
|
6414
7057
|
const { speed = 200, normalizeDiagonal = true } = opts;
|
|
6415
|
-
|
|
7058
|
+
useEffect35(() => {
|
|
6416
7059
|
const updateFn = (id, world, input) => {
|
|
6417
7060
|
if (!world.hasEntity(id)) return;
|
|
6418
7061
|
const rb = world.getComponent(id, "RigidBody");
|
|
@@ -6437,11 +7080,11 @@ function useTopDownMovement(entityId, opts = {}) {
|
|
|
6437
7080
|
}
|
|
6438
7081
|
|
|
6439
7082
|
// ../gameplay/src/hooks/useDialogue.ts
|
|
6440
|
-
import { useState as
|
|
7083
|
+
import { useState as useState15, useCallback as useCallback16, useRef as useRef16 } from "react";
|
|
6441
7084
|
function useDialogue() {
|
|
6442
|
-
const [active, setActive] =
|
|
6443
|
-
const [currentId, setCurrentId] =
|
|
6444
|
-
const scriptRef =
|
|
7085
|
+
const [active, setActive] = useState15(false);
|
|
7086
|
+
const [currentId, setCurrentId] = useState15(null);
|
|
7087
|
+
const scriptRef = useRef16(null);
|
|
6445
7088
|
const start = useCallback16((script, startId) => {
|
|
6446
7089
|
scriptRef.current = script;
|
|
6447
7090
|
const id = startId ?? Object.keys(script)[0];
|
|
@@ -6485,16 +7128,16 @@ function useDialogue() {
|
|
|
6485
7128
|
}
|
|
6486
7129
|
|
|
6487
7130
|
// ../gameplay/src/hooks/useCutscene.ts
|
|
6488
|
-
import { useState as
|
|
7131
|
+
import { useState as useState16, useCallback as useCallback17, useRef as useRef17, useEffect as useEffect36, useContext as useContext40 } from "react";
|
|
6489
7132
|
function useCutscene() {
|
|
6490
|
-
const engine =
|
|
6491
|
-
const [playing, setPlaying] =
|
|
6492
|
-
const [stepIndex, setStepIndex] =
|
|
6493
|
-
const stepsRef =
|
|
6494
|
-
const timerRef =
|
|
6495
|
-
const idxRef =
|
|
6496
|
-
const playingRef =
|
|
6497
|
-
const entityRef =
|
|
7133
|
+
const engine = useContext40(EngineContext);
|
|
7134
|
+
const [playing, setPlaying] = useState16(false);
|
|
7135
|
+
const [stepIndex, setStepIndex] = useState16(0);
|
|
7136
|
+
const stepsRef = useRef17([]);
|
|
7137
|
+
const timerRef = useRef17(0);
|
|
7138
|
+
const idxRef = useRef17(0);
|
|
7139
|
+
const playingRef = useRef17(false);
|
|
7140
|
+
const entityRef = useRef17(null);
|
|
6498
7141
|
const finish = useCallback17(() => {
|
|
6499
7142
|
playingRef.current = false;
|
|
6500
7143
|
setPlaying(false);
|
|
@@ -6572,7 +7215,7 @@ function useCutscene() {
|
|
|
6572
7215
|
}
|
|
6573
7216
|
finish();
|
|
6574
7217
|
}, [finish]);
|
|
6575
|
-
|
|
7218
|
+
useEffect36(() => {
|
|
6576
7219
|
return () => {
|
|
6577
7220
|
if (entityRef.current !== null && engine.ecs.hasEntity(entityRef.current)) {
|
|
6578
7221
|
engine.ecs.destroyEntity(entityRef.current);
|
|
@@ -6618,8 +7261,112 @@ function useGameStore(key, initialState) {
|
|
|
6618
7261
|
return [state, setState];
|
|
6619
7262
|
}
|
|
6620
7263
|
|
|
7264
|
+
// ../gameplay/src/hooks/useTween.ts
|
|
7265
|
+
import { useRef as useRef18, useCallback as useCallback19, useEffect as useEffect37 } from "react";
|
|
7266
|
+
function useTween(opts) {
|
|
7267
|
+
const rafRef = useRef18(null);
|
|
7268
|
+
const startTimeRef = useRef18(0);
|
|
7269
|
+
const runningRef = useRef18(false);
|
|
7270
|
+
const optsRef = useRef18(opts);
|
|
7271
|
+
optsRef.current = opts;
|
|
7272
|
+
const stop = useCallback19(() => {
|
|
7273
|
+
if (rafRef.current !== null) {
|
|
7274
|
+
cancelAnimationFrame(rafRef.current);
|
|
7275
|
+
rafRef.current = null;
|
|
7276
|
+
}
|
|
7277
|
+
runningRef.current = false;
|
|
7278
|
+
}, []);
|
|
7279
|
+
const start = useCallback19(() => {
|
|
7280
|
+
stop();
|
|
7281
|
+
runningRef.current = true;
|
|
7282
|
+
startTimeRef.current = performance.now();
|
|
7283
|
+
const tick = (now) => {
|
|
7284
|
+
if (!runningRef.current) return;
|
|
7285
|
+
const { from, to, duration, ease, onUpdate, onComplete } = optsRef.current;
|
|
7286
|
+
const easeFn = ease ?? Ease.linear;
|
|
7287
|
+
const elapsed = (now - startTimeRef.current) / 1e3;
|
|
7288
|
+
const t = duration > 0 ? Math.min(elapsed / duration, 1) : 1;
|
|
7289
|
+
const value = from + (to - from) * easeFn(t);
|
|
7290
|
+
onUpdate(value);
|
|
7291
|
+
if (t >= 1) {
|
|
7292
|
+
runningRef.current = false;
|
|
7293
|
+
rafRef.current = null;
|
|
7294
|
+
onComplete?.();
|
|
7295
|
+
} else {
|
|
7296
|
+
rafRef.current = requestAnimationFrame(tick);
|
|
7297
|
+
}
|
|
7298
|
+
};
|
|
7299
|
+
rafRef.current = requestAnimationFrame(tick);
|
|
7300
|
+
}, [stop]);
|
|
7301
|
+
useEffect37(() => {
|
|
7302
|
+
if (opts.autoStart) {
|
|
7303
|
+
start();
|
|
7304
|
+
}
|
|
7305
|
+
}, []);
|
|
7306
|
+
useEffect37(() => {
|
|
7307
|
+
return () => {
|
|
7308
|
+
if (rafRef.current !== null) {
|
|
7309
|
+
cancelAnimationFrame(rafRef.current);
|
|
7310
|
+
rafRef.current = null;
|
|
7311
|
+
}
|
|
7312
|
+
runningRef.current = false;
|
|
7313
|
+
};
|
|
7314
|
+
}, []);
|
|
7315
|
+
return {
|
|
7316
|
+
start,
|
|
7317
|
+
stop,
|
|
7318
|
+
get isRunning() {
|
|
7319
|
+
return runningRef.current;
|
|
7320
|
+
}
|
|
7321
|
+
};
|
|
7322
|
+
}
|
|
7323
|
+
|
|
7324
|
+
// ../gameplay/src/hooks/useObjectPool.ts
|
|
7325
|
+
import { useRef as useRef19, useMemo as useMemo10, useEffect as useEffect38 } from "react";
|
|
7326
|
+
function useObjectPool(factory, reset, initialSize) {
|
|
7327
|
+
const poolRef = useRef19([]);
|
|
7328
|
+
const activeRef = useRef19(0);
|
|
7329
|
+
const factoryRef = useRef19(factory);
|
|
7330
|
+
factoryRef.current = factory;
|
|
7331
|
+
const resetRef = useRef19(reset);
|
|
7332
|
+
resetRef.current = reset;
|
|
7333
|
+
useEffect38(() => {
|
|
7334
|
+
if (initialSize != null && initialSize > 0) {
|
|
7335
|
+
const pool = poolRef.current;
|
|
7336
|
+
for (let i = 0; i < initialSize; i++) {
|
|
7337
|
+
pool.push(factoryRef.current());
|
|
7338
|
+
}
|
|
7339
|
+
}
|
|
7340
|
+
}, []);
|
|
7341
|
+
return useMemo10(() => ({
|
|
7342
|
+
acquire() {
|
|
7343
|
+
activeRef.current++;
|
|
7344
|
+
if (poolRef.current.length > 0) {
|
|
7345
|
+
return poolRef.current.pop();
|
|
7346
|
+
}
|
|
7347
|
+
return factoryRef.current();
|
|
7348
|
+
},
|
|
7349
|
+
release(obj) {
|
|
7350
|
+
resetRef.current(obj);
|
|
7351
|
+
activeRef.current = Math.max(0, activeRef.current - 1);
|
|
7352
|
+
poolRef.current.push(obj);
|
|
7353
|
+
},
|
|
7354
|
+
prewarm(count) {
|
|
7355
|
+
for (let i = 0; i < count; i++) {
|
|
7356
|
+
poolRef.current.push(factoryRef.current());
|
|
7357
|
+
}
|
|
7358
|
+
},
|
|
7359
|
+
get activeCount() {
|
|
7360
|
+
return activeRef.current;
|
|
7361
|
+
},
|
|
7362
|
+
get poolSize() {
|
|
7363
|
+
return poolRef.current.length;
|
|
7364
|
+
}
|
|
7365
|
+
}), []);
|
|
7366
|
+
}
|
|
7367
|
+
|
|
6621
7368
|
// ../../packages/audio/src/useSound.ts
|
|
6622
|
-
import { useEffect as
|
|
7369
|
+
import { useEffect as useEffect39, useRef as useRef20 } from "react";
|
|
6623
7370
|
var _audioCtx = null;
|
|
6624
7371
|
function getAudioCtx() {
|
|
6625
7372
|
if (!_audioCtx) _audioCtx = new AudioContext();
|
|
@@ -6686,13 +7433,13 @@ async function loadBuffer(src) {
|
|
|
6686
7433
|
return buf;
|
|
6687
7434
|
}
|
|
6688
7435
|
function useSound(src, opts = {}) {
|
|
6689
|
-
const bufferRef =
|
|
6690
|
-
const sourceRef =
|
|
6691
|
-
const gainRef =
|
|
6692
|
-
const volRef =
|
|
6693
|
-
const loopRef =
|
|
6694
|
-
const groupRef =
|
|
6695
|
-
|
|
7436
|
+
const bufferRef = useRef20(null);
|
|
7437
|
+
const sourceRef = useRef20(null);
|
|
7438
|
+
const gainRef = useRef20(null);
|
|
7439
|
+
const volRef = useRef20(opts.volume ?? 1);
|
|
7440
|
+
const loopRef = useRef20(opts.loop ?? false);
|
|
7441
|
+
const groupRef = useRef20(opts.group);
|
|
7442
|
+
useEffect39(() => {
|
|
6696
7443
|
let cancelled = false;
|
|
6697
7444
|
loadBuffer(src).then((buf) => {
|
|
6698
7445
|
if (!cancelled) bufferRef.current = buf;
|
|
@@ -6714,7 +7461,7 @@ function useSound(src, opts = {}) {
|
|
|
6714
7461
|
};
|
|
6715
7462
|
}, [src]);
|
|
6716
7463
|
const getDestination = () => groupRef.current ? getGroupGainNode(groupRef.current) : getGroupGainNode("master");
|
|
6717
|
-
const play = () => {
|
|
7464
|
+
const play = (playOpts) => {
|
|
6718
7465
|
if (!bufferRef.current) return;
|
|
6719
7466
|
const ctx = getAudioCtx();
|
|
6720
7467
|
if (ctx.state === "suspended") void ctx.resume();
|
|
@@ -6733,7 +7480,12 @@ function useSound(src, opts = {}) {
|
|
|
6733
7480
|
source.buffer = bufferRef.current;
|
|
6734
7481
|
source.loop = loopRef.current;
|
|
6735
7482
|
source.connect(gain);
|
|
6736
|
-
|
|
7483
|
+
const delay = playOpts?.delay;
|
|
7484
|
+
if (delay && delay > 0) {
|
|
7485
|
+
source.start(ctx.currentTime + delay);
|
|
7486
|
+
} else {
|
|
7487
|
+
source.start();
|
|
7488
|
+
}
|
|
6737
7489
|
source.onended = () => {
|
|
6738
7490
|
sourceRef.current = null;
|
|
6739
7491
|
};
|
|
@@ -6827,7 +7579,19 @@ function createAtlas(names, _columns) {
|
|
|
6827
7579
|
});
|
|
6828
7580
|
return atlas;
|
|
6829
7581
|
}
|
|
7582
|
+
|
|
7583
|
+
// src/utils/prefab.ts
|
|
7584
|
+
import { memo } from "react";
|
|
7585
|
+
function definePrefab(name, defaults, render) {
|
|
7586
|
+
const component = memo((props) => {
|
|
7587
|
+
const merged = { ...defaults, ...props };
|
|
7588
|
+
return render(merged);
|
|
7589
|
+
});
|
|
7590
|
+
component.displayName = name;
|
|
7591
|
+
return component;
|
|
7592
|
+
}
|
|
6830
7593
|
export {
|
|
7594
|
+
AnimatedSprite,
|
|
6831
7595
|
Animation,
|
|
6832
7596
|
AssetLoader,
|
|
6833
7597
|
BoxCollider,
|
|
@@ -6858,29 +7622,38 @@ export {
|
|
|
6858
7622
|
VirtualJoystick,
|
|
6859
7623
|
World,
|
|
6860
7624
|
arrive,
|
|
7625
|
+
chromaticAberrationEffect,
|
|
6861
7626
|
createAtlas,
|
|
6862
7627
|
createCompoundCollider,
|
|
6863
7628
|
createInputMap,
|
|
6864
7629
|
createInputRecorder,
|
|
6865
7630
|
createNineSlice,
|
|
6866
7631
|
createPlayerInput,
|
|
7632
|
+
createPostProcessStack,
|
|
7633
|
+
createRenderLayerManager,
|
|
6867
7634
|
createSprite,
|
|
6868
7635
|
createTag,
|
|
7636
|
+
createTimeline,
|
|
6869
7637
|
createTimer,
|
|
6870
7638
|
createTransform,
|
|
7639
|
+
defaultLayers,
|
|
7640
|
+
defineAnimations,
|
|
6871
7641
|
definePlugin,
|
|
7642
|
+
definePrefab,
|
|
6872
7643
|
duck,
|
|
6873
7644
|
findByTag,
|
|
6874
7645
|
flee,
|
|
6875
7646
|
getGroupVolume,
|
|
6876
7647
|
globalInputContext,
|
|
6877
7648
|
hotReloadPlugin,
|
|
7649
|
+
mergeTileColliders,
|
|
6878
7650
|
overlapBox,
|
|
6879
7651
|
overlapCircle,
|
|
6880
7652
|
patrol,
|
|
6881
7653
|
preloadManifest,
|
|
6882
7654
|
raycast,
|
|
6883
7655
|
raycastAll,
|
|
7656
|
+
scanlineEffect,
|
|
6884
7657
|
seek,
|
|
6885
7658
|
setGroupMute,
|
|
6886
7659
|
setGroupVolume,
|
|
@@ -6894,6 +7667,7 @@ export {
|
|
|
6894
7667
|
useCircleEnter,
|
|
6895
7668
|
useCircleExit,
|
|
6896
7669
|
useCircleStay,
|
|
7670
|
+
useCollidingWith,
|
|
6897
7671
|
useCollisionEnter,
|
|
6898
7672
|
useCollisionExit,
|
|
6899
7673
|
useCollisionStay,
|
|
@@ -6918,12 +7692,15 @@ export {
|
|
|
6918
7692
|
useKinematicBody,
|
|
6919
7693
|
useLevelTransition,
|
|
6920
7694
|
useLocalMultiplayer,
|
|
7695
|
+
useObjectPool,
|
|
6921
7696
|
usePathfinding,
|
|
6922
7697
|
usePause,
|
|
6923
7698
|
usePersistedBindings,
|
|
6924
7699
|
usePlatformerController,
|
|
6925
7700
|
usePlayerInput,
|
|
7701
|
+
usePostProcess,
|
|
6926
7702
|
usePreload,
|
|
7703
|
+
useProfiler,
|
|
6927
7704
|
useRestart,
|
|
6928
7705
|
useSave,
|
|
6929
7706
|
useSnapshot,
|
|
@@ -6932,6 +7709,8 @@ export {
|
|
|
6932
7709
|
useTriggerEnter,
|
|
6933
7710
|
useTriggerExit,
|
|
6934
7711
|
useTriggerStay,
|
|
7712
|
+
useTween,
|
|
6935
7713
|
useVirtualInput,
|
|
7714
|
+
vignetteEffect,
|
|
6936
7715
|
wander
|
|
6937
7716
|
};
|