@almadar/ui 5.42.0 → 5.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/avl/index.cjs +318 -263
- package/dist/avl/index.js +319 -264
- package/dist/components/game/molecules/three/index.cjs +128 -17
- package/dist/components/game/molecules/three/index.js +128 -17
- package/dist/components/game/organisms/physics-sim/SimulationCanvas.d.ts +8 -2
- package/dist/components/game/templates/GameCanvas3DBattleTemplate.d.ts +8 -1
- package/dist/components/game/templates/GameCanvas3DCastleTemplate.d.ts +8 -1
- package/dist/components/game/templates/GameCanvas3DWorldMapTemplate.d.ts +8 -1
- package/dist/components/index.cjs +442 -264
- package/dist/components/index.js +443 -265
- package/dist/hooks/index.cjs +68 -0
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.js +68 -1
- package/dist/hooks/useRenderInterpolation.d.ts +33 -0
- package/dist/providers/index.cjs +318 -263
- package/dist/providers/index.js +319 -264
- package/dist/runtime/index.cjs +318 -263
- package/dist/runtime/index.js +319 -264
- package/package.json +1 -1
|
@@ -28834,6 +28834,78 @@ var init_GameOverScreen = __esm({
|
|
|
28834
28834
|
GameOverScreen.displayName = "GameOverScreen";
|
|
28835
28835
|
}
|
|
28836
28836
|
});
|
|
28837
|
+
function useRenderInterpolation(options = {}) {
|
|
28838
|
+
const tickIntervalMs = options.tickIntervalMs ?? 1e3 / 30;
|
|
28839
|
+
const prevRef = React77.useRef(null);
|
|
28840
|
+
const currRef = React77.useRef(null);
|
|
28841
|
+
const rafRef = React77.useRef(null);
|
|
28842
|
+
const onSnapshot = React77.useCallback((entities) => {
|
|
28843
|
+
prevRef.current = currRef.current;
|
|
28844
|
+
currRef.current = { entities, arrivedAt: performance.now() };
|
|
28845
|
+
}, []);
|
|
28846
|
+
const getInterpolated = React77.useCallback((now) => {
|
|
28847
|
+
const out = /* @__PURE__ */ new Map();
|
|
28848
|
+
const curr = currRef.current;
|
|
28849
|
+
if (!curr) return out;
|
|
28850
|
+
const prev = prevRef.current;
|
|
28851
|
+
if (!prev) {
|
|
28852
|
+
for (const e of curr.entities) out.set(e.id, { x: e.x, y: e.y });
|
|
28853
|
+
return out;
|
|
28854
|
+
}
|
|
28855
|
+
const rawAlpha = (now - curr.arrivedAt) / tickIntervalMs;
|
|
28856
|
+
const alpha = rawAlpha < 0 ? 0 : rawAlpha > 1 ? 1 : rawAlpha;
|
|
28857
|
+
const prevMap = /* @__PURE__ */ new Map();
|
|
28858
|
+
for (const e of prev.entities) prevMap.set(e.id, e);
|
|
28859
|
+
for (const c of curr.entities) {
|
|
28860
|
+
const p2 = prevMap.get(c.id);
|
|
28861
|
+
if (!p2) {
|
|
28862
|
+
out.set(c.id, { x: c.x, y: c.y });
|
|
28863
|
+
} else {
|
|
28864
|
+
out.set(c.id, {
|
|
28865
|
+
x: p2.x + (c.x - p2.x) * alpha,
|
|
28866
|
+
y: p2.y + (c.y - p2.y) * alpha
|
|
28867
|
+
});
|
|
28868
|
+
}
|
|
28869
|
+
}
|
|
28870
|
+
return out;
|
|
28871
|
+
}, [tickIntervalMs]);
|
|
28872
|
+
const startLoop = React77.useCallback(
|
|
28873
|
+
(draw) => {
|
|
28874
|
+
let active = true;
|
|
28875
|
+
const loop = () => {
|
|
28876
|
+
if (!active) return;
|
|
28877
|
+
try {
|
|
28878
|
+
draw(getInterpolated(performance.now()));
|
|
28879
|
+
} catch {
|
|
28880
|
+
}
|
|
28881
|
+
rafRef.current = requestAnimationFrame(loop);
|
|
28882
|
+
};
|
|
28883
|
+
rafRef.current = requestAnimationFrame(loop);
|
|
28884
|
+
return () => {
|
|
28885
|
+
active = false;
|
|
28886
|
+
if (rafRef.current !== null) {
|
|
28887
|
+
cancelAnimationFrame(rafRef.current);
|
|
28888
|
+
rafRef.current = null;
|
|
28889
|
+
}
|
|
28890
|
+
};
|
|
28891
|
+
},
|
|
28892
|
+
[getInterpolated]
|
|
28893
|
+
);
|
|
28894
|
+
React77.useEffect(() => {
|
|
28895
|
+
return () => {
|
|
28896
|
+
if (rafRef.current !== null) {
|
|
28897
|
+
cancelAnimationFrame(rafRef.current);
|
|
28898
|
+
rafRef.current = null;
|
|
28899
|
+
}
|
|
28900
|
+
};
|
|
28901
|
+
}, []);
|
|
28902
|
+
return { onSnapshot, getInterpolated, startLoop };
|
|
28903
|
+
}
|
|
28904
|
+
var init_useRenderInterpolation = __esm({
|
|
28905
|
+
"hooks/useRenderInterpolation.ts"() {
|
|
28906
|
+
"use client";
|
|
28907
|
+
}
|
|
28908
|
+
});
|
|
28837
28909
|
function PlatformerCanvas({
|
|
28838
28910
|
player,
|
|
28839
28911
|
platforms = [
|
|
@@ -28902,8 +28974,43 @@ function PlatformerCanvas({
|
|
|
28902
28974
|
y: 336,
|
|
28903
28975
|
width: 32,
|
|
28904
28976
|
height: 48,
|
|
28977
|
+
vx: 0,
|
|
28978
|
+
vy: 0,
|
|
28979
|
+
grounded: true,
|
|
28905
28980
|
facingRight: true
|
|
28906
28981
|
};
|
|
28982
|
+
const playerRef = React77.useRef(resolvedPlayer);
|
|
28983
|
+
playerRef.current = resolvedPlayer;
|
|
28984
|
+
const interp = useRenderInterpolation();
|
|
28985
|
+
React77.useEffect(() => {
|
|
28986
|
+
interp.onSnapshot([{ id: "player", x: resolvedPlayer.x, y: resolvedPlayer.y }]);
|
|
28987
|
+
}, [resolvedPlayer.x, resolvedPlayer.y]);
|
|
28988
|
+
const propsRef = React77.useRef({
|
|
28989
|
+
platforms,
|
|
28990
|
+
worldWidth,
|
|
28991
|
+
worldHeight,
|
|
28992
|
+
canvasWidth,
|
|
28993
|
+
canvasHeight,
|
|
28994
|
+
followCamera,
|
|
28995
|
+
bgColor,
|
|
28996
|
+
playerSprite,
|
|
28997
|
+
tileSprites,
|
|
28998
|
+
backgroundImage,
|
|
28999
|
+
assetBaseUrl
|
|
29000
|
+
});
|
|
29001
|
+
propsRef.current = {
|
|
29002
|
+
platforms,
|
|
29003
|
+
worldWidth,
|
|
29004
|
+
worldHeight,
|
|
29005
|
+
canvasWidth,
|
|
29006
|
+
canvasHeight,
|
|
29007
|
+
followCamera,
|
|
29008
|
+
bgColor,
|
|
29009
|
+
playerSprite,
|
|
29010
|
+
tileSprites,
|
|
29011
|
+
backgroundImage,
|
|
29012
|
+
assetBaseUrl
|
|
29013
|
+
};
|
|
28907
29014
|
const handleKeyDown = React77.useCallback((e) => {
|
|
28908
29015
|
if (keysRef.current.has(e.code)) return;
|
|
28909
29016
|
keysRef.current.add(e.code);
|
|
@@ -28952,124 +29059,149 @@ function PlatformerCanvas({
|
|
|
28952
29059
|
canvas.width = canvasWidth * dpr;
|
|
28953
29060
|
canvas.height = canvasHeight * dpr;
|
|
28954
29061
|
ctx.scale(dpr, dpr);
|
|
28955
|
-
|
|
28956
|
-
|
|
28957
|
-
|
|
28958
|
-
|
|
28959
|
-
|
|
28960
|
-
|
|
28961
|
-
|
|
28962
|
-
|
|
28963
|
-
|
|
28964
|
-
|
|
28965
|
-
|
|
28966
|
-
|
|
28967
|
-
|
|
28968
|
-
|
|
28969
|
-
|
|
28970
|
-
|
|
28971
|
-
|
|
28972
|
-
|
|
28973
|
-
|
|
28974
|
-
|
|
28975
|
-
|
|
28976
|
-
|
|
28977
|
-
|
|
28978
|
-
|
|
28979
|
-
|
|
28980
|
-
|
|
28981
|
-
|
|
28982
|
-
|
|
28983
|
-
|
|
28984
|
-
|
|
28985
|
-
|
|
28986
|
-
|
|
28987
|
-
|
|
28988
|
-
|
|
28989
|
-
|
|
28990
|
-
const px = plat.x - camX;
|
|
28991
|
-
const py = plat.y - camY;
|
|
28992
|
-
const platType = plat.type ?? "ground";
|
|
28993
|
-
const spriteUrl = tileSprites?.[platType];
|
|
28994
|
-
const tileImg = spriteUrl ? loadImage(spriteUrl) : null;
|
|
28995
|
-
if (tileImg) {
|
|
28996
|
-
const tileW = tileImg.naturalWidth;
|
|
28997
|
-
const tileH = tileImg.naturalHeight;
|
|
28998
|
-
const scaleH = plat.height / tileH;
|
|
28999
|
-
const scaledW = tileW * scaleH;
|
|
29000
|
-
for (let tx = 0; tx < plat.width; tx += scaledW) {
|
|
29001
|
-
const drawW = Math.min(scaledW, plat.width - tx);
|
|
29002
|
-
const srcW = drawW / scaleH;
|
|
29003
|
-
ctx.drawImage(tileImg, 0, 0, srcW, tileH, px + tx, py, drawW, plat.height);
|
|
29004
|
-
}
|
|
29062
|
+
}, [canvasWidth, canvasHeight]);
|
|
29063
|
+
React77.useEffect(() => {
|
|
29064
|
+
const drawFrame = (positions) => {
|
|
29065
|
+
const canvas = canvasRef.current;
|
|
29066
|
+
if (!canvas) return;
|
|
29067
|
+
const ctx = canvas.getContext("2d");
|
|
29068
|
+
if (!ctx) return;
|
|
29069
|
+
const {
|
|
29070
|
+
platforms: plats,
|
|
29071
|
+
worldWidth: ww,
|
|
29072
|
+
worldHeight: wh,
|
|
29073
|
+
canvasWidth: cw,
|
|
29074
|
+
canvasHeight: ch,
|
|
29075
|
+
followCamera: fc,
|
|
29076
|
+
bgColor: bg,
|
|
29077
|
+
playerSprite: pSprite,
|
|
29078
|
+
tileSprites: tSprites,
|
|
29079
|
+
backgroundImage: bgImg
|
|
29080
|
+
} = propsRef.current;
|
|
29081
|
+
const auth = playerRef.current;
|
|
29082
|
+
const interped = positions.get("player");
|
|
29083
|
+
const px = interped?.x ?? auth.x;
|
|
29084
|
+
const py = interped?.y ?? auth.y;
|
|
29085
|
+
let camX = 0;
|
|
29086
|
+
let camY = 0;
|
|
29087
|
+
if (fc) {
|
|
29088
|
+
camX = Math.max(0, Math.min(px - cw / 2, ww - cw));
|
|
29089
|
+
camY = Math.max(0, Math.min(py - ch / 2 - 50, wh - ch));
|
|
29090
|
+
}
|
|
29091
|
+
const bgImage = bgImg ? loadImage(bgImg) : null;
|
|
29092
|
+
if (bgImage) {
|
|
29093
|
+
ctx.drawImage(bgImage, 0, 0, cw, ch);
|
|
29094
|
+
} else if (bg) {
|
|
29095
|
+
ctx.fillStyle = bg;
|
|
29096
|
+
ctx.fillRect(0, 0, cw, ch);
|
|
29005
29097
|
} else {
|
|
29006
|
-
const
|
|
29007
|
-
|
|
29008
|
-
|
|
29009
|
-
ctx.fillStyle =
|
|
29010
|
-
ctx.fillRect(
|
|
29011
|
-
|
|
29012
|
-
|
|
29013
|
-
|
|
29014
|
-
|
|
29015
|
-
|
|
29016
|
-
|
|
29098
|
+
const grad = ctx.createLinearGradient(0, 0, 0, ch);
|
|
29099
|
+
grad.addColorStop(0, SKY_GRADIENT_TOP);
|
|
29100
|
+
grad.addColorStop(1, SKY_GRADIENT_BOTTOM);
|
|
29101
|
+
ctx.fillStyle = grad;
|
|
29102
|
+
ctx.fillRect(0, 0, cw, ch);
|
|
29103
|
+
}
|
|
29104
|
+
ctx.strokeStyle = GRID_COLOR;
|
|
29105
|
+
ctx.lineWidth = 1;
|
|
29106
|
+
const gridSize = 32;
|
|
29107
|
+
for (let gx = -camX % gridSize; gx < cw; gx += gridSize) {
|
|
29108
|
+
ctx.beginPath();
|
|
29109
|
+
ctx.moveTo(gx, 0);
|
|
29110
|
+
ctx.lineTo(gx, ch);
|
|
29111
|
+
ctx.stroke();
|
|
29112
|
+
}
|
|
29113
|
+
for (let gy = -camY % gridSize; gy < ch; gy += gridSize) {
|
|
29114
|
+
ctx.beginPath();
|
|
29115
|
+
ctx.moveTo(0, gy);
|
|
29116
|
+
ctx.lineTo(cw, gy);
|
|
29117
|
+
ctx.stroke();
|
|
29118
|
+
}
|
|
29119
|
+
for (const plat of plats) {
|
|
29120
|
+
const platX = plat.x - camX;
|
|
29121
|
+
const platY = plat.y - camY;
|
|
29122
|
+
const platType = plat.type ?? "ground";
|
|
29123
|
+
const spriteUrl = tSprites?.[platType];
|
|
29124
|
+
const tileImg = spriteUrl ? loadImage(spriteUrl) : null;
|
|
29125
|
+
if (tileImg) {
|
|
29126
|
+
const tileW = tileImg.naturalWidth;
|
|
29127
|
+
const tileH = tileImg.naturalHeight;
|
|
29128
|
+
const scaleH = plat.height / tileH;
|
|
29129
|
+
const scaledW = tileW * scaleH;
|
|
29130
|
+
for (let tx = 0; tx < plat.width; tx += scaledW) {
|
|
29131
|
+
const drawW = Math.min(scaledW, plat.width - tx);
|
|
29132
|
+
const srcW = drawW / scaleH;
|
|
29133
|
+
ctx.drawImage(tileImg, 0, 0, srcW, tileH, platX + tx, platY, drawW, plat.height);
|
|
29134
|
+
}
|
|
29135
|
+
} else {
|
|
29136
|
+
const color = PLATFORM_COLORS[platType] ?? PLATFORM_COLORS.ground;
|
|
29137
|
+
ctx.fillStyle = color;
|
|
29138
|
+
ctx.fillRect(platX, platY, plat.width, plat.height);
|
|
29139
|
+
ctx.fillStyle = "rgba(255, 255, 255, 0.15)";
|
|
29140
|
+
ctx.fillRect(platX, platY, plat.width, 3);
|
|
29141
|
+
ctx.fillStyle = "rgba(0, 0, 0, 0.3)";
|
|
29142
|
+
ctx.fillRect(platX, platY + plat.height - 2, plat.width, 2);
|
|
29143
|
+
if (platType === "hazard") {
|
|
29144
|
+
ctx.strokeStyle = "#e74c3c";
|
|
29145
|
+
ctx.lineWidth = 2;
|
|
29146
|
+
for (let sx = platX; sx < platX + plat.width; sx += 12) {
|
|
29147
|
+
ctx.beginPath();
|
|
29148
|
+
ctx.moveTo(sx, platY);
|
|
29149
|
+
ctx.lineTo(sx + 6, platY + plat.height);
|
|
29150
|
+
ctx.stroke();
|
|
29151
|
+
}
|
|
29152
|
+
}
|
|
29153
|
+
if (platType === "goal") {
|
|
29154
|
+
ctx.fillStyle = "rgba(241, 196, 15, 0.5)";
|
|
29017
29155
|
ctx.beginPath();
|
|
29018
|
-
ctx.
|
|
29019
|
-
ctx.
|
|
29020
|
-
ctx.stroke();
|
|
29156
|
+
ctx.arc(platX + plat.width / 2, platY - 10, 8, 0, Math.PI * 2);
|
|
29157
|
+
ctx.fill();
|
|
29021
29158
|
}
|
|
29022
29159
|
}
|
|
29023
|
-
if (platType === "goal") {
|
|
29024
|
-
ctx.fillStyle = "rgba(241, 196, 15, 0.5)";
|
|
29025
|
-
ctx.beginPath();
|
|
29026
|
-
ctx.arc(px + plat.width / 2, py - 10, 8, 0, Math.PI * 2);
|
|
29027
|
-
ctx.fill();
|
|
29028
|
-
}
|
|
29029
29160
|
}
|
|
29030
|
-
|
|
29031
|
-
|
|
29032
|
-
|
|
29033
|
-
|
|
29034
|
-
|
|
29035
|
-
|
|
29036
|
-
|
|
29037
|
-
|
|
29038
|
-
|
|
29039
|
-
|
|
29040
|
-
|
|
29041
|
-
|
|
29042
|
-
|
|
29161
|
+
const pw = auth.width ?? 24;
|
|
29162
|
+
const ph = auth.height ?? 32;
|
|
29163
|
+
const ppx = px - camX;
|
|
29164
|
+
const ppy = py - camY;
|
|
29165
|
+
const facingRight = auth.facingRight ?? true;
|
|
29166
|
+
const playerImg = pSprite ? loadImage(pSprite) : null;
|
|
29167
|
+
if (playerImg) {
|
|
29168
|
+
ctx.save();
|
|
29169
|
+
if (!facingRight) {
|
|
29170
|
+
ctx.translate(ppx + pw, ppy);
|
|
29171
|
+
ctx.scale(-1, 1);
|
|
29172
|
+
ctx.drawImage(playerImg, 0, 0, pw, ph);
|
|
29173
|
+
} else {
|
|
29174
|
+
ctx.drawImage(playerImg, ppx, ppy, pw, ph);
|
|
29175
|
+
}
|
|
29176
|
+
ctx.restore();
|
|
29043
29177
|
} else {
|
|
29044
|
-
ctx.
|
|
29178
|
+
ctx.fillStyle = PLAYER_COLOR;
|
|
29179
|
+
const radius = Math.min(pw, ph) * 0.25;
|
|
29180
|
+
ctx.beginPath();
|
|
29181
|
+
ctx.moveTo(ppx + radius, ppy);
|
|
29182
|
+
ctx.lineTo(ppx + pw - radius, ppy);
|
|
29183
|
+
ctx.quadraticCurveTo(ppx + pw, ppy, ppx + pw, ppy + radius);
|
|
29184
|
+
ctx.lineTo(ppx + pw, ppy + ph - radius);
|
|
29185
|
+
ctx.quadraticCurveTo(ppx + pw, ppy + ph, ppx + pw - radius, ppy + ph);
|
|
29186
|
+
ctx.lineTo(ppx + radius, ppy + ph);
|
|
29187
|
+
ctx.quadraticCurveTo(ppx, ppy + ph, ppx, ppy + ph - radius);
|
|
29188
|
+
ctx.lineTo(ppx, ppy + radius);
|
|
29189
|
+
ctx.quadraticCurveTo(ppx, ppy, ppx + radius, ppy);
|
|
29190
|
+
ctx.fill();
|
|
29191
|
+
const eyeY = ppy + ph * 0.3;
|
|
29192
|
+
const eyeSize = 3;
|
|
29193
|
+
const eyeOffsetX = facingRight ? pw * 0.55 : pw * 0.2;
|
|
29194
|
+
ctx.fillStyle = PLAYER_EYE_COLOR;
|
|
29195
|
+
ctx.beginPath();
|
|
29196
|
+
ctx.arc(ppx + eyeOffsetX, eyeY, eyeSize, 0, Math.PI * 2);
|
|
29197
|
+
ctx.fill();
|
|
29198
|
+
ctx.beginPath();
|
|
29199
|
+
ctx.arc(ppx + eyeOffsetX + 7, eyeY, eyeSize, 0, Math.PI * 2);
|
|
29200
|
+
ctx.fill();
|
|
29045
29201
|
}
|
|
29046
|
-
|
|
29047
|
-
|
|
29048
|
-
|
|
29049
|
-
const radius = Math.min(pw, ph) * 0.25;
|
|
29050
|
-
ctx.beginPath();
|
|
29051
|
-
ctx.moveTo(ppx + radius, ppy);
|
|
29052
|
-
ctx.lineTo(ppx + pw - radius, ppy);
|
|
29053
|
-
ctx.quadraticCurveTo(ppx + pw, ppy, ppx + pw, ppy + radius);
|
|
29054
|
-
ctx.lineTo(ppx + pw, ppy + ph - radius);
|
|
29055
|
-
ctx.quadraticCurveTo(ppx + pw, ppy + ph, ppx + pw - radius, ppy + ph);
|
|
29056
|
-
ctx.lineTo(ppx + radius, ppy + ph);
|
|
29057
|
-
ctx.quadraticCurveTo(ppx, ppy + ph, ppx, ppy + ph - radius);
|
|
29058
|
-
ctx.lineTo(ppx, ppy + radius);
|
|
29059
|
-
ctx.quadraticCurveTo(ppx, ppy, ppx + radius, ppy);
|
|
29060
|
-
ctx.fill();
|
|
29061
|
-
const eyeY = ppy + ph * 0.3;
|
|
29062
|
-
const eyeSize = 3;
|
|
29063
|
-
const eyeOffsetX = facingRight ? pw * 0.55 : pw * 0.2;
|
|
29064
|
-
ctx.fillStyle = PLAYER_EYE_COLOR;
|
|
29065
|
-
ctx.beginPath();
|
|
29066
|
-
ctx.arc(ppx + eyeOffsetX, eyeY, eyeSize, 0, Math.PI * 2);
|
|
29067
|
-
ctx.fill();
|
|
29068
|
-
ctx.beginPath();
|
|
29069
|
-
ctx.arc(ppx + eyeOffsetX + 7, eyeY, eyeSize, 0, Math.PI * 2);
|
|
29070
|
-
ctx.fill();
|
|
29071
|
-
}
|
|
29072
|
-
}, [player, platforms, worldWidth, worldHeight, canvasWidth, canvasHeight, followCamera, bgColor, playerSprite, tileSprites, backgroundImage, assetBaseUrl, loadedImages]);
|
|
29202
|
+
};
|
|
29203
|
+
return interp.startLoop(drawFrame);
|
|
29204
|
+
}, [interp.startLoop, loadImage]);
|
|
29073
29205
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
29074
29206
|
"canvas",
|
|
29075
29207
|
{
|
|
@@ -29087,6 +29219,7 @@ var init_PlatformerCanvas = __esm({
|
|
|
29087
29219
|
init_cn();
|
|
29088
29220
|
init_useEventBus();
|
|
29089
29221
|
init_verificationRegistry();
|
|
29222
|
+
init_useRenderInterpolation();
|
|
29090
29223
|
PLATFORM_COLORS = {
|
|
29091
29224
|
ground: "#4a7c59",
|
|
29092
29225
|
platform: "#7c6b4a",
|
|
@@ -29491,13 +29624,13 @@ var init_MapView = __esm({
|
|
|
29491
29624
|
shadowSize: [41, 41]
|
|
29492
29625
|
});
|
|
29493
29626
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
29494
|
-
const { useEffect:
|
|
29627
|
+
const { useEffect: useEffect74, useRef: useRef71, useCallback: useCallback114, useState: useState105 } = React77__namespace.default;
|
|
29495
29628
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
29496
29629
|
const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
29497
29630
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
29498
29631
|
const map = useMap();
|
|
29499
|
-
const prevRef =
|
|
29500
|
-
|
|
29632
|
+
const prevRef = useRef71({ centerLat, centerLng, zoom });
|
|
29633
|
+
useEffect74(() => {
|
|
29501
29634
|
const prev = prevRef.current;
|
|
29502
29635
|
if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
|
|
29503
29636
|
map.setView([centerLat, centerLng], zoom);
|
|
@@ -29508,7 +29641,7 @@ var init_MapView = __esm({
|
|
|
29508
29641
|
}
|
|
29509
29642
|
function MapClickHandler({ onMapClick }) {
|
|
29510
29643
|
const map = useMap();
|
|
29511
|
-
|
|
29644
|
+
useEffect74(() => {
|
|
29512
29645
|
if (!onMapClick) return;
|
|
29513
29646
|
const handler = (e) => {
|
|
29514
29647
|
onMapClick(e.latlng.lat, e.latlng.lng);
|
|
@@ -29537,7 +29670,7 @@ var init_MapView = __esm({
|
|
|
29537
29670
|
}) {
|
|
29538
29671
|
const eventBus = useEventBus2();
|
|
29539
29672
|
const [clickedPosition, setClickedPosition] = useState105(null);
|
|
29540
|
-
const handleMapClick =
|
|
29673
|
+
const handleMapClick = useCallback114((lat, lng) => {
|
|
29541
29674
|
if (showClickedPin) {
|
|
29542
29675
|
setClickedPosition({ lat, lng });
|
|
29543
29676
|
}
|
|
@@ -29546,7 +29679,7 @@ var init_MapView = __esm({
|
|
|
29546
29679
|
eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
|
|
29547
29680
|
}
|
|
29548
29681
|
}, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
|
|
29549
|
-
const handleMarkerClick =
|
|
29682
|
+
const handleMarkerClick = useCallback114((marker) => {
|
|
29550
29683
|
onMarkerClick?.(marker);
|
|
29551
29684
|
if (markerClickEvent) {
|
|
29552
29685
|
eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
|
|
@@ -45876,11 +46009,13 @@ function SimulationCanvas({
|
|
|
45876
46009
|
height = 400,
|
|
45877
46010
|
running,
|
|
45878
46011
|
speed = 1,
|
|
46012
|
+
bodies: externalBodies,
|
|
45879
46013
|
className
|
|
45880
46014
|
}) {
|
|
45881
46015
|
const preset = React77.useMemo(() => resolvePreset(presetProp), [presetProp]);
|
|
45882
46016
|
const canvasRef = React77.useRef(null);
|
|
45883
46017
|
const bodiesRef = React77.useRef(structuredClone(preset.bodies));
|
|
46018
|
+
const interp = useRenderInterpolation();
|
|
45884
46019
|
React77.useEffect(() => {
|
|
45885
46020
|
bodiesRef.current = structuredClone(preset.bodies);
|
|
45886
46021
|
}, [preset]);
|
|
@@ -45978,6 +46113,67 @@ function SimulationCanvas({
|
|
|
45978
46113
|
}
|
|
45979
46114
|
}, [width, height, preset]);
|
|
45980
46115
|
React77.useEffect(() => {
|
|
46116
|
+
if (!externalBodies) return;
|
|
46117
|
+
interp.onSnapshot(externalBodies.map((b) => ({ id: b.id, x: b.x, y: b.y })));
|
|
46118
|
+
}, [externalBodies]);
|
|
46119
|
+
const presetRef = React77.useRef(preset);
|
|
46120
|
+
presetRef.current = preset;
|
|
46121
|
+
const widthRef = React77.useRef(width);
|
|
46122
|
+
widthRef.current = width;
|
|
46123
|
+
const heightRef = React77.useRef(height);
|
|
46124
|
+
heightRef.current = height;
|
|
46125
|
+
React77.useEffect(() => {
|
|
46126
|
+
if (!externalBodies) return;
|
|
46127
|
+
const drawInterpolated = (positions) => {
|
|
46128
|
+
const canvas = canvasRef.current;
|
|
46129
|
+
if (!canvas) return;
|
|
46130
|
+
const ctx = canvas.getContext("2d");
|
|
46131
|
+
if (!ctx) return;
|
|
46132
|
+
const bodies = bodiesRef.current;
|
|
46133
|
+
const p2 = presetRef.current;
|
|
46134
|
+
const w = widthRef.current;
|
|
46135
|
+
const h = heightRef.current;
|
|
46136
|
+
ctx.clearRect(0, 0, w, h);
|
|
46137
|
+
ctx.fillStyle = p2.backgroundColor ?? "#1a1a2e";
|
|
46138
|
+
ctx.fillRect(0, 0, w, h);
|
|
46139
|
+
if (p2.constraints) {
|
|
46140
|
+
for (const c of p2.constraints) {
|
|
46141
|
+
const a = bodies[c.bodyA];
|
|
46142
|
+
const b = bodies[c.bodyB];
|
|
46143
|
+
if (a && b) {
|
|
46144
|
+
const aPos = positions.get(a.id) ?? a;
|
|
46145
|
+
const bPos = positions.get(b.id) ?? b;
|
|
46146
|
+
ctx.beginPath();
|
|
46147
|
+
ctx.moveTo(aPos.x, aPos.y);
|
|
46148
|
+
ctx.lineTo(bPos.x, bPos.y);
|
|
46149
|
+
ctx.strokeStyle = "#533483";
|
|
46150
|
+
ctx.lineWidth = 1;
|
|
46151
|
+
ctx.setLineDash([4, 4]);
|
|
46152
|
+
ctx.stroke();
|
|
46153
|
+
ctx.setLineDash([]);
|
|
46154
|
+
}
|
|
46155
|
+
}
|
|
46156
|
+
}
|
|
46157
|
+
for (const body of bodies) {
|
|
46158
|
+
const pos = positions.get(body.id) ?? body;
|
|
46159
|
+
ctx.beginPath();
|
|
46160
|
+
ctx.arc(pos.x, pos.y, body.radius, 0, Math.PI * 2);
|
|
46161
|
+
ctx.fillStyle = body.color ?? "#e94560";
|
|
46162
|
+
ctx.fill();
|
|
46163
|
+
if (p2.showVelocity) {
|
|
46164
|
+
ctx.beginPath();
|
|
46165
|
+
ctx.moveTo(pos.x, pos.y);
|
|
46166
|
+
ctx.lineTo(pos.x + body.vx * 0.1, pos.y + body.vy * 0.1);
|
|
46167
|
+
ctx.strokeStyle = "#16213e";
|
|
46168
|
+
ctx.lineWidth = 2;
|
|
46169
|
+
ctx.stroke();
|
|
46170
|
+
}
|
|
46171
|
+
}
|
|
46172
|
+
};
|
|
46173
|
+
return interp.startLoop(drawInterpolated);
|
|
46174
|
+
}, [externalBodies !== void 0, interp.startLoop]);
|
|
46175
|
+
React77.useEffect(() => {
|
|
46176
|
+
if (externalBodies !== void 0) return;
|
|
45981
46177
|
if (!running) return;
|
|
45982
46178
|
let raf;
|
|
45983
46179
|
const loop = () => {
|
|
@@ -45987,10 +46183,11 @@ function SimulationCanvas({
|
|
|
45987
46183
|
};
|
|
45988
46184
|
raf = requestAnimationFrame(loop);
|
|
45989
46185
|
return () => cancelAnimationFrame(raf);
|
|
45990
|
-
}, [running, step, draw]);
|
|
46186
|
+
}, [running, step, draw, externalBodies]);
|
|
45991
46187
|
React77.useEffect(() => {
|
|
46188
|
+
if (externalBodies !== void 0) return;
|
|
45992
46189
|
draw();
|
|
45993
|
-
}, [draw]);
|
|
46190
|
+
}, [draw, externalBodies]);
|
|
45994
46191
|
React77.useEffect(() => {
|
|
45995
46192
|
if (typeof window === "undefined") return;
|
|
45996
46193
|
const canvas = canvasRef.current;
|
|
@@ -46016,136 +46213,10 @@ var init_SimulationCanvas = __esm({
|
|
|
46016
46213
|
init_atoms2();
|
|
46017
46214
|
init_verificationRegistry();
|
|
46018
46215
|
init_presets();
|
|
46216
|
+
init_useRenderInterpolation();
|
|
46019
46217
|
SimulationCanvas.displayName = "SimulationCanvas";
|
|
46020
46218
|
}
|
|
46021
46219
|
});
|
|
46022
|
-
function SimulationControls({
|
|
46023
|
-
running,
|
|
46024
|
-
speed,
|
|
46025
|
-
parameters,
|
|
46026
|
-
onPlay,
|
|
46027
|
-
onPause,
|
|
46028
|
-
onStep,
|
|
46029
|
-
onReset,
|
|
46030
|
-
onSpeedChange,
|
|
46031
|
-
onParameterChange,
|
|
46032
|
-
className
|
|
46033
|
-
}) {
|
|
46034
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "md", className, children: [
|
|
46035
|
-
/* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { gap: "sm", align: "center", children: [
|
|
46036
|
-
running ? /* @__PURE__ */ jsxRuntime.jsx(exports.Button, { size: "sm", variant: "secondary", onClick: onPause, icon: LucideIcons2.Pause, children: "Pause" }) : /* @__PURE__ */ jsxRuntime.jsx(exports.Button, { size: "sm", variant: "primary", onClick: onPlay, icon: LucideIcons2.Play, children: "Play" }),
|
|
46037
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Button, { size: "sm", variant: "ghost", onClick: onStep, icon: LucideIcons2.SkipForward, disabled: running, children: "Step" }),
|
|
46038
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Button, { size: "sm", variant: "ghost", onClick: onReset, icon: LucideIcons2.RotateCcw, children: "Reset" })
|
|
46039
|
-
] }),
|
|
46040
|
-
/* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "xs", children: [
|
|
46041
|
-
/* @__PURE__ */ jsxRuntime.jsxs(exports.Typography, { variant: "caption", color: "muted", children: [
|
|
46042
|
-
"Speed: ",
|
|
46043
|
-
speed.toFixed(1),
|
|
46044
|
-
"x"
|
|
46045
|
-
] }),
|
|
46046
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
46047
|
-
"input",
|
|
46048
|
-
{
|
|
46049
|
-
type: "range",
|
|
46050
|
-
min: 0.1,
|
|
46051
|
-
max: 5,
|
|
46052
|
-
step: 0.1,
|
|
46053
|
-
value: speed,
|
|
46054
|
-
onChange: (e) => onSpeedChange(parseFloat(e.target.value)),
|
|
46055
|
-
className: "w-full"
|
|
46056
|
-
}
|
|
46057
|
-
)
|
|
46058
|
-
] }),
|
|
46059
|
-
Object.entries(parameters).map(([name, param]) => /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "xs", children: [
|
|
46060
|
-
/* @__PURE__ */ jsxRuntime.jsxs(exports.Typography, { variant: "caption", color: "muted", children: [
|
|
46061
|
-
param.label,
|
|
46062
|
-
": ",
|
|
46063
|
-
param.value.toFixed(2)
|
|
46064
|
-
] }),
|
|
46065
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
46066
|
-
"input",
|
|
46067
|
-
{
|
|
46068
|
-
type: "range",
|
|
46069
|
-
min: param.min,
|
|
46070
|
-
max: param.max,
|
|
46071
|
-
step: param.step,
|
|
46072
|
-
value: param.value,
|
|
46073
|
-
onChange: (e) => onParameterChange(name, parseFloat(e.target.value)),
|
|
46074
|
-
className: "w-full"
|
|
46075
|
-
}
|
|
46076
|
-
)
|
|
46077
|
-
] }, name))
|
|
46078
|
-
] });
|
|
46079
|
-
}
|
|
46080
|
-
var init_SimulationControls = __esm({
|
|
46081
|
-
"components/game/organisms/physics-sim/SimulationControls.tsx"() {
|
|
46082
|
-
init_atoms2();
|
|
46083
|
-
SimulationControls.displayName = "SimulationControls";
|
|
46084
|
-
}
|
|
46085
|
-
});
|
|
46086
|
-
function SimulationGraph({
|
|
46087
|
-
label,
|
|
46088
|
-
unit,
|
|
46089
|
-
data,
|
|
46090
|
-
maxPoints = 200,
|
|
46091
|
-
width = 300,
|
|
46092
|
-
height = 120,
|
|
46093
|
-
color = "#e94560",
|
|
46094
|
-
className
|
|
46095
|
-
}) {
|
|
46096
|
-
const canvasRef = React77.useRef(null);
|
|
46097
|
-
const visibleData = data.slice(-maxPoints);
|
|
46098
|
-
React77.useEffect(() => {
|
|
46099
|
-
const canvas = canvasRef.current;
|
|
46100
|
-
if (!canvas || visibleData.length < 2) return;
|
|
46101
|
-
const ctx = canvas.getContext("2d");
|
|
46102
|
-
if (!ctx) return;
|
|
46103
|
-
ctx.clearRect(0, 0, width, height);
|
|
46104
|
-
ctx.fillStyle = "#0f0f23";
|
|
46105
|
-
ctx.fillRect(0, 0, width, height);
|
|
46106
|
-
ctx.strokeStyle = "#1a1a3e";
|
|
46107
|
-
ctx.lineWidth = 0.5;
|
|
46108
|
-
for (let i = 0; i < 5; i++) {
|
|
46109
|
-
const y = height / 5 * i;
|
|
46110
|
-
ctx.beginPath();
|
|
46111
|
-
ctx.moveTo(0, y);
|
|
46112
|
-
ctx.lineTo(width, y);
|
|
46113
|
-
ctx.stroke();
|
|
46114
|
-
}
|
|
46115
|
-
let minVal = Infinity;
|
|
46116
|
-
let maxVal = -Infinity;
|
|
46117
|
-
for (const pt of visibleData) {
|
|
46118
|
-
if (pt.value < minVal) minVal = pt.value;
|
|
46119
|
-
if (pt.value > maxVal) maxVal = pt.value;
|
|
46120
|
-
}
|
|
46121
|
-
const range = maxVal - minVal || 1;
|
|
46122
|
-
const pad = height * 0.1;
|
|
46123
|
-
ctx.beginPath();
|
|
46124
|
-
ctx.strokeStyle = color;
|
|
46125
|
-
ctx.lineWidth = 2;
|
|
46126
|
-
for (let i = 0; i < visibleData.length; i++) {
|
|
46127
|
-
const x = i / (maxPoints - 1) * width;
|
|
46128
|
-
const y = pad + (maxVal - visibleData[i].value) / range * (height - 2 * pad);
|
|
46129
|
-
if (i === 0) ctx.moveTo(x, y);
|
|
46130
|
-
else ctx.lineTo(x, y);
|
|
46131
|
-
}
|
|
46132
|
-
ctx.stroke();
|
|
46133
|
-
const last = visibleData[visibleData.length - 1];
|
|
46134
|
-
ctx.fillStyle = color;
|
|
46135
|
-
ctx.font = "12px monospace";
|
|
46136
|
-
ctx.fillText(`${last.value.toFixed(2)} ${unit}`, width - 80, 16);
|
|
46137
|
-
}, [visibleData, width, height, color, unit, maxPoints]);
|
|
46138
|
-
return /* @__PURE__ */ jsxRuntime.jsx(exports.Card, { padding: "sm", className, children: /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "xs", children: [
|
|
46139
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "caption", weight: "bold", children: label }),
|
|
46140
|
-
/* @__PURE__ */ jsxRuntime.jsx("canvas", { ref: canvasRef, width, height, className: "rounded" })
|
|
46141
|
-
] }) });
|
|
46142
|
-
}
|
|
46143
|
-
var init_SimulationGraph = __esm({
|
|
46144
|
-
"components/game/organisms/physics-sim/SimulationGraph.tsx"() {
|
|
46145
|
-
init_atoms2();
|
|
46146
|
-
SimulationGraph.displayName = "SimulationGraph";
|
|
46147
|
-
}
|
|
46148
|
-
});
|
|
46149
46220
|
function SimulatorBoard({
|
|
46150
46221
|
entity,
|
|
46151
46222
|
completeEvent = "PUZZLE_COMPLETE",
|
|
@@ -48679,7 +48750,6 @@ var init_component_registry_generated = __esm({
|
|
|
48679
48750
|
init_Navigation();
|
|
48680
48751
|
init_NegotiatorBoard();
|
|
48681
48752
|
init_NumberStepper();
|
|
48682
|
-
init_ObjectRulePanel();
|
|
48683
48753
|
init_OptionConstraintGroup();
|
|
48684
48754
|
init_OrbitalVisualization();
|
|
48685
48755
|
init_Overlay();
|
|
@@ -48710,7 +48780,6 @@ var init_component_registry_generated = __esm({
|
|
|
48710
48780
|
init_ResourceBar();
|
|
48711
48781
|
init_ResourceCounter();
|
|
48712
48782
|
init_RichBlockEditor();
|
|
48713
|
-
init_RuleEditor();
|
|
48714
48783
|
init_RuntimeDebugger2();
|
|
48715
48784
|
init_ScaledDiagram();
|
|
48716
48785
|
init_ScoreBoard();
|
|
@@ -48730,8 +48799,6 @@ var init_component_registry_generated = __esm({
|
|
|
48730
48799
|
init_SignaturePad();
|
|
48731
48800
|
init_SimpleGrid();
|
|
48732
48801
|
init_SimulationCanvas();
|
|
48733
|
-
init_SimulationControls();
|
|
48734
|
-
init_SimulationGraph();
|
|
48735
48802
|
init_SimulatorBoard();
|
|
48736
48803
|
init_Skeleton();
|
|
48737
48804
|
init_SocialProof();
|
|
@@ -48749,7 +48816,6 @@ var init_component_registry_generated = __esm({
|
|
|
48749
48816
|
init_StateArchitectBoard();
|
|
48750
48817
|
init_StateIndicator();
|
|
48751
48818
|
init_StateMachineView();
|
|
48752
|
-
init_StateNode();
|
|
48753
48819
|
init_StatsGrid();
|
|
48754
48820
|
init_StatsOrganism();
|
|
48755
48821
|
init_StatusDot();
|
|
@@ -48788,8 +48854,6 @@ var init_component_registry_generated = __esm({
|
|
|
48788
48854
|
init_Tooltip();
|
|
48789
48855
|
init_TraitFrame();
|
|
48790
48856
|
init_TraitSlot();
|
|
48791
|
-
init_TraitStateViewer();
|
|
48792
|
-
init_TransitionArrow();
|
|
48793
48857
|
init_TrendIndicator();
|
|
48794
48858
|
init_TurnIndicator();
|
|
48795
48859
|
init_TurnPanel();
|
|
@@ -48799,7 +48863,6 @@ var init_component_registry_generated = __esm({
|
|
|
48799
48863
|
init_UncontrolledBattleBoard();
|
|
48800
48864
|
init_UnitCommandBar();
|
|
48801
48865
|
init_UploadDropZone();
|
|
48802
|
-
init_VariablePanel();
|
|
48803
48866
|
init_VersionDiff();
|
|
48804
48867
|
init_ViolationAlert();
|
|
48805
48868
|
init_VoteStack();
|
|
@@ -49009,7 +49072,6 @@ var init_component_registry_generated = __esm({
|
|
|
49009
49072
|
"Navigation": exports.Navigation,
|
|
49010
49073
|
"NegotiatorBoard": NegotiatorBoard,
|
|
49011
49074
|
"NumberStepper": exports.NumberStepper,
|
|
49012
|
-
"ObjectRulePanel": ObjectRulePanel,
|
|
49013
49075
|
"OptionConstraintGroup": exports.OptionConstraintGroup,
|
|
49014
49076
|
"OrbitalVisualization": exports.OrbitalVisualization,
|
|
49015
49077
|
"Overlay": exports.Overlay,
|
|
@@ -49040,7 +49102,6 @@ var init_component_registry_generated = __esm({
|
|
|
49040
49102
|
"ResourceBar": ResourceBar,
|
|
49041
49103
|
"ResourceCounter": ResourceCounter,
|
|
49042
49104
|
"RichBlockEditor": exports.RichBlockEditor,
|
|
49043
|
-
"RuleEditor": RuleEditor,
|
|
49044
49105
|
"RuntimeDebugger": RuntimeDebugger,
|
|
49045
49106
|
"ScaledDiagram": exports.ScaledDiagram,
|
|
49046
49107
|
"ScoreBoard": ScoreBoard,
|
|
@@ -49060,8 +49121,6 @@ var init_component_registry_generated = __esm({
|
|
|
49060
49121
|
"SignaturePad": exports.SignaturePad,
|
|
49061
49122
|
"SimpleGrid": exports.SimpleGrid,
|
|
49062
49123
|
"SimulationCanvas": SimulationCanvas,
|
|
49063
|
-
"SimulationControls": SimulationControls,
|
|
49064
|
-
"SimulationGraph": SimulationGraph,
|
|
49065
49124
|
"SimulatorBoard": SimulatorBoard,
|
|
49066
49125
|
"Skeleton": Skeleton,
|
|
49067
49126
|
"SocialProof": exports.SocialProof,
|
|
@@ -49082,7 +49141,6 @@ var init_component_registry_generated = __esm({
|
|
|
49082
49141
|
"StateArchitectBoard": StateArchitectBoard,
|
|
49083
49142
|
"StateIndicator": StateIndicator,
|
|
49084
49143
|
"StateMachineView": exports.StateMachineView,
|
|
49085
|
-
"StateNode": StateNode2,
|
|
49086
49144
|
"StatsGrid": exports.StatsGrid,
|
|
49087
49145
|
"StatsOrganism": exports.StatsOrganism,
|
|
49088
49146
|
"StatusDot": exports.StatusDot,
|
|
@@ -49121,8 +49179,6 @@ var init_component_registry_generated = __esm({
|
|
|
49121
49179
|
"Tooltip": exports.Tooltip,
|
|
49122
49180
|
"TraitFrame": TraitFrame,
|
|
49123
49181
|
"TraitSlot": TraitSlot,
|
|
49124
|
-
"TraitStateViewer": TraitStateViewer,
|
|
49125
|
-
"TransitionArrow": TransitionArrow,
|
|
49126
49182
|
"TrendIndicator": exports.TrendIndicator,
|
|
49127
49183
|
"TurnIndicator": TurnIndicator,
|
|
49128
49184
|
"TurnPanel": TurnPanel,
|
|
@@ -49133,7 +49189,6 @@ var init_component_registry_generated = __esm({
|
|
|
49133
49189
|
"UnitCommandBar": UnitCommandBar,
|
|
49134
49190
|
"UploadDropZone": exports.UploadDropZone,
|
|
49135
49191
|
"VStack": exports.VStack,
|
|
49136
|
-
"VariablePanel": VariablePanel,
|
|
49137
49192
|
"VersionDiff": exports.VersionDiff,
|
|
49138
49193
|
"ViolationAlert": exports.ViolationAlert,
|
|
49139
49194
|
"VoteStack": exports.VoteStack,
|
|
@@ -50897,8 +50952,131 @@ init_NegotiatorBoard();
|
|
|
50897
50952
|
|
|
50898
50953
|
// components/game/organisms/physics-sim/index.ts
|
|
50899
50954
|
init_SimulationCanvas();
|
|
50900
|
-
|
|
50901
|
-
|
|
50955
|
+
|
|
50956
|
+
// components/game/organisms/physics-sim/SimulationControls.tsx
|
|
50957
|
+
init_atoms2();
|
|
50958
|
+
function SimulationControls({
|
|
50959
|
+
running,
|
|
50960
|
+
speed,
|
|
50961
|
+
parameters,
|
|
50962
|
+
onPlay,
|
|
50963
|
+
onPause,
|
|
50964
|
+
onStep,
|
|
50965
|
+
onReset,
|
|
50966
|
+
onSpeedChange,
|
|
50967
|
+
onParameterChange,
|
|
50968
|
+
className
|
|
50969
|
+
}) {
|
|
50970
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "md", className, children: [
|
|
50971
|
+
/* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { gap: "sm", align: "center", children: [
|
|
50972
|
+
running ? /* @__PURE__ */ jsxRuntime.jsx(exports.Button, { size: "sm", variant: "secondary", onClick: onPause, icon: LucideIcons2.Pause, children: "Pause" }) : /* @__PURE__ */ jsxRuntime.jsx(exports.Button, { size: "sm", variant: "primary", onClick: onPlay, icon: LucideIcons2.Play, children: "Play" }),
|
|
50973
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Button, { size: "sm", variant: "ghost", onClick: onStep, icon: LucideIcons2.SkipForward, disabled: running, children: "Step" }),
|
|
50974
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Button, { size: "sm", variant: "ghost", onClick: onReset, icon: LucideIcons2.RotateCcw, children: "Reset" })
|
|
50975
|
+
] }),
|
|
50976
|
+
/* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "xs", children: [
|
|
50977
|
+
/* @__PURE__ */ jsxRuntime.jsxs(exports.Typography, { variant: "caption", color: "muted", children: [
|
|
50978
|
+
"Speed: ",
|
|
50979
|
+
speed.toFixed(1),
|
|
50980
|
+
"x"
|
|
50981
|
+
] }),
|
|
50982
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
50983
|
+
"input",
|
|
50984
|
+
{
|
|
50985
|
+
type: "range",
|
|
50986
|
+
min: 0.1,
|
|
50987
|
+
max: 5,
|
|
50988
|
+
step: 0.1,
|
|
50989
|
+
value: speed,
|
|
50990
|
+
onChange: (e) => onSpeedChange(parseFloat(e.target.value)),
|
|
50991
|
+
className: "w-full"
|
|
50992
|
+
}
|
|
50993
|
+
)
|
|
50994
|
+
] }),
|
|
50995
|
+
Object.entries(parameters).map(([name, param]) => /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "xs", children: [
|
|
50996
|
+
/* @__PURE__ */ jsxRuntime.jsxs(exports.Typography, { variant: "caption", color: "muted", children: [
|
|
50997
|
+
param.label,
|
|
50998
|
+
": ",
|
|
50999
|
+
param.value.toFixed(2)
|
|
51000
|
+
] }),
|
|
51001
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
51002
|
+
"input",
|
|
51003
|
+
{
|
|
51004
|
+
type: "range",
|
|
51005
|
+
min: param.min,
|
|
51006
|
+
max: param.max,
|
|
51007
|
+
step: param.step,
|
|
51008
|
+
value: param.value,
|
|
51009
|
+
onChange: (e) => onParameterChange(name, parseFloat(e.target.value)),
|
|
51010
|
+
className: "w-full"
|
|
51011
|
+
}
|
|
51012
|
+
)
|
|
51013
|
+
] }, name))
|
|
51014
|
+
] });
|
|
51015
|
+
}
|
|
51016
|
+
SimulationControls.displayName = "SimulationControls";
|
|
51017
|
+
|
|
51018
|
+
// components/game/organisms/physics-sim/SimulationGraph.tsx
|
|
51019
|
+
init_atoms2();
|
|
51020
|
+
function SimulationGraph({
|
|
51021
|
+
label,
|
|
51022
|
+
unit,
|
|
51023
|
+
data,
|
|
51024
|
+
maxPoints = 200,
|
|
51025
|
+
width = 300,
|
|
51026
|
+
height = 120,
|
|
51027
|
+
color = "#e94560",
|
|
51028
|
+
className
|
|
51029
|
+
}) {
|
|
51030
|
+
const canvasRef = React77.useRef(null);
|
|
51031
|
+
const visibleData = data.slice(-maxPoints);
|
|
51032
|
+
React77.useEffect(() => {
|
|
51033
|
+
const canvas = canvasRef.current;
|
|
51034
|
+
if (!canvas || visibleData.length < 2) return;
|
|
51035
|
+
const ctx = canvas.getContext("2d");
|
|
51036
|
+
if (!ctx) return;
|
|
51037
|
+
ctx.clearRect(0, 0, width, height);
|
|
51038
|
+
ctx.fillStyle = "#0f0f23";
|
|
51039
|
+
ctx.fillRect(0, 0, width, height);
|
|
51040
|
+
ctx.strokeStyle = "#1a1a3e";
|
|
51041
|
+
ctx.lineWidth = 0.5;
|
|
51042
|
+
for (let i = 0; i < 5; i++) {
|
|
51043
|
+
const y = height / 5 * i;
|
|
51044
|
+
ctx.beginPath();
|
|
51045
|
+
ctx.moveTo(0, y);
|
|
51046
|
+
ctx.lineTo(width, y);
|
|
51047
|
+
ctx.stroke();
|
|
51048
|
+
}
|
|
51049
|
+
let minVal = Infinity;
|
|
51050
|
+
let maxVal = -Infinity;
|
|
51051
|
+
for (const pt of visibleData) {
|
|
51052
|
+
if (pt.value < minVal) minVal = pt.value;
|
|
51053
|
+
if (pt.value > maxVal) maxVal = pt.value;
|
|
51054
|
+
}
|
|
51055
|
+
const range = maxVal - minVal || 1;
|
|
51056
|
+
const pad = height * 0.1;
|
|
51057
|
+
ctx.beginPath();
|
|
51058
|
+
ctx.strokeStyle = color;
|
|
51059
|
+
ctx.lineWidth = 2;
|
|
51060
|
+
for (let i = 0; i < visibleData.length; i++) {
|
|
51061
|
+
const x = i / (maxPoints - 1) * width;
|
|
51062
|
+
const y = pad + (maxVal - visibleData[i].value) / range * (height - 2 * pad);
|
|
51063
|
+
if (i === 0) ctx.moveTo(x, y);
|
|
51064
|
+
else ctx.lineTo(x, y);
|
|
51065
|
+
}
|
|
51066
|
+
ctx.stroke();
|
|
51067
|
+
const last = visibleData[visibleData.length - 1];
|
|
51068
|
+
ctx.fillStyle = color;
|
|
51069
|
+
ctx.font = "12px monospace";
|
|
51070
|
+
ctx.fillText(`${last.value.toFixed(2)} ${unit}`, width - 80, 16);
|
|
51071
|
+
}, [visibleData, width, height, color, unit, maxPoints]);
|
|
51072
|
+
return /* @__PURE__ */ jsxRuntime.jsx(exports.Card, { padding: "sm", className, children: /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "xs", children: [
|
|
51073
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "caption", weight: "bold", children: label }),
|
|
51074
|
+
/* @__PURE__ */ jsxRuntime.jsx("canvas", { ref: canvasRef, width, height, className: "rounded" })
|
|
51075
|
+
] }) });
|
|
51076
|
+
}
|
|
51077
|
+
SimulationGraph.displayName = "SimulationGraph";
|
|
51078
|
+
|
|
51079
|
+
// components/game/organisms/physics-sim/index.ts
|
|
50902
51080
|
init_presets();
|
|
50903
51081
|
|
|
50904
51082
|
// components/game/organisms/types/game.ts
|