From 09d54aa5259e9655b04ef538cb9a1be5c3124b22 Mon Sep 17 00:00:00 2001 From: Sysy's Date: Tue, 31 Mar 2026 09:46:29 +0200 Subject: [PATCH] Add diagonal lasers --- web/assets/css/game.css | 9 +++++- web/assets/js/game.js | 68 +++++++++++++++++++++++++---------------- 2 files changed, 50 insertions(+), 27 deletions(-) diff --git a/web/assets/css/game.css b/web/assets/css/game.css index 3a7f56c..065e5e3 100644 --- a/web/assets/css/game.css +++ b/web/assets/css/game.css @@ -71,7 +71,6 @@ main { .empty { background-color: #DADEEF; - border-color: #DADEEF; } .empty:hover { @@ -113,6 +112,14 @@ main { background: linear-gradient(to right, transparent 0%, transparent 45%, red 45%, red 55%, transparent 55%, transparent 100%), #DADEEF; } +.laser-diagonal-down { + background: linear-gradient(45deg, transparent 0%, transparent 46%, red 46%, red 54%, transparent 54%, transparent 100%), #DADEEF; +} + +.laser-diagonal-up { + background: linear-gradient(135deg, transparent 0%, transparent 46%, red 46%, red 54%, transparent 54%, transparent 100%), #DADEEF; +} + /* ================================ MIRROR ================================ */ diff --git a/web/assets/js/game.js b/web/assets/js/game.js index f9337cf..db6ea50 100644 --- a/web/assets/js/game.js +++ b/web/assets/js/game.js @@ -33,6 +33,45 @@ let laserDirection = { dx: 0, dy: 0 }; let laserSegments = {}; let mirrorOrientations = {}; +function normalizeLaserDirection(dx, dy) { + const epsilon = 0.0001; + const normalizedDx = Math.abs(dx) < epsilon ? 0 : Math.sign(dx); + const normalizedDy = Math.abs(dy) < epsilon ? 0 : Math.sign(dy); + + return { dx: normalizedDx, dy: normalizedDy }; +} + +function reflectLaser(direction, mirrorAngle) { + const mirrorRadians = mirrorAngle * (Math.PI / 180); + const mirrorVectorX = Math.cos(mirrorRadians); + const mirrorVectorY = Math.sin(mirrorRadians); + const dotProduct = (direction.dx * mirrorVectorX) + (direction.dy * mirrorVectorY); + const reflectedDx = (2 * dotProduct * mirrorVectorX) - direction.dx; + const reflectedDy = (2 * dotProduct * mirrorVectorY) - direction.dy; + + return normalizeLaserDirection(reflectedDx, reflectedDy); +} + +function getLaserSegmentClass(segmentDirection) { + if (!segmentDirection) { + return "laser-horizontal"; + } + + if (segmentDirection.dx === 0) { + return "laser-vertical"; + } + + if (segmentDirection.dy === 0) { + return "laser-horizontal"; + } + + if (segmentDirection.dx === segmentDirection.dy) { + return "laser-diagonal-down"; + } + + return "laser-diagonal-up"; +} + function initializeMirrorOrientations() { mirrorOrientations = {}; // Reset for (let y = 0; y < level1.length; y++) { @@ -105,11 +144,7 @@ function loadGrid() { case legend.ligthLaser: cell.classList.add("light-laser"); const segmentDirection = laserSegments[`${y},${x}`]; - if (segmentDirection && segmentDirection.dx === 0) { - cell.classList.add("laser-vertical"); - } else { - cell.classList.add("laser-horizontal"); - } + cell.classList.add(getLaserSegmentClass(segmentDirection)); break; } @@ -134,7 +169,7 @@ function rotateMirror(x, y, isRightClick) { let currentAngle = mirrorOrientations[coordKey] || 0; // Rotation and normalize negative angles to [0, 360) - currentAngle = (currentAngle + (isRightClick ? 45 : -45)) % 360; + currentAngle = (currentAngle + (isRightClick ? 22.5 : -22.5)) % 360; if (currentAngle < 0) { currentAngle += 360; } @@ -223,26 +258,7 @@ function traceLaser() { case legend.mirror: const mirrorAngle = mirrorOrientations[`${currentY},${currentX}`] || 0; - - 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; - } - } + laserDirection = reflectLaser(laserDirection, mirrorAngle); break; case legend.wall: