diff --git a/index.html b/index.html index 5e07223..775de82 100644 --- a/index.html +++ b/index.html @@ -105,6 +105,7 @@ + diff --git a/src/main.js b/src/main.js index 74497a4..45c84bf 100644 --- a/src/main.js +++ b/src/main.js @@ -2,30 +2,13 @@ const { Engine, Render, Runner, World, Body, Constraint, Events, Vector } = Matter; - const { scenes = [], defaultSceneId } = window.PhysilinksScenes || {}; - const getSceneById = (sceneId) => - scenes.find((candidate) => candidate.id === sceneId) || null; - - const getSceneIdFromUrl = () => { - try { - const params = new URLSearchParams(window.location.search); - const urlScene = params.get("scene"); - return getSceneById(urlScene) ? urlScene : null; - } catch (err) { - return null; - } - }; - - const setSceneIdInUrl = (sceneId) => { - if (!sceneId) return; - try { - const url = new URL(window.location.href); - url.searchParams.set("scene", sceneId); - history.replaceState({}, "", `${url.pathname}${url.search}${url.hash}`); - } catch (err) { - // ignore history failures (blocked or unsupported) - } - }; + const { + scenes = [], + defaultSceneId, + order: sceneOrder = [], + } = window.PhysilinksScenes || {}; + const { getSceneById, getSceneIdFromUrl, setSceneIdInUrl, getNextSceneId } = + window.PhysilinksSceneRegistry || {}; const defaultMessageConfig = { durationMs: 4200, @@ -206,28 +189,6 @@ updateHud(); }; - const getNextSceneId = () => { - const order = window.PhysilinksScenes?.order || []; - const currentId = currentScene?.id; - const orderedExisting = order.filter((id) => - scenes.some((s) => s.id === id), - ); - if (orderedExisting.length > 0 && currentId) { - const idx = orderedExisting.indexOf(currentId); - if (idx >= 0 && idx < orderedExisting.length - 1) { - return orderedExisting[idx + 1]; - } - if (idx === orderedExisting.length - 1) { - return orderedExisting[0]; - } - } - const fallbackIdx = scenes.findIndex((s) => s.id === currentId); - if (fallbackIdx >= 0 && fallbackIdx < scenes.length - 1) { - return scenes[fallbackIdx + 1].id; - } - return scenes[0]?.id || defaultSceneId; - }; - const chain = { active: false, color: null, @@ -782,7 +743,12 @@ onPauseToggle: () => setPaused(!isPaused), onRestart: restartGame, onSceneChange: (id) => applyScene(id), - onWinNext: () => applyScene(getNextSceneId()), + onWinNext: () => + applyScene( + getNextSceneId + ? getNextSceneId(scenes, sceneOrder, currentScene) || currentScene?.id + : currentScene?.id, + ), }); ui.setSceneOptions( scenes, diff --git a/src/scene-registry.js b/src/scene-registry.js new file mode 100644 index 0000000..14c4f74 --- /dev/null +++ b/src/scene-registry.js @@ -0,0 +1,53 @@ +(() => { + const getSceneById = (scenes, sceneId) => + scenes.find((candidate) => candidate.id === sceneId) || null; + + const getSceneIdFromUrl = (scenes) => { + try { + const params = new URLSearchParams(window.location.search); + const urlScene = params.get("scene"); + return getSceneById(scenes, urlScene) ? urlScene : null; + } catch (err) { + return null; + } + }; + + const setSceneIdInUrl = (sceneId) => { + if (!sceneId) return; + try { + const url = new URL(window.location.href); + url.searchParams.set("scene", sceneId); + history.replaceState({}, "", `${url.pathname}${url.search}${url.hash}`); + } catch (err) { + // ignore history failures (blocked or unsupported) + } + }; + + const getNextSceneId = (scenes, order, currentScene) => { + const currentId = currentScene?.id; + const orderedExisting = order.filter((id) => + scenes.some((s) => s.id === id), + ); + if (orderedExisting.length > 0 && currentId) { + const idx = orderedExisting.indexOf(currentId); + if (idx >= 0 && idx < orderedExisting.length - 1) { + return orderedExisting[idx + 1]; + } + if (idx === orderedExisting.length - 1) { + return orderedExisting[0]; + } + } + const fallbackIdx = scenes.findIndex((s) => s.id === currentId); + if (fallbackIdx >= 0 && fallbackIdx < scenes.length - 1) { + return scenes[fallbackIdx + 1].id; + } + return scenes[0]?.id || null; + }; + + window.PhysilinksSceneRegistry = { + getSceneById, + getSceneIdFromUrl, + setSceneIdInUrl, + getNextSceneId, + }; +})();