2 Commits

Author SHA1 Message Date
Sysy's
9b1e2ccf6d Use root-relative path for index.css
Update stylesheet link in view template from '../../assets/css/index.css' to '/assets/css/index.css' so the CSS resolves from the site root. This prevents broken styling when the page is accessed from nested routes or different template contexts.
2026-03-30 15:20:49 +02:00
Sysy's
68421a71df Add hero page HTML and responsive CSS
Add a new landing view and stylesheet for MirrorGame. Creates web/templates/view/index.html (hero layout with image, play button, and left/right ad banner iframes) and web/assets/css/index.css (CSS variables, Inter font import, hero layout, responsive breakpoints, and .hero-play-button styles). Provides responsive behavior and positioning for ads and hero components.
2026-03-30 15:09:09 +02:00
8 changed files with 272 additions and 887 deletions

1
backend/.gitignore vendored
View File

@@ -1 +0,0 @@
/target

View File

@@ -1,297 +0,0 @@
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html,
body {
width: 100vw;
height: 100vh;
overflow: hidden;
}
body {
background: #f7f7f7;
display: flex;
align-items: center;
justify-content: center;
font-family: 'Arial', sans-serif;
user-select: none;
}
main {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 20px;
border-radius: 10px;
min-width: fit-content;
flex-shrink: 0;
gap: 16px;
}
.game-layout {
width: min(95vw, 1000px);
}
.toolbox {
width: 100%;
background: #dfe5f8;
border-radius: 10px;
padding: 14px;
display: flex;
flex-direction: column;
gap: 10px;
}
.toolbox h2 {
font-size: 1rem;
}
.toolbox p {
font-size: 0.9rem;
color: #334;
}
.glass-palette {
display: flex;
gap: 10px;
flex-wrap: wrap;
}
/* ================================
GRID
================================ */
.map {
display: flex;
flex-direction: column;
gap: 0px;
padding: 10px;
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);
transition: all 0.2s ease;
display: flex;
align-items: center;
justify-content: center;
margin: 0;
position: relative;
background-color: #2a2a2a;
user-select: none;
overflow: hidden;
}
.cell.can-drop {
outline: 2px dashed rgba(0, 0, 0, 0.2);
}
/* ================================
CASES TYPE
================================ */
.empty {
background-color: #DADEEF;
}
.empty:hover {
background-color: #333333;
}
.laser {
background-color: #f5f5f5;
border: 2px solid #d8d8d8;
}
.colored-laser {
background-color: #ffa726;
}
.mirror {
background-color: #DADEEF;
border-color: #444444;
position: relative;
overflow: hidden;
}
.wall {
background-color: #0729c0;
}
.door {
background-color: #6d4c41;
}
.door-open {
background-color: #bca89c;
}
.button {
background-color: #7cb342;
}
.button-2 {
background-color: #ff8f00;
}
.button-active {
background-color: #c6ff00;
}
.target {
background: #00FF00;
}
/* ================================
LIGHT LASER
================================ */
.light-laser {
position: relative;
}
.laser-overlay {
position: absolute;
inset: 0;
pointer-events: none;
z-index: 2;
}
.laser-horizontal {
--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 {
--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 {
--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 {
--laser-color: red;
background: linear-gradient(135deg, transparent 0%, transparent 46%, var(--laser-color) 46%, var(--laser-color) 54%, transparent 54%, transparent 100%);
}
.laser-color-white {
--laser-color: #f8f8f8;
}
.laser-color-red {
--laser-color: #ff3b30;
}
.laser-color-blue {
--laser-color: #2d7ff9;
}
.laser-color-yellow {
--laser-color: #ffd400;
}
/* ================================
MIRROR
================================ */
.btn-mirror {
background: none;
border: none;
cursor: pointer;
height: 100%;
position: relative;
z-index: 3;
}
.btn-mirror::after {
content: '';
position: absolute;
top: 50%;
left: 10%;
width: 80%;
height: 2px;
background-color: #aaaaaa;
transform-origin: center;
}
.glass-item {
width: 54px;
height: 54px;
border: none;
border-radius: 10px;
cursor: grab;
position: relative;
box-shadow: inset 0 0 0 2px rgba(0, 0, 0, 0.1);
user-select: none;
}
.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;
}
/* ================================
RESPONSIVE
================================ */
@media (max-width: 600px) {
.map {
padding: 5px;
border-radius: 3px;
}
main {
padding: 8px;
}
}
@media (max-height: 500px) {
.map {
padding: 4px;
}
}

244
web/assets/css/index.css Normal file
View File

@@ -0,0 +1,244 @@
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap');
* {
--clr-light-a0: #ffffff;
--clr-light-a10: #f4f4f4;
--clr-light-a20: #e0e0e0;
--clr-light-a30: #c2c2c2;
--clr-light-a40: #a3a3a3;
--clr-light-a50: #858585;
--clr-dark: #000000;
--clr-surface-a0: #FFF6E5;
--clr-surface-a10: #f7f7f7;
--clr-surface-a20: #DADEEF;
--clr-surface-a30: #e0e0e0;
--clr-surface-a40: #d1d1d1;
--clr-surface-a50: #c2c2c2;
box-sizing: border-box;
}
html {
font-size: 100%;
}
body {
background-color: var(--clr-surface-a0);
font-family: 'Inter', sans-serif;
margin: 0;
padding: 0;
}
.hero {
position: relative;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
min-height: 100vh;
gap: 3rem;
padding: 2rem clamp(1rem, 4vw, 3rem);
box-sizing: border-box;
background: var(--clr-surface-a10);
}
.adsbanner {
position: absolute;
top: 50%;
left: clamp(0.75rem, 3vw, 2.5rem);
transform: translateY(-50%);
z-index: 5;
width: clamp(160px, 22vw, 300px);
aspect-ratio: 9 / 16;
box-shadow: 0 18px 40px rgba(0,0,0,0.18);
}
.adsbanner.is-hidden {
display: none;
}
.leftadsbanner {
position: absolute;
top: 50%;
right: clamp(0.75rem, 3vw, 2.5rem);
transform: translateY(-50%);
z-index: 5;
width: clamp(160px, 22vw, 300px);
aspect-ratio: 9 / 16;
}
.hero-content {
max-width: 90vw;
text-align: left;
display: flex;
flex-direction: column;
align-items: center;
background: var(--clr-surface-a20);
border-radius: 1.5rem;
padding: 2rem clamp(2rem, 8vw, 10rem);
box-shadow: 0px 0px 27px 14px rgba(0,0,0,0.2);
}
.hero-content-text {
width: 100%;
}
.hero h1 {
color: var(--clr-dark);
font-size: clamp(2.5rem, 7vw, 4rem);
margin: 0 0 1rem 0;
line-height: 1.1;
word-break: break-word;
text-shadow: none;
}
.hero-content button {
margin-top: 2rem;
align-self: center;
}
.hero img {
max-width: 400px;
width: 35vw;
min-width: 180px;
height: auto;
border-radius: 1.5rem;
box-shadow: 0 6px 32px rgba(0,0,0,.10);
flex-shrink: 1;
background: var(--clr-surface-a0);
}
/* --- RESPONSIVE HERO-PLAY-BUTTON FIXES --- */
@media (max-width: 900px) {
.hero {
flex-direction: column;
text-align: center;
gap: 2rem;
padding: 1.5rem;
}
.hero-content {
max-width: 100vw;
text-align: center;
padding: 2rem;
}
.hero-content {
align-items: center;
}
.adsbanner {
left: 1rem;
width: clamp(130px, 24vw, 220px);
}
.leftadsbanner {
right: 1rem;
width: clamp(130px, 24vw, 220px);
}
.hero img {
max-width: 70vw;
min-width: 0;
}
.hero-play-button {
padding: 1rem 4vw;
font-size: 1.1rem;
min-width: min(220px, 70vw);
max-width: 90vw;
}
.hero-play-button svg {
width: 2em;
height: 1em;
min-width: 1.25em;
min-height: 1em;
margin-right: 0.5em;
flex-shrink: 0;
}
}
@media (max-width: 600px) {
.hero {
min-height: 70vh;
padding: 0.5rem;
}
.hero-content {
padding: 1.5rem;
}
.hero h1 {
font-size: clamp(2rem, 9vw, 2.5rem);
}
.hero p {
font-size: clamp(1rem, 5vw, 1.15rem);
}
.adsbanner {
top: 1rem;
left: 0.75rem;
transform: none;
width: clamp(110px, 30vw, 170px);
border-radius: 1rem;
}
.leftadsbanner {
right: 0.75rem;
width: clamp(110px, 30vw, 170px);
border-radius: 1rem;
}
.hero img {
max-width: 100%;
border-radius: 1rem;
box-shadow: 0 2px 12px rgba(0,0,0,.07);
}
.hero-play-button {
padding: 0.85rem 3vw;
min-width: min(120px, 92vw);
max-width: 96vw;
font-size: 1rem;
}
.hero-play-button svg {
width: 1.3em;
height: 1em;
min-width: 1em;
min-height: 1em;
margin-right: 0.45em;
flex-shrink: 0;
}
}
.hero-play-button {
font-family: inherit;
font-size: 20px;
background: #8ea3fd;
color: white;
padding: 1rem 10rem;
display: flex;
align-items: center;
justify-content: center; /* Ensure SVG/button content is horizontally centered */
border: none;
border-radius: 50px;
overflow: hidden;
transition: all 0.2s;
cursor: pointer;
box-shadow: 0 2px 8px rgba(30, 80, 255, 0.10);
/* Button grows/shrinks with container at low widths */
width: 100%;
max-width: 500px;
min-width: 180px;
box-sizing: border-box;
}
.hero-play-button:hover {
background: #7286e0;
transform: translateY(-2px);
}
.hero-play-button:active {
transform: scale(0.95);
}
.hero-play-button svg {
width: 2em;
height: 1em;
min-width: 1.2em;
min-height: 1em;
margin-right: 0.6em;
color: var(--clr-surface-a0);
flex-shrink: 0;
flex-grow: 0;
display: inline-block;
vertical-align: middle;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

View File

@@ -1,555 +0,0 @@
// Legend of grid case
const legend = {
empty: 0,
laser: 1,
coloredLaser: 2,
mirror: 3,
door: 4,
button: 5,
wall: 6,
demiWall: 7,
target: 8,
ligthLaser: 9,
button2: 10,
}
const laserColors = {
white: "white",
red: "red",
blue: "blue",
yellow: "yellow",
};
const glassOptions = [
laserColors.red,
laserColors.blue,
laserColors.yellow,
];
// Grid test
let level1 = [
[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, 4, 0, 0, 3, 0, 7, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 5, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 0, 0, 0, 3, 5, 3, 0, 8, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
]
const initialMirrorAngles = {
"8,4": 315,
"2,4": 45,
"2,8": 315,
"6,8": 45,
};
const buttonGroups = {
"4,4": 1,
"8,5": 2,
};
const doorGroups = {
"2,5": 1,
"2,6": 2,
};
let laserDirection = { dx: 0, dy: 0 };
let laserSegments = {};
let mirrorOrientations = {};
let glassPlacements = {};
let activatedButtons = {};
let openedDoors = {};
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 getLaserColorClass(color) {
return `laser-color-${color || laserColors.white}`;
}
function reverseLaser(direction) {
return {
dx: direction.dx * -1,
dy: direction.dy * -1,
};
}
function getButtonGroup(x, y) {
const cellType = level1[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);
for (let doorY = 0; doorY < level1.length; doorY++) {
for (let doorX = 0; doorX < level1[doorY].length; doorX++) {
if (level1[doorY][doorX] === legend.door && getDoorGroup(doorX, doorY) === buttonGroup) {
openedDoors[`${doorY},${doorX}`] = true;
}
}
}
}
function saveLaserSegment(x, y, direction, color) {
laserSegments[`${y},${x}`] = {
direction: { ...direction },
color: color,
};
if (level1[y][x] === legend.empty) {
level1[y][x] = legend.ligthLaser;
}
}
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 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("text/plain", glassColor);
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;
}
if (level1[y][x] !== legend.empty && level1[y][x] !== legend.ligthLaser) {
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 (level1[y][x] !== legend.empty && level1[y][x] !== legend.ligthLaser) {
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 < level1.length; y++) {
for (let x = 0; x < level1[y].length; x++) {
if (level1[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
mapDiv.innerHTML = "";
for (let y = 0; y < level1.length; y++) {
const lign = document.createElement("div");
lign.classList.add("lign");
for (let x = 0; x < level1[y].length; x++) {
const cell = document.createElement("div");
cell.classList.add("cell");
addDropEvents(cell, x, y);
switch (level1[y][x]) {
case legend.empty:
cell.classList.add("empty");
break;
case legend.laser:
cell.classList.add("laser");
break;
case legend.coloredLaser:
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.type = "button";
btnMirror.style.transform = `rotate(${currentAngle}deg)`;
btnMirror.style.width = "100%";
btnMirror.onmousedown = (e) => {
e.preventDefault();
e.stopPropagation();
if(!isLevelFinished){
rotateMirror(x, y, e.button === 2);
}
};
btnMirror.oncontextmenu = (e) => e.preventDefault();
cell.appendChild(btnMirror);
cell.classList.add("mirror");
break;
case legend.door:
cell.classList.add("door");
if (openedDoors[`${y},${x}`]) {
cell.classList.add("door-open");
}
break;
case legend.button:
cell.classList.add("button");
if (activatedButtons[`${y},${x}`]) {
cell.classList.add("button-active");
}
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");
break;
case legend.demiWall:
cell.classList.add("demi-wall");
break;
case legend.target:
cell.classList.add("target");
break;
case legend.ligthLaser:
cell.classList.add("empty");
break;
}
const segmentData = laserSegments[`${y},${x}`];
if (segmentData) {
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);
}
drawGlassInCell(cell, x, y);
lign.appendChild(cell);
}
mapDiv.appendChild(lign);
}
}
loadGrid();
// Function to rotate mirror
function rotateMirror(x, y, isRightClick) {
const coordKey = `${y},${x}`;
if (level1[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);
}
// Function to trace
let isLevelFinished = false;
function traceLaser() {
// Reset light laser from previous trace
laserSegments = {};
activatedButtons = {};
openedDoors = {};
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;
}
}
}
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;
let currentLaserColor = laserColors.white;
const maxIterations = 1000; // Prevent infinite loops
let iterations = 0;
isLevelFinished = false;
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];
const glassColor = glassPlacements[`${currentY},${currentX}`];
if (glassColor) {
currentLaserColor = glassColor;
}
switch (cellType) {
case legend.laser:
case legend.coloredLaser:
laserActive = false;
break;
case legend.empty:
saveLaserSegment(currentX, currentY, laserDirection, currentLaserColor);
break;
case legend.target:
saveLaserSegment(currentX, currentY, laserDirection, currentLaserColor);
laserActive = false;
isLevelFinished = true;
break;
case legend.mirror:
if (currentLaserColor === laserColors.yellow) {
saveLaserSegment(currentX, currentY, laserDirection, currentLaserColor);
} else {
const mirrorAngle = mirrorOrientations[`${currentY},${currentX}`] || 0;
laserDirection = reflectLaser(laserDirection, mirrorAngle);
}
break;
case legend.wall:
if (currentLaserColor === laserColors.blue) {
laserDirection = reverseLaser(laserDirection);
} else if (currentLaserColor === laserColors.yellow) {
saveLaserSegment(currentX, currentY, laserDirection, currentLaserColor);
} else {
laserActive = false;
}
break;
case legend.demiWall:
if (currentLaserColor === laserColors.blue) {
laserDirection = reverseLaser(laserDirection);
} else if (currentLaserColor === laserColors.yellow) {
saveLaserSegment(currentX, currentY, laserDirection, currentLaserColor);
} else {
laserActive = false;
}
break;
case legend.door:
if (openedDoors[`${currentY},${currentX}`]) {
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:
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;
default:
saveLaserSegment(currentX, currentY, laserDirection, currentLaserColor);
break;
}
}
loadGrid();
if (isLevelFinished) {
finish();
}
}
createPalette();
initializeMirrorOrientations();
blockBrowserDrop();
traceLaser();
// If level finishh -> call this function
function finish() {
setTimeout(() => {
alert("Réussi !");
}, 100);
}

0
web/assets/js/index.js Normal file
View File

View File

@@ -1,34 +0,0 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../../assets/css/game.css">
<title>Game</title>
<script>(function(s){s.dataset.zone='10809858',s.src='https://n6wxm.com/vignette.min.js'})([document.documentElement, document.body].filter(Boolean).pop().appendChild(document.createElement('script')))</script>
<script>(function(s){s.dataset.zone='10809853',s.src='https://nap5k.com/tag.min.js'})([document.documentElement, document.body].filter(Boolean).pop().appendChild(document.createElement('script')))</script>
</head>
<body>
<script>
atOptions = {
'key' : '72b6ba1a1c26b9671167b66063c7e699',
'format' : 'iframe',
'height' : 600,
'width' : 160,
'params' : {}
};
</script>
<script src="https://www.highperformanceformat.com/72b6ba1a1c26b9671167b66063c7e699/invoke.js"></script>
<main class="game-layout">
<div id="map" class="map"></div>
<section class="toolbox">
<h2>Vitres tintées</h2>
<div id="glass-palette" class="glass-palette"></div>
</section>
</main>
<script src="../../assets/js/game.js" defer></script>
</body>
</html>

File diff suppressed because one or more lines are too long