diff --git a/web/assets/css/game.css b/web/assets/css/game.css
index 30c5e00..e23411f 100644
--- a/web/assets/css/game.css
+++ b/web/assets/css/game.css
@@ -16,7 +16,7 @@ body {
display: flex;
align-items: center;
justify-content: center;
- font-family: 'Arial', sans-serif;
+ font-family: Arial, sans-serif;
user-select: none;
}
@@ -61,29 +61,18 @@ main {
flex-wrap: wrap;
}
-/* ================================
- GRID
-================================ */
-
.map {
display: flex;
flex-direction: column;
- gap: 0px;
padding: 10px;
- background: #DADEEF;
+ background: #dadeef;
border-radius: 5px;
}
.lign {
display: flex;
- gap: 0px;
- margin: 0;
}
-/* ================================
- CELLS
-================================ */
-
.cell {
width: clamp(28px, 5.5vmin, 60px);
height: clamp(28px, 5.5vmin, 60px);
@@ -91,7 +80,6 @@ main {
display: flex;
align-items: center;
justify-content: center;
- margin: 0;
position: relative;
background-color: #2a2a2a;
user-select: none;
@@ -102,12 +90,8 @@ main {
outline: 2px dashed rgba(0, 0, 0, 0.2);
}
-/* ================================
- CASES TYPE
-================================ */
-
.empty {
- background-color: #DADEEF;
+ background-color: #dadeef;
}
.empty:hover {
@@ -148,14 +132,16 @@ main {
.door {
background-color: #DADEEF;
background-image: url("../img/tiles/WoodenDoor.svg");
- transform: rotate(90deg);
- background-size: 100%;
+ background-size: contain;
background-repeat: no-repeat;
- background-position: center;
+ background-position: end;
}
.door-open {
- opacity: 0.5;
+ background-image: url("../img/tiles/WoodenDoor_openned.svg");
+ background-size: contain;
+ background-repeat: no-repeat;
+ background-position: end;
}
.button {
@@ -166,18 +152,18 @@ main {
background-position: center;
}
-.button-active {
- opacity: 0.7;
-}
-
-.demi-wall {
+.button-2 {
background-color: #DADEEF;
- background-image: url("../img/tiles/VerticaleSemi.svg");
- background-size: 100%;
+ background-image: url("../img/tiles/ButtonQuarter.svg"), url("../img/tiles/Tuile.svg");
+ background-size: 100% 100%;
background-repeat: no-repeat;
background-position: center;
}
+.button-active {
+ opacity: 0.7;
+}
+
.target {
background-color: #DADEEF;
background-image: url("../img/tiles/Trigger.svg");
@@ -218,41 +204,57 @@ main {
background-position: center;
}
-/* ================================
- LIGHT LASER
-================================ */
-
-.light-laser {
- position: relative;
+.laser-overlay {
+ position: absolute;
+ inset: 0;
+ pointer-events: none;
+ z-index: 2;
}
.laser-horizontal {
- background: linear-gradient(to bottom, transparent 0%, transparent 45%, red 45%, red 55%, transparent 55%, transparent 100%), #DADEEF
+ --laser-color: red;
+ background: linear-gradient(to bottom, transparent 0%, transparent 45%, var(--laser-color) 45%, var(--laser-color) 55%, transparent 55%, transparent 100%);
}
.laser-vertical {
- background: linear-gradient(to right, transparent 0%, transparent 45%, red 45%, red 55%, transparent 55%, transparent 100%), #DADEEF;
+ --laser-color: red;
+ background: linear-gradient(to right, transparent 0%, transparent 45%, var(--laser-color) 45%, var(--laser-color) 55%, transparent 55%, transparent 100%);
}
.laser-diagonal-down {
- background: linear-gradient(45deg, transparent 0%, transparent 46%, red 46%, red 54%, transparent 54%, transparent 100%), #DADEEF;
+ --laser-color: red;
+ background: linear-gradient(45deg, transparent 0%, transparent 46%, var(--laser-color) 46%, var(--laser-color) 54%, transparent 54%, transparent 100%);
}
.laser-diagonal-up {
- background: linear-gradient(135deg, transparent 0%, transparent 46%, red 46%, red 54%, transparent 54%, transparent 100%), #DADEEF;
+ --laser-color: red;
+ background: linear-gradient(135deg, transparent 0%, transparent 46%, var(--laser-color) 46%, var(--laser-color) 54%, transparent 54%, transparent 100%);
}
-/* ================================
- MIRROR
-================================ */
+.laser-color-white {
+ --laser-color: #f8f8f8;
+}
+
+.laser-color-red {
+ --laser-color: #ff3b30;
+}
+
+.laser-color-blue {
+ --laser-color: #2d7ff9;
+}
+
+.laser-color-yellow {
+ --laser-color: #ffd400;
+}
.btn-mirror {
background: none;
border: none;
cursor: pointer;
- height: 100%;
width: 100%;
+ height: 100%;
position: relative;
+ z-index: 3;
display: flex;
align-items: center;
justify-content: center;
@@ -262,35 +264,60 @@ main {
width: 80%;
height: 80%;
object-fit: contain;
+ pointer-events: none;
}
-.button-door {
- background: none;
+.glass-item {
+ width: 54px;
+ height: 54px;
border: none;
- cursor: pointer;
- width: 100%;
- height: 100%;
- position: absolute;
- inset: 0;
+ border-radius: 10px;
+ cursor: grab;
+ position: relative;
+ box-shadow: inset 0 0 0 2px rgba(0, 0, 0, 0.1);
+ user-select: none;
+ color: #223;
+ font-size: 0.8rem;
+ font-weight: bold;
}
-/* ================================
- RESPONSIVE
-================================ */
+.glass-item::after,
+.cell-glass::after {
+ content: "";
+ position: absolute;
+ inset: 10px;
+ border-radius: 8px;
+ background: rgba(255, 255, 255, 0.45);
+ border: 1px solid rgba(255, 255, 255, 0.8);
+}
+
+.glass-red {
+ background: rgba(255, 59, 48, 0.85);
+}
+
+.glass-blue {
+ background: rgba(45, 127, 249, 0.85);
+}
+
+.glass-yellow {
+ background: rgba(255, 212, 0, 0.9);
+}
+
+.cell-glass {
+ position: absolute;
+ inset: 5px;
+ border-radius: 8px;
+ opacity: 0.9;
+ pointer-events: none;
+ z-index: 4;
+}
@media (max-width: 600px) {
.map {
padding: 5px;
- border-radius: 3px;
}
main {
padding: 8px;
}
}
-
-@media (max-height: 500px) {
- .map {
- padding: 4px;
- }
-}
diff --git a/web/assets/img/tiles/WoodenDoor.svg b/web/assets/img/tiles/WoodenDoor.svg
index 970a126..bead2b3 100644
--- a/web/assets/img/tiles/WoodenDoor.svg
+++ b/web/assets/img/tiles/WoodenDoor.svg
@@ -1,46 +1,49 @@
-
\ No newline at end of file
diff --git a/web/assets/img/tiles/WoodenDoor_openned.svg b/web/assets/img/tiles/WoodenDoor_openned.svg
new file mode 100644
index 0000000..0c07c55
--- /dev/null
+++ b/web/assets/img/tiles/WoodenDoor_openned.svg
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/web/assets/js/game.js b/web/assets/js/game.js
index 403fb7e..c98b140 100644
--- a/web/assets/js/game.js
+++ b/web/assets/js/game.js
@@ -15,7 +15,8 @@ const legend = {
demiWallCornerDownLeft: 11,
demiWallCornerDownRight: 12,
doorOpen: 13,
-}
+ button2: 14,
+};
const laserColors = {
white: "white",
@@ -30,33 +31,46 @@ const glassOptions = [
laserColors.yellow,
];
-// Grid test
-
let levels = [
[
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[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, 4, 0, 10, 6, 0, 0, 0, 0],
- [0, 0, 0, 0, 7, 6, 6, 5, 6, 0, 6, 0, 0, 0, 0],
+ [0, 0, 0, 0, 1, 0, 5, 4, 0, 10, 6, 0, 0, 0, 0],
+ [0, 0, 0, 0, 7, 6, 6, 6, 6, 0, 6, 0, 0, 0, 0],
[0, 0, 0, 0, 3, 0, 0, 0, 0, 12, 6, 0, 0, 0, 0],
[0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 9, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- ]
-
-
+ ],
];
let currentLevelIndex = 0;
-// Function to save initial orientation of mirrors
+const initialMirrorAngles = {
+ "6,4": 315,
+};
+
+const buttonGroups = {
+ "4,6": 1,
+};
+
+const doorGroups = {
+ "4,7": 1,
+};
+
let laserDirection = { dx: 0, dy: 0 };
let laserSegments = {};
let mirrorOrientations = {};
+let glassPlacements = {};
let activatedButtons = {};
let openedDoors = {};
+let isLevelFinished = false;
+
+function getCurrentLevel() {
+ return levels[currentLevelIndex];
+}
function normalizeLaserDirection(dx, dy) {
const epsilon = 0.0001;
@@ -77,6 +91,13 @@ function reflectLaser(direction, mirrorAngle) {
return normalizeLaserDirection(reflectedDx, reflectedDy);
}
+function reverseLaser(direction) {
+ return {
+ dx: direction.dx * -1,
+ dy: direction.dy * -1,
+ };
+}
+
function getLaserSegmentClass(segmentDirection) {
if (!segmentDirection) {
return "laser-horizontal";
@@ -97,59 +118,190 @@ function getLaserSegmentClass(segmentDirection) {
return "laser-diagonal-up";
}
-function openAdjacentDoors(x, y) {
- // Open adjacent doors (up, down, left, right)
- const directions = [
- { dx: 0, dy: -1 },
- { dx: 0, dy: 1 },
- { dx: -1, dy: 0 },
- { dx: 1, dy: 0 }
- ];
+function getLaserColorClass(color) {
+ return `laser-color-${color || laserColors.white}`;
+}
- for (let dir of directions) {
- const newX = x + dir.dx;
- const newY = y + dir.dy;
-
- if (newX >= 0 && newX < levels[currentLevelIndex][0].length &&
- newY >= 0 && newY < levels[currentLevelIndex].length) {
- if (levels[currentLevelIndex][newY][newX] === legend.door) {
- openedDoors[`${newY},${newX}`] = true;
- levels[currentLevelIndex][newY][newX] = legend.doorOpen; // Change state to open
+function getButtonGroup(x, y) {
+ const cellType = getCurrentLevel()[y][x];
+
+ if (cellType === legend.button2) {
+ return 2;
+ }
+
+ return buttonGroups[`${y},${x}`] || 1;
+}
+
+function getDoorGroup(x, y) {
+ return doorGroups[`${y},${x}`] || 1;
+}
+
+function openDoorsFromButton(x, y) {
+ const buttonGroup = getButtonGroup(x, y);
+ const level = getCurrentLevel();
+
+ for (let doorY = 0; doorY < level.length; doorY++) {
+ for (let doorX = 0; doorX < level[doorY].length; doorX++) {
+ if (level[doorY][doorX] === legend.door && getDoorGroup(doorX, doorY) === buttonGroup) {
+ openedDoors[`${doorY},${doorX}`] = true;
}
}
}
+}
- loadGrid(); // Refresh grid to show opened doors
+function saveLaserSegment(x, y, direction, color) {
+ laserSegments[`${y},${x}`] = {
+ direction: { ...direction },
+ color: color,
+ };
+}
+
+function isGlassOnCell(x, y) {
+ return glassPlacements[`${y},${x}`] !== undefined;
+}
+
+function drawGlassInCell(cell, x, y) {
+ const glassColor = glassPlacements[`${y},${x}`];
+
+ if (!glassColor) {
+ return;
+ }
+
+ const glassDiv = document.createElement("div");
+ glassDiv.classList.add("cell-glass", `glass-${glassColor}`);
+ cell.appendChild(glassDiv);
+}
+
+function drawLaserInCell(cell, segmentData) {
+ if (!segmentData) {
+ return;
+ }
+
+ const laserDiv = document.createElement("div");
+ laserDiv.classList.add("laser-overlay");
+ laserDiv.classList.add(getLaserSegmentClass(segmentData.direction));
+ laserDiv.classList.add(getLaserColorClass(segmentData.color));
+ cell.appendChild(laserDiv);
+}
+
+function createPalette() {
+ const palette = document.getElementById("glass-palette");
+
+ if (!palette) {
+ return;
+ }
+
+ palette.innerHTML = "";
+
+ for (let i = 0; i < glassOptions.length; i++) {
+ const glassColor = glassOptions[i];
+ const glassButton = document.createElement("button");
+ glassButton.type = "button";
+ glassButton.classList.add("glass-item", `glass-${glassColor}`);
+ glassButton.draggable = true;
+ glassButton.addEventListener("dragstart", (event) => {
+ event.dataTransfer.effectAllowed = "copy";
+ event.dataTransfer.setData("application/x-glass-color", glassColor);
+ });
+
+ palette.appendChild(glassButton);
+ }
+}
+
+function addDropEvents(cell, x, y) {
+ cell.addEventListener("dragover", (event) => {
+ if (isLevelFinished) {
+ return;
+ }
+
+ if (!event.dataTransfer.types.includes("application/x-glass-color")) {
+ return;
+ }
+
+ const cellType = getCurrentLevel()[y][x];
+ if (cellType !== legend.empty) {
+ return;
+ }
+
+ event.preventDefault();
+ cell.classList.add("can-drop");
+ });
+
+ cell.addEventListener("dragleave", () => {
+ cell.classList.remove("can-drop");
+ });
+
+ cell.addEventListener("drop", (event) => {
+ if (isLevelFinished) {
+ return;
+ }
+
+ const selectedColor = event.dataTransfer.getData("application/x-glass-color");
+ cell.classList.remove("can-drop");
+
+ if (!selectedColor) {
+ return;
+ }
+
+ if (getCurrentLevel()[y][x] !== legend.empty) {
+ return;
+ }
+
+ event.preventDefault();
+ glassPlacements[`${y},${x}`] = selectedColor;
+ traceLaser();
+ });
+
+ cell.addEventListener("dblclick", () => {
+ if (isLevelFinished) {
+ return;
+ }
+
+ if (isGlassOnCell(x, y)) {
+ delete glassPlacements[`${y},${x}`];
+ traceLaser();
+ }
+ });
+}
+
+function blockBrowserDrop() {
+ document.addEventListener("dragover", (event) => {
+ event.preventDefault();
+ });
+
+ document.addEventListener("drop", (event) => {
+ event.preventDefault();
+ });
}
function initializeMirrorOrientations() {
- mirrorOrientations = {}; // Reset
- for (let y = 0; y < levels[currentLevelIndex].length; y++) {
- for (let x = 0; x < levels[currentLevelIndex][y].length; x++) {
- if (levels[currentLevelIndex][y][x] === legend.mirror) {
- mirrorOrientations[`${y},${x}`] = 0; // Default angle
+ mirrorOrientations = {};
+ const level = getCurrentLevel();
+
+ 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;
}
}
}
}
-
-// Function to print grid
-let mirrorCoordinates = [];
-
function loadGrid() {
- const mapDiv = document.getElementById("map"); // Div with map in DOM
+ const mapDiv = document.getElementById("map");
+ const level = getCurrentLevel();
mapDiv.innerHTML = "";
- for (let y = 0; y < levels[currentLevelIndex].length; y++) {
+ for (let y = 0; y < level.length; y++) {
const lign = document.createElement("div");
lign.classList.add("lign");
- for (let x = 0; x < levels[currentLevelIndex][y].length; x++) {
+ for (let x = 0; x < level[y].length; x++) {
const cell = document.createElement("div");
cell.classList.add("cell");
+ addDropEvents(cell, x, y);
- switch (levels[currentLevelIndex][y][x]) {
+ switch (level[y][x]) {
case legend.empty:
cell.classList.add("empty");
break;
@@ -160,25 +312,25 @@ function loadGrid() {
cell.classList.add("colored-laser");
break;
case legend.mirror:
+ cell.classList.add("mirror");
const currentAngle = mirrorOrientations[`${y},${x}`] || 0;
const btnMirror = document.createElement("button");
btnMirror.classList.add("btn-mirror");
btnMirror.type = "button";
- btnMirror.style.transform = `rotate(${currentAngle}deg)`;
const img = document.createElement("img");
img.src = "../../assets/img/tiles/Mirror.svg";
- img.style.rotate = `${currentAngle}deg`;
- img.className = "mirror-img";
+ img.classList.add("mirror-img");
+ img.style.transform = `rotate(${currentAngle}deg)`;
btnMirror.appendChild(img);
- btnMirror.onmousedown = (e) => {
- e.preventDefault();
- e.stopPropagation();
- rotateMirror(x, y, e.button === 2);
+ btnMirror.onmousedown = (event) => {
+ event.preventDefault();
+ event.stopPropagation();
+ if (!isLevelFinished) {
+ rotateMirror(x, y, event.button === 2);
+ }
};
- btnMirror.oncontextmenu = (e) => e.preventDefault();
-
+ btnMirror.oncontextmenu = (event) => event.preventDefault();
cell.appendChild(btnMirror);
- cell.classList.add("mirror");
break;
case legend.door:
cell.classList.add("door");
@@ -186,22 +338,20 @@ function loadGrid() {
cell.classList.add("door-open");
}
break;
+ case legend.doorOpen:
+ cell.classList.add("door", "door-open");
+ break;
case legend.button:
cell.classList.add("button");
if (activatedButtons[`${y},${x}`]) {
cell.classList.add("button-active");
}
- let button = document.createElement("button");
- button.classList.add("button-door");
- button.type = "button";
- button.onclick = () => {
- activatedButtons[`${y},${x}`] = !activatedButtons[`${y},${x}`];
- if (activatedButtons[`${y},${x}`]) {
- openAdjacentDoors(x, y);
- }
- traceLaser();
- };
- cell.appendChild(button);
+ break;
+ case legend.button2:
+ cell.classList.add("button", "button-2");
+ if (activatedButtons[`${y},${x}`]) {
+ cell.classList.add("button-active");
+ }
break;
case legend.wall:
cell.classList.add("wall");
@@ -209,11 +359,6 @@ function loadGrid() {
case legend.target:
cell.classList.add("target");
break;
- case legend.ligthLaser:
- cell.classList.add("light-laser");
- const segmentDirection = laserSegments[`${y},${x}`];
- cell.classList.add(getLaserSegmentClass(segmentDirection));
- break;
case legend.demiWallCornerUpLeft:
cell.classList.add("demi-wall-corner-up-left");
break;
@@ -226,11 +371,10 @@ function loadGrid() {
case legend.demiWallCornerDownRight:
cell.classList.add("demi-wall-corner-down-right");
break;
- case legend.doorOpen:
- cell.classList.add("door-open");
- break;
}
+ drawLaserInCell(cell, laserSegments[`${y},${x}`]);
+ drawGlassInCell(cell, x, y);
lign.appendChild(cell);
}
@@ -238,89 +382,76 @@ function loadGrid() {
}
}
-loadGrid();
-
-// Function to rotate mirror
-
function rotateMirror(x, y, isRightClick) {
const coordKey = `${y},${x}`;
- if (levels[currentLevelIndex][y][x] !== legend.mirror) {
+ if (getCurrentLevel()[y][x] !== legend.mirror) {
return;
}
let currentAngle = mirrorOrientations[coordKey] || 0;
-
- // Rotation and normalize negative angles to [0, 360)
currentAngle = (currentAngle + (isRightClick ? 22.5 : -22.5)) % 360;
+
if (currentAngle < 0) {
currentAngle += 360;
}
- // Save
mirrorOrientations[coordKey] = currentAngle;
-
- // Print laser light
- traceLaser(true);
+ traceLaser();
}
-
-// Function to trace
-
-let isLevelFinished = false;
-
function traceLaser() {
- // Reset light laser from previous trace
laserSegments = {};
- // Ne pas réinitialiser activatedButtons et openedDoors pour préserver l'état des boutons manuels
- for (let y = 0; y < levels[currentLevelIndex].length; y++) {
- for (let x = 0; x < levels[currentLevelIndex][y].length; x++) {
- if (levels[currentLevelIndex][y][x] === legend.ligthLaser) {
- levels[currentLevelIndex][y][x] = legend.empty;
- }
- }
- }
+ activatedButtons = {};
+ openedDoors = {};
+ isLevelFinished = false;
+ const level = getCurrentLevel();
let startLaserX;
let startLaserY;
- // Search laser
- for (let y = 0; y < levels[currentLevelIndex].length; y++) {
- for (let x = 0; x < levels[currentLevelIndex][y].length; x++) {
- if (levels[currentLevelIndex][y][x] === legend.laser) {
+ for (let y = 0; y < level.length; y++) {
+ for (let x = 0; x < level[y].length; x++) {
+ if (level[y][x] === legend.laser) {
startLaserX = x;
startLaserY = y;
laserDirection = { dx: 1, dy: 0 };
break;
}
}
- if (startLaserX !== undefined) break;
+
+ if (startLaserX !== undefined) {
+ break;
+ }
}
- // If laser not found -> return
if (startLaserX === undefined) {
return;
}
let currentX = startLaserX;
let currentY = startLaserY;
+ let currentLaserColor = laserColors.white;
let laserActive = true;
- const maxIterations = 1000; // Prevent infinite loops
let iterations = 0;
+ const maxIterations = 1000;
while (laserActive && iterations < maxIterations) {
iterations++;
-
currentX += laserDirection.dx;
currentY += laserDirection.dy;
- // Out of bounds
- if (currentX < 0 || currentX >= levels[currentLevelIndex][0].length || currentY < 0 || currentY >= levels[currentLevelIndex].length) {
+ if (currentX < 0 || currentX >= level[0].length || currentY < 0 || currentY >= level.length) {
laserActive = false;
break;
}
- const cellType = levels[currentLevelIndex][currentY][currentX];
+ const cellType = level[currentY][currentX];
+ const glassColor = glassPlacements[`${currentY},${currentX}`];
+
+ if (glassColor) {
+ currentLaserColor = glassColor;
+ }
switch (cellType) {
case legend.laser:
@@ -329,68 +460,80 @@ function traceLaser() {
break;
case legend.empty:
- levels[currentLevelIndex][currentY][currentX] = legend.ligthLaser;
- laserSegments[`${currentY},${currentX}`] = { ...laserDirection };
+ saveLaserSegment(currentX, currentY, laserDirection, currentLaserColor);
break;
case legend.target:
- levels[currentLevelIndex][currentY][currentX] = legend.ligthLaser;
- laserSegments[`${currentY},${currentX}`] = { ...laserDirection };
+ saveLaserSegment(currentX, currentY, laserDirection, currentLaserColor);
laserActive = false;
isLevelFinished = true;
break;
case legend.mirror:
- const mirrorAngle = mirrorOrientations[`${currentY},${currentX}`] || 0;
- laserDirection = reflectLaser(laserDirection, mirrorAngle);
+ if (currentLaserColor === laserColors.yellow) {
+ saveLaserSegment(currentX, currentY, laserDirection, currentLaserColor);
+ } else {
+ const mirrorAngle = mirrorOrientations[`${currentY},${currentX}`] || 0;
+ laserDirection = reflectLaser(laserDirection, mirrorAngle);
+ }
break;
case legend.wall:
- laserActive = false;
- break;
-
- case legend.door:
- if (openedDoors[`${currentY},${currentX}`]) {
- // La porte est ouverte, le laser la traverse
- levels[currentLevelIndex][currentY][currentX] = legend.ligthLaser;
- laserSegments[`${currentY},${currentX}`] = { ...laserDirection };
+ if (currentLaserColor === laserColors.blue) {
+ laserDirection = reverseLaser(laserDirection);
+ } else if (currentLaserColor === laserColors.yellow) {
+ saveLaserSegment(currentX, currentY, laserDirection, currentLaserColor);
} else {
- // La porte est fermée, le laser s'arrête
laserActive = false;
}
break;
+ case legend.door:
case legend.doorOpen:
- // Porte ouverte - le laser la traverse
- levels[currentLevelIndex][currentY][currentX] = legend.ligthLaser;
- laserSegments[`${currentY},${currentX}`] = { ...laserDirection };
+ if (openedDoors[`${currentY},${currentX}`] || cellType === legend.doorOpen) {
+ saveLaserSegment(currentX, currentY, laserDirection, currentLaserColor);
+ } else if (currentLaserColor === laserColors.blue) {
+ laserDirection = reverseLaser(laserDirection);
+ } else if (currentLaserColor === laserColors.yellow) {
+ saveLaserSegment(currentX, currentY, laserDirection, currentLaserColor);
+ } else {
+ laserActive = false;
+ }
break;
case legend.button:
- // Activer le bouton et ouvrir les portes adjacentes
- activatedButtons[`${currentY},${currentX}`] = true;
- openAdjacentDoors(currentX, currentY);
- levels[currentLevelIndex][currentY][currentX] = legend.ligthLaser;
- laserSegments[`${currentY},${currentX}`] = { ...laserDirection };
- laserActive = false;
+ case legend.button2:
+ if (currentLaserColor === laserColors.red) {
+ activatedButtons[`${currentY},${currentX}`] = true;
+ openDoorsFromButton(currentX, currentY);
+ saveLaserSegment(currentX, currentY, laserDirection, currentLaserColor);
+ } else if (currentLaserColor === laserColors.yellow) {
+ saveLaserSegment(currentX, currentY, laserDirection, currentLaserColor);
+ } else if (currentLaserColor === laserColors.blue) {
+ laserDirection = reverseLaser(laserDirection);
+ } else {
+ laserActive = false;
+ }
break;
case legend.demiWallCornerUpLeft:
laserDirection = reflectLaser(laserDirection, 135);
break;
+
case legend.demiWallCornerUpRight:
laserDirection = reflectLaser(laserDirection, 45);
break;
+
case legend.demiWallCornerDownLeft:
- laserDirection = reflectLaser(laserDirection, 45);
+ laserDirection = reflectLaser(laserDirection, 225);
break;
+
case legend.demiWallCornerDownRight:
laserDirection = reflectLaser(laserDirection, 315);
break;
default:
- levels[currentLevelIndex][currentY][currentX] = legend.ligthLaser;
- laserSegments[`${currentY},${currentX}`] = { ...laserDirection };
+ saveLaserSegment(currentX, currentY, laserDirection, currentLaserColor);
break;
}
}
@@ -402,22 +545,13 @@ function traceLaser() {
}
}
-traceLaser();
-
-// Reset level state
-function resetLevel() {
- activatedButtons = {};
- openedDoors = {};
- laserSegments = {};
- laserDirection = { dx: 0, dy: 0 };
- isLevelFinished = false;
- initializeMirrorOrientations();
- traceLaser();
-}
-
-// If level finishh -> call this function
function finish() {
setTimeout(() => {
- alert("Réussi !");
+ alert("Reussi !");
}, 100);
}
+
+createPalette();
+initializeMirrorOrientations();
+blockBrowserDrop();
+traceLaser();
diff --git a/web/templates/view/game.html b/web/templates/view/game.html
index d90f9e9..970a953 100644
--- a/web/templates/view/game.html
+++ b/web/templates/view/game.html
@@ -5,10 +5,30 @@
Game
+
+
-
+
+
+
+
+
+
+
+
-