From 3e6a2130e9c6f65796efbcfa8cb0f52e4d9ee28d Mon Sep 17 00:00:00 2001 From: Pierre Date: Mon, 30 Mar 2026 16:48:53 +0200 Subject: [PATCH] Laser print and reflect --- web/assets/css/game.css | 5 +- web/assets/js/game.js | 195 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 178 insertions(+), 22 deletions(-) diff --git a/web/assets/css/game.css b/web/assets/css/game.css index 636c7c2..607036e 100644 --- a/web/assets/css/game.css +++ b/web/assets/css/game.css @@ -113,9 +113,8 @@ main { } .light-laser { - margin-top: 14px; - height: 7px; + height: 2px; width: 35px; background-color: red; - display: flex; + background-size: 2px 35px; } \ No newline at end of file diff --git a/web/assets/js/game.js b/web/assets/js/game.js index 84934e2..e8f36d7 100644 --- a/web/assets/js/game.js +++ b/web/assets/js/game.js @@ -5,7 +5,7 @@ const legend = { laser: 1, coloredLaser: 2, mirror: 3, - door:4, + door: 4, button: 5, wall: 6, demiWall: 7, @@ -15,35 +15,51 @@ const legend = { // Grid test -let grid = [ - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 3, 0, 0], +let level1 = [ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 3, 0, 0, 0, 8, 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, 0, 0, 0, 0], + [0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 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], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], ] +// Function to save initial orientation of mirrors +let laserDirection = { dx: 0, dy: 0 }; +let mirrorOrientations = {}; + +function initializeMirrorOrientations() { + mirrorOrientations = {}; // Reset + for (let y = 0; y < level1.length; y++) { + for (let x = 0; x < level1[y].length; x++) { + if (level1[y][x] === legend.mirror) { + mirrorOrientations[`${y},${x}`] = 0; // Default angle + } + } + } +} + + // Function to print grid let mirrorCoordinates = []; -function loadGrid () { +function loadGrid() { const mapDiv = document.getElementById("map"); // Div with map in DOM mapDiv.innerHTML = ""; - for (let y = 0; y < grid.length; y++) { + for (let y = 0; y < level1.length; y++) { const lign = document.createElement("div"); lign.classList.add("lign"); - for (let x = 0; x < grid[y].length; x++) { + for (let x = 0; x < level1[y].length; x++) { const cell = document.createElement("div"); cell.classList.add("cell"); - switch (grid[y][x]) { + switch (level1[y][x]) { case legend.empty: cell.classList.add("empty"); break; @@ -54,10 +70,11 @@ function loadGrid () { cell.classList.add("colored-laser"); break; case legend.mirror: + const currentAngle = mirrorOrientations[`${y},${x}`] || 0; const btnMirror = document.createElement("button"); btnMirror.classList.add("btn-mirror"); - btnMirror.addEventListener("click", () => rotateMirror(btnMirror)); - btnMirror.style.transform = "rotate(0deg)"; + btnMirror.addEventListener("click", () => rotateMirror(btnMirror, x, y)); + btnMirror.style.transform = `rotate(${currentAngle}deg)`; btnMirror.style.width = "100%"; cell.appendChild(btnMirror); cell.classList.add("mirror"); @@ -82,10 +99,10 @@ function loadGrid () { break; } - lign.appendChild(cell); + lign.appendChild(cell); } - mapDiv.appendChild(lign); + mapDiv.appendChild(lign); } } @@ -93,12 +110,152 @@ loadGrid(); // Function to rotate mirror -function rotateMirror(mirror) { - let angle = 0; - if (mirror.style.transform == "") { - angle = 0; - } else { - angle = parseInt(mirror.style.transform.split("(")[1].split("deg")[0])%360; +function rotateMirror(mirrorElement, x, y) { + const coordKey = `${y},${x}`; + let currentAngle = mirrorOrientations[coordKey] || 0; + + // Rotation 45° + currentAngle = (currentAngle + 45) % 360; + mirrorOrientations[coordKey] = currentAngle; + + // New rotation + mirrorElement.style.transform = `rotate(${currentAngle}deg)`; + + // Print laser light + traceLaser(true); +} + + +// Function to trace + +let isLevelFinished = false; + +function traceLaser() { + // Reset light laser from previous trace + for (let y = 0; y < level1.length; y++) { + for (let x = 0; x < level1[y].length; x++) { + if (level1[y][x] === legend.ligthLaser) { + level1[y][x] = legend.empty; + } + } } - mirror.style.transform = `rotate(${angle+45}deg)`; + + let startLaserX; + let startLaserY; + + // Search laser + for (let y = 0; y < level1.length; y++) { + for (let x = 0; x < level1[y].length; x++) { + if (level1[y][x] === legend.laser) { + startLaserX = x; + startLaserY = y; + laserDirection = { dx: 1, dy: 0 }; + break; + } + } + if (startLaserX !== undefined) break; + } + + // If laser not found -> return + if (startLaserX === undefined) { + return; + } + + let currentX = startLaserX; + let currentY = startLaserY; + let laserActive = true; + const maxIterations = 1000; // Prevent infinite loops + let iterations = 0; + + while (laserActive && iterations < maxIterations) { + iterations++; + + currentX += laserDirection.dx; + currentY += laserDirection.dy; + + // Out of bounds + if (currentX < 0 || currentX >= level1[0].length || currentY < 0 || currentY >= level1.length) { + laserActive = false; + break; + } + + const cellType = level1[currentY][currentX]; + + switch (cellType) { + case legend.laser: + case legend.coloredLaser: + laserActive = false; + break; + + case legend.empty: + level1[currentY][currentX] = legend.ligthLaser; + break; + + case legend.target: + level1[currentY][currentX] = legend.ligthLaser; + laserActive = false; + isLevelFinished = true; + break; + + case legend.mirror: + // Change direction based on mirror angle + const mirrorAngle = mirrorOrientations[`${currentY},${currentX}`] || 0; + + // 0° or 180°: reflect horizontal + if (mirrorAngle === 0 || mirrorAngle === 180) { + laserDirection.dy = -laserDirection.dy; + } else { + if (mirrorAngle === 90 || mirrorAngle === 270) { + laserDirection.dx = -laserDirection.dx; + } + + if (mirrorAngle === 45 || mirrorAngle === 225) { + const tempDx = laserDirection.dx; + laserDirection.dx = laserDirection.dy; + laserDirection.dy = tempDx; + } + + if (mirrorAngle === 135 || mirrorAngle === 315) { + const tempDx = laserDirection.dx; + laserDirection.dx = -laserDirection.dy; + laserDirection.dy = -tempDx; + } + } + break; + + case legend.wall: + laserActive = false; + break; + + case legend.demiWall: + laserActive = false; + break; + + case legend.door: + laserActive = false; + break; + + case legend.button: + level1[currentY][currentX] = legend.ligthLaser; + laserActive = false; + break; + + default: + level1[currentY][currentX] = legend.ligthLaser; + break; + } + } + + loadGrid(); + + if (isLevelFinished) { + finish(); + } +} + +traceLaser(); + +// If level finishh -> call this function +function finish() { + alert("Réussi !"); } \ No newline at end of file