From 36fa5a909275773dd73c36f8380c614a4300da02 Mon Sep 17 00:00:00 2001 From: Sysy's Date: Tue, 31 Mar 2026 13:34:27 +0200 Subject: [PATCH] Support per-level game element configs Convert global config maps (initialMirrorAngles, buttonGroups, doorGroups, captorGroups, rotatorButtons) into per-level arrays and add getCurrentLevelConfig(levelConfigs) helper. Update getButtonGroup, getDoorGroup, getCaptorGroup, getRotatorButtonConfig, isMirrorControlledByButton, syncRotatorButtons and initializeMirrorOrientations to pull configs for the current level. Also tweak a couple of level tiles and add a rotator button config for the third level ("3,7": { mirrorX: 7, mirrorY: 7, step: -22.5, intervalMs: 1000 }) while keeping empty objects for levels without overrides. These changes enable per-level customization of mirrors, buttons, doors, captors and rotators. --- web/assets/js/game.js | 81 +++++++++++++++++++++++++++++-------------- 1 file changed, 55 insertions(+), 26 deletions(-) diff --git a/web/assets/js/game.js b/web/assets/js/game.js index 03321a2..49ee375 100644 --- a/web/assets/js/game.js +++ b/web/assets/js/game.js @@ -66,11 +66,11 @@ let levels = [ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 11, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0, 10, 6, 0, 0, 0, 0], - [0, 0, 0, 0, 3, 16, 16, 20, 0, 3, 6, 0, 0, 0, 0], + [0, 0, 0, 3, 0, 16, 16, 20, 0, 3, 6, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 6, 0, 0, 0, 0], [0, 0, 0, 0, 12, 6, 6, 6, 6, 6, 9, 0, 0, 0, 0], [0, 0, 0, 0, 6, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 6, 0, 0, 0, 3, 0, 7, 0, 0, 0, 0], + [0, 0, 0, 0, 6, 0, 0, 3, 0, 0, 7, 0, 0, 0, 0], [0, 0, 0, 0, 6, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 10, 6, 6, 6, 6, 6, 0, 0, 0, 0, 0], ], @@ -92,26 +92,50 @@ let levels = [ let currentLevelIndex = 0; -const initialMirrorAngles = { - "6,4": 315, - "4,3": 315, -}; +const initialMirrorAngles = [ + { + "6,4": 315, + }, + {}, + { + "3,4": 315, + "7,8": 0, + }, +]; -const buttonGroups = { - "4,6": 1, - "4,7": 2, -}; +const buttonGroups = [ + { + "4,6": 1, + }, + {}, + {}, +]; -const doorGroups = { - "4,7": 1, - "4,8": 2, -}; +const doorGroups = [ + { + "4,7": 1, + }, + { + "4,6": 1, + }, + {}, +]; -const captorGroups = { -}; +const captorGroups = [ + {}, + { + "2,6": 1, + }, + {}, +]; -const rotatorButtons = { -}; +const rotatorButtons = [ + {}, + {}, + { + "3,7": { mirrorX: 7, mirrorY: 7, step: -22.5, intervalMs: 1000 }, + }, +]; let laserDirection = { dx: 0, dy: 0 }; let laserSegments = {}; @@ -129,6 +153,10 @@ function getCurrentLevel() { return levels[currentLevelIndex]; } +function getCurrentLevelConfig(configByLevel) { + return configByLevel[currentLevelIndex] || {}; +} + function normalizeLaserDirection(dx, dy) { const epsilon = 0.0001; const normalizedDx = Math.abs(dx) < epsilon ? 0 : Math.sign(dx); @@ -186,15 +214,15 @@ function getButtonGroup(x, y) { return 2; } - return buttonGroups[`${y},${x}`] || 1; + return getCurrentLevelConfig(buttonGroups)[`${y},${x}`] || 1; } function getDoorGroup(x, y) { - return doorGroups[`${y},${x}`] || 1; + return getCurrentLevelConfig(doorGroups)[`${y},${x}`] || 1; } function getCaptorGroup(x, y) { - return captorGroups[`${y},${x}`] || getDoorGroup(x, y); + return getCurrentLevelConfig(captorGroups)[`${y},${x}`] || getDoorGroup(x, y); } function openDoorsFromButton(x, y) { @@ -226,11 +254,11 @@ function toggleDoorsFromCaptor(x, y) { } function getRotatorButtonConfig(x, y) { - return rotatorButtons[`${y},${x}`]; + return getCurrentLevelConfig(rotatorButtons)[`${y},${x}`]; } function isMirrorControlledByButton(x, y) { - const rotatorEntries = Object.values(rotatorButtons); + const rotatorEntries = Object.values(getCurrentLevelConfig(rotatorButtons)); for (let i = 0; i < rotatorEntries.length; i++) { const rotatorConfig = rotatorEntries[i]; @@ -261,11 +289,12 @@ function rotateMirrorStep(x, y, angleStep) { } function syncRotatorButtons() { - const rotatorKeys = Object.keys(rotatorButtons); + const currentLevelRotatorButtons = getCurrentLevelConfig(rotatorButtons); + const rotatorKeys = Object.keys(currentLevelRotatorButtons); for (let i = 0; i < rotatorKeys.length; i++) { const key = rotatorKeys[i]; - const config = rotatorButtons[key]; + const config = currentLevelRotatorButtons[key]; const isActive = activeRotatorButtons[key] === true; if (isActive && !rotatorIntervals[key]) { @@ -425,7 +454,7 @@ function initializeMirrorOrientations() { for (let y = 0; y < level.length; y++) { for (let x = 0; x < level[y].length; x++) { if (level[y][x] === legend.mirror) { - mirrorOrientations[`${y},${x}`] = initialMirrorAngles[`${y},${x}`] || 0; + mirrorOrientations[`${y},${x}`] = getCurrentLevelConfig(initialMirrorAngles)[`${y},${x}`] || 0; } } }