ishallah
This commit is contained in:
@@ -20,6 +20,71 @@ body {
|
|||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.level-menu-shell {
|
||||||
|
position: fixed;
|
||||||
|
top: 24px;
|
||||||
|
right: 24px;
|
||||||
|
z-index: 1100;
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-menu-toggle {
|
||||||
|
border: none;
|
||||||
|
border-radius: 999px;
|
||||||
|
background: #223;
|
||||||
|
color: #fff;
|
||||||
|
padding: 12px 18px;
|
||||||
|
font-size: 0.95rem;
|
||||||
|
font-weight: 700;
|
||||||
|
cursor: pointer;
|
||||||
|
box-shadow: 0 8px 20px rgba(34, 51, 68, 0.18);
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-menu-panel {
|
||||||
|
min-width: 180px;
|
||||||
|
background: rgba(255, 255, 255, 0.96);
|
||||||
|
border-radius: 18px;
|
||||||
|
padding: 14px;
|
||||||
|
box-shadow: 0 18px 40px rgba(34, 51, 68, 0.18);
|
||||||
|
border: 1px solid rgba(34, 51, 68, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-menu-panel h2 {
|
||||||
|
font-size: 0.95rem;
|
||||||
|
color: #223;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-menu-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-menu-item {
|
||||||
|
border: none;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 10px 12px;
|
||||||
|
text-align: left;
|
||||||
|
background: #dfe5f8;
|
||||||
|
color: #223;
|
||||||
|
font-weight: 700;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-menu-item.is-current {
|
||||||
|
background: #223;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-menu-item:disabled {
|
||||||
|
background: #eceff7;
|
||||||
|
color: #8a92a3;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
main {
|
main {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -143,6 +208,22 @@ main {
|
|||||||
background-position: center;
|
background-position: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.wall-semi-angle {
|
||||||
|
background-color: #DADEEF;
|
||||||
|
background-image: url("/web/assets/img/tiles/BottomLeft.svg");
|
||||||
|
background-size: 100%;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.horizontal-semi {
|
||||||
|
background-color: #DADEEF;
|
||||||
|
background-image: url("/web/assets/img/tiles/HorizontaleSemi.svg");
|
||||||
|
background-size: 100%;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: bottom;
|
||||||
|
}
|
||||||
|
|
||||||
.captor {
|
.captor {
|
||||||
background-color: #DADEEF;
|
background-color: #DADEEF;
|
||||||
background-image: url("/web/assets/img/tiles/Capteur-1.svg");
|
background-image: url("/web/assets/img/tiles/Capteur-1.svg");
|
||||||
@@ -160,13 +241,37 @@ main {
|
|||||||
background-position: center;
|
background-position: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cable {
|
.captor-turn-reverse {
|
||||||
background-color: #DADEEF;
|
background-color: #DADEEF;
|
||||||
background-image: url("/web/assets/img/tiles/CableV.svg");
|
background-image: url("/web/assets/img/tiles/Capteur-2.svg");
|
||||||
|
background-size: 100%;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.captor-turn-horizontale2 {
|
||||||
|
background-color: #DADEEF;
|
||||||
|
background-image: url("/web/assets/img/tiles/Capteur-1.svg");
|
||||||
|
background-size: 100%;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cable {
|
||||||
|
background-color: #DADEEF;
|
||||||
|
background-image: url("/web/assets/img/tiles/CableH.svg");
|
||||||
|
background-size: 100%;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cable-turn {
|
||||||
|
background-color: #DADEEF;
|
||||||
|
background-image: url("/web/assets/img/tiles/CableBottomLeft.svg");
|
||||||
background-size: 100%;
|
background-size: 100%;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
transform: rotate(90deg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.cable-vertical {
|
.cable-vertical {
|
||||||
@@ -177,6 +282,23 @@ main {
|
|||||||
background-position: center;
|
background-position: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.cable-turn-horizontale {
|
||||||
|
background-color: #DADEEF;
|
||||||
|
background-image: url("/web/assets/img/tiles/CableTopLeft.svg");
|
||||||
|
background-size: 100%;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cable-turn-horizontale2 {
|
||||||
|
background-color: #DADEEF;
|
||||||
|
background-image: url("/web/assets/img/tiles/CableTopLeft.svg");
|
||||||
|
background-size: 100%;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
.door {
|
.door {
|
||||||
background-color: #DADEEF;
|
background-color: #DADEEF;
|
||||||
background-image: url("/web/assets/img/tiles/WoodenDoor.svg");
|
background-image: url("/web/assets/img/tiles/WoodenDoor.svg");
|
||||||
@@ -246,7 +368,7 @@ main {
|
|||||||
|
|
||||||
.demi-wall-corner-down-left {
|
.demi-wall-corner-down-left {
|
||||||
background-color: #DADEEF;
|
background-color: #DADEEF;
|
||||||
background-image: url("/web/assets/img/tiles/BottomLeft.svg");
|
background-image: url("/web/assets/img/tiles/BottomLeftAngle.svg");
|
||||||
background-size: 100%;
|
background-size: 100%;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
@@ -254,7 +376,7 @@ main {
|
|||||||
|
|
||||||
.demi-wall-corner-down-right {
|
.demi-wall-corner-down-right {
|
||||||
background-color: #DADEEF;
|
background-color: #DADEEF;
|
||||||
background-image: url("/web/assets/img/tiles/BottomRight.svg");
|
background-image: url("/web/assets/img/tiles/BottomRightAngle.svg");
|
||||||
background-size: 100%;
|
background-size: 100%;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
@@ -341,6 +463,24 @@ main {
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.glass-item:disabled {
|
||||||
|
cursor: not-allowed;
|
||||||
|
opacity: 0.45;
|
||||||
|
}
|
||||||
|
|
||||||
|
.glass-item-label {
|
||||||
|
position: absolute;
|
||||||
|
right: 4px;
|
||||||
|
bottom: 3px;
|
||||||
|
z-index: 2;
|
||||||
|
font-size: 0.7rem;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #223;
|
||||||
|
background: rgba(255, 255, 255, 0.88);
|
||||||
|
padding: 1px 5px;
|
||||||
|
border-radius: 999px;
|
||||||
|
}
|
||||||
|
|
||||||
.glass-item::after,
|
.glass-item::after,
|
||||||
.cell-glass::after {
|
.cell-glass::after {
|
||||||
content: "";
|
content: "";
|
||||||
|
|||||||
@@ -1,17 +1,19 @@
|
|||||||
<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path d="M1 99L1 2.41406L97.5859 99L1 99Z" fill="url(#paint0_linear_17_89)" stroke="url(#paint1_linear_17_89)" stroke-width="2"/>
|
<path d="M1 99L1 1.61816L99 50.6182V99L1 99Z" fill="url(#paint0_linear_35_19)" stroke="url(#paint1_linear_35_19)" stroke-width="2"/>
|
||||||
<circle cx="5.5" cy="94.5" r="1.5" transform="rotate(-180 5.5 94.5)" fill="#4A4A4A"/>
|
<circle cx="5.5" cy="94.5" r="1.5" transform="rotate(-180 5.5 94.5)" fill="#4A4A4A"/>
|
||||||
<circle cx="5.5" cy="94.5" r="1" transform="rotate(-180 5.5 94.5)" fill="#898989"/>
|
<circle cx="5.5" cy="94.5" r="1" transform="rotate(-180 5.5 94.5)" fill="#898989"/>
|
||||||
<circle cx="5.5" cy="13.5" r="1.5" transform="rotate(-180 5.5 13.5)" fill="#4A4A4A"/>
|
<circle cx="4.5" cy="8.5" r="1.5" transform="rotate(-180 4.5 8.5)" fill="#4A4A4A"/>
|
||||||
<circle cx="5.5" cy="13.5" r="1" transform="rotate(-180 5.5 13.5)" fill="#898989"/>
|
<circle cx="4.5" cy="8.5" r="1" transform="rotate(-180 4.5 8.5)" fill="#898989"/>
|
||||||
<circle cx="86.5" cy="94.5" r="1.5" transform="rotate(-180 86.5 94.5)" fill="#4A4A4A"/>
|
<circle cx="94.5" cy="94.5" r="1.5" transform="rotate(-180 94.5 94.5)" fill="#4A4A4A"/>
|
||||||
<circle cx="86.5" cy="94.5" r="1" transform="rotate(-180 86.5 94.5)" fill="#898989"/>
|
<circle cx="94.5" cy="94.5" r="1" transform="rotate(-180 94.5 94.5)" fill="#898989"/>
|
||||||
|
<circle cx="94.5" cy="53.5" r="1.5" transform="rotate(-180 94.5 53.5)" fill="#4A4A4A"/>
|
||||||
|
<circle cx="94.5" cy="53.5" r="1" transform="rotate(-180 94.5 53.5)" fill="#898989"/>
|
||||||
<defs>
|
<defs>
|
||||||
<linearGradient id="paint0_linear_17_89" x1="0" y1="0" x2="100" y2="100" gradientUnits="userSpaceOnUse">
|
<linearGradient id="paint0_linear_35_19" x1="0" y1="0" x2="40" y2="80" gradientUnits="userSpaceOnUse">
|
||||||
<stop stop-color="white"/>
|
<stop stop-color="white"/>
|
||||||
<stop offset="1" stop-color="#747474"/>
|
<stop offset="1" stop-color="#747474"/>
|
||||||
</linearGradient>
|
</linearGradient>
|
||||||
<linearGradient id="paint1_linear_17_89" x1="100" y1="100" x2="0" y2="0" gradientUnits="userSpaceOnUse">
|
<linearGradient id="paint1_linear_35_19" x1="100" y1="50" x2="60" y2="-30" gradientUnits="userSpaceOnUse">
|
||||||
<stop stop-color="#A8A8A8"/>
|
<stop stop-color="#A8A8A8"/>
|
||||||
<stop offset="1" stop-color="#848484"/>
|
<stop offset="1" stop-color="#848484"/>
|
||||||
</linearGradient>
|
</linearGradient>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.3 KiB |
19
web/assets/img/tiles/BottomLeftAngle.svg
Normal file
19
web/assets/img/tiles/BottomLeftAngle.svg
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M1 99L1 2.41406L97.5859 99L1 99Z" fill="url(#paint0_linear_17_89)" stroke="url(#paint1_linear_17_89)" stroke-width="2"/>
|
||||||
|
<circle cx="5.5" cy="94.5" r="1.5" transform="rotate(-180 5.5 94.5)" fill="#4A4A4A"/>
|
||||||
|
<circle cx="5.5" cy="94.5" r="1" transform="rotate(-180 5.5 94.5)" fill="#898989"/>
|
||||||
|
<circle cx="5.5" cy="13.5" r="1.5" transform="rotate(-180 5.5 13.5)" fill="#4A4A4A"/>
|
||||||
|
<circle cx="5.5" cy="13.5" r="1" transform="rotate(-180 5.5 13.5)" fill="#898989"/>
|
||||||
|
<circle cx="86.5" cy="94.5" r="1.5" transform="rotate(-180 86.5 94.5)" fill="#4A4A4A"/>
|
||||||
|
<circle cx="86.5" cy="94.5" r="1" transform="rotate(-180 86.5 94.5)" fill="#898989"/>
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="paint0_linear_17_89" x1="0" y1="0" x2="100" y2="100" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="white"/>
|
||||||
|
<stop offset="1" stop-color="#747474"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="paint1_linear_17_89" x1="100" y1="100" x2="0" y2="0" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#A8A8A8"/>
|
||||||
|
<stop offset="1" stop-color="#848484"/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -1,17 +1,19 @@
|
|||||||
<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path d="M99 99H2.41406L99 2.41406V99Z" fill="url(#paint0_linear_19_190)" stroke="url(#paint1_linear_19_190)" stroke-width="2"/>
|
<path d="M99 99H1V50.6182L99 1.61816V99Z" fill="url(#paint0_linear_35_30)" stroke="url(#paint1_linear_35_30)" stroke-width="2"/>
|
||||||
<circle cx="94.5" cy="94.5" r="1.5" transform="rotate(90 94.5 94.5)" fill="#4A4A4A"/>
|
<circle cx="94.5" cy="94.5" r="1.5" transform="rotate(90 94.5 94.5)" fill="#4A4A4A"/>
|
||||||
<circle cx="94.5" cy="94.5" r="1" transform="rotate(90 94.5 94.5)" fill="#898989"/>
|
<circle cx="94.5" cy="94.5" r="1" transform="rotate(90 94.5 94.5)" fill="#898989"/>
|
||||||
<circle cx="13.5" cy="94.5" r="1.5" transform="rotate(90 13.5 94.5)" fill="#4A4A4A"/>
|
<circle cx="5.5" cy="94.5" r="1.5" transform="rotate(90 5.5 94.5)" fill="#4A4A4A"/>
|
||||||
<circle cx="13.5" cy="94.5" r="1" transform="rotate(90 13.5 94.5)" fill="#898989"/>
|
<circle cx="5.5" cy="94.5" r="1" transform="rotate(90 5.5 94.5)" fill="#898989"/>
|
||||||
<circle cx="94.5" cy="13.5" r="1.5" transform="rotate(90 94.5 13.5)" fill="#4A4A4A"/>
|
<circle cx="5.5" cy="53.5" r="1.5" transform="rotate(90 5.5 53.5)" fill="#4A4A4A"/>
|
||||||
<circle cx="94.5" cy="13.5" r="1" transform="rotate(90 94.5 13.5)" fill="#898989"/>
|
<circle cx="5.5" cy="53.5" r="1" transform="rotate(90 5.5 53.5)" fill="#898989"/>
|
||||||
|
<circle cx="94.5" cy="9.5" r="1.5" transform="rotate(90 94.5 9.5)" fill="#4A4A4A"/>
|
||||||
|
<circle cx="94.5" cy="9.5" r="1" transform="rotate(90 94.5 9.5)" fill="#898989"/>
|
||||||
<defs>
|
<defs>
|
||||||
<linearGradient id="paint0_linear_19_190" x1="0" y1="0" x2="100" y2="100" gradientUnits="userSpaceOnUse">
|
<linearGradient id="paint0_linear_35_30" x1="8.9049e-06" y1="1.50801e-06" x2="40" y2="80" gradientUnits="userSpaceOnUse">
|
||||||
<stop stop-color="white"/>
|
<stop stop-color="white"/>
|
||||||
<stop offset="1" stop-color="#747474"/>
|
<stop offset="1" stop-color="#747474"/>
|
||||||
</linearGradient>
|
</linearGradient>
|
||||||
<linearGradient id="paint1_linear_19_190" x1="100" y1="100" x2="0" y2="0" gradientUnits="userSpaceOnUse">
|
<linearGradient id="paint1_linear_35_30" x1="100" y1="50" x2="60" y2="-30" gradientUnits="userSpaceOnUse">
|
||||||
<stop stop-color="#A8A8A8"/>
|
<stop stop-color="#A8A8A8"/>
|
||||||
<stop offset="1" stop-color="#848484"/>
|
<stop offset="1" stop-color="#848484"/>
|
||||||
</linearGradient>
|
</linearGradient>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.3 KiB |
19
web/assets/img/tiles/BottomRightAngle.svg
Normal file
19
web/assets/img/tiles/BottomRightAngle.svg
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M99 99H2.41406L99 2.41406V99Z" fill="url(#paint0_linear_19_190)" stroke="url(#paint1_linear_19_190)" stroke-width="2"/>
|
||||||
|
<circle cx="94.5" cy="94.5" r="1.5" transform="rotate(90 94.5 94.5)" fill="#4A4A4A"/>
|
||||||
|
<circle cx="94.5" cy="94.5" r="1" transform="rotate(90 94.5 94.5)" fill="#898989"/>
|
||||||
|
<circle cx="13.5" cy="94.5" r="1.5" transform="rotate(90 13.5 94.5)" fill="#4A4A4A"/>
|
||||||
|
<circle cx="13.5" cy="94.5" r="1" transform="rotate(90 13.5 94.5)" fill="#898989"/>
|
||||||
|
<circle cx="94.5" cy="13.5" r="1.5" transform="rotate(90 94.5 13.5)" fill="#4A4A4A"/>
|
||||||
|
<circle cx="94.5" cy="13.5" r="1" transform="rotate(90 94.5 13.5)" fill="#898989"/>
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="paint0_linear_19_190" x1="0" y1="0" x2="100" y2="100" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="white"/>
|
||||||
|
<stop offset="1" stop-color="#747474"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="paint1_linear_19_190" x1="100" y1="100" x2="0" y2="0" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#A8A8A8"/>
|
||||||
|
<stop offset="1" stop-color="#848484"/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -20,6 +20,14 @@ const legend = {
|
|||||||
cable: 16,
|
cable: 16,
|
||||||
captorTurn: 17,
|
captorTurn: 17,
|
||||||
cableVertical: 18,
|
cableVertical: 18,
|
||||||
|
captorTurnReturn: 19,
|
||||||
|
rotatorButton: 20,
|
||||||
|
cableTurn: 21,
|
||||||
|
horizontalSemi: 22,
|
||||||
|
cableTurnHorizontale : 23,
|
||||||
|
cableTurnHorizontale2 : 24,
|
||||||
|
captorTurnHorizontal : 25,
|
||||||
|
wallSemiAngle: 26,
|
||||||
};
|
};
|
||||||
|
|
||||||
const laserColors = {
|
const laserColors = {
|
||||||
@@ -30,34 +38,64 @@ const laserColors = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const glassOptions = [
|
const glassOptions = [
|
||||||
laserColors.red,
|
[
|
||||||
laserColors.blue,
|
{ color: laserColors.red, maxAmount: 1, currentAmount: 1 },
|
||||||
laserColors.yellow,
|
{ color: laserColors.blue, maxAmount: 1, currentAmount: 1 },
|
||||||
|
{ color: laserColors.yellow, maxAmount: 1, currentAmount: 1 },
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{ color: laserColors.red, maxAmount: 1, currentAmount: 1 },
|
||||||
|
{ color: laserColors.blue, maxAmount: 1, currentAmount: 1 },
|
||||||
|
{ color: laserColors.yellow, maxAmount: 1, currentAmount: 1 },
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{ color: laserColors.red, maxAmount: 2, currentAmount: 2 },
|
||||||
|
{ color: laserColors.blue, maxAmount: 2, currentAmount:2},
|
||||||
|
{ color: laserColors.yellow, maxAmount: 2, currentAmount: 2 },
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{ color: laserColors.red, maxAmount: 2, currentAmount: 2 },
|
||||||
|
{ color: laserColors.blue, maxAmount: 1, currentAmount: 1 },
|
||||||
|
{ color: laserColors.yellow, maxAmount: 2, currentAmount: 2 },
|
||||||
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
let levels = [
|
let levels = [
|
||||||
[
|
[
|
||||||
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
[6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6],
|
||||||
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
[6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6],
|
||||||
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
[6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6],
|
||||||
[0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 11, 0, 0, 0, 0],
|
[6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6],
|
||||||
[0, 0, 0, 0, 1, 0, 5, 4, 0, 10, 6, 0, 0, 0, 0],
|
[6, 6, 6, 6, 1, 0, 5, 4, 0, 10, 6, 6, 6, 6, 6],
|
||||||
[0, 0, 0, 0, 7, 6, 6, 6, 6, 0, 6, 0, 0, 0, 0],
|
[6, 6, 6, 6, 7, 6, 6, 6, 6, 0, 6, 6, 6, 6, 6],
|
||||||
[0, 0, 0, 0, 3, 0, 0, 0, 0, 12, 6, 0, 0, 0, 0],
|
[6, 6, 6, 6, 3, 0, 0, 0, 0, 12, 6, 6, 6, 6, 6],
|
||||||
[0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 9, 0, 0, 0, 0],
|
[6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6],
|
||||||
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
[6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6],
|
||||||
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
[6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6],
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
[6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6],
|
||||||
|
[6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6],
|
||||||
|
[6, 6, 1, 0, 0, 0, 17, 0, 0, 3, 6, 6, 6, 6, 6],
|
||||||
|
[6, 6, 6, 6, 6, 6, 18, 6, 6, 0, 6, 6, 6, 6, 6],
|
||||||
|
[6, 6, 7, 0, 0, 0, 4, 0, 0, 12, 6, 6, 6, 6, 6],
|
||||||
|
[6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6],
|
||||||
|
[6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6],
|
||||||
|
[6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6],
|
||||||
|
[6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6],
|
||||||
|
[6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6],
|
||||||
],
|
],
|
||||||
|
|
||||||
[
|
[
|
||||||
[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, 6, 6, 11, 0, 0, 0, 0],
|
[0, 6, 6, 6, 6, 6, 0, 10, 6, 6, 11, 0, 0, 0, 0],
|
||||||
[0, 0, 1, 0, 0, 0, 17, 0, 0, 3, 6, 0, 0, 0, 0],
|
[7, 1, 0, 0, 0, 4, 0, 0, 0, 3, 21, 0, 0, 0, 0],
|
||||||
[0, 0, 6, 6, 6, 6, 18, 6, 6, 0, 6, 0, 0, 0, 0],
|
[0, 6, 6, 6, 6, 18, 6, 26, 22, 0, 18, 0, 0, 0, 0],
|
||||||
[0, 0, 7, 0, 0, 0, 4, 0, 0, 12, 6, 0, 0, 0, 0],
|
[0, 6, 9, 0, 0, 19, 0, 0, 0, 12, 18, 0, 0, 0, 0],
|
||||||
[0, 0, 6, 6, 6, 6, 6, 6, 6, 6, 9, 0, 0, 0, 0],
|
[0, 6, 0, 6, 6, 6, 6, 6, 6, 24, 23, 0, 0, 0, 0],
|
||||||
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
[0, 6, 11, 0, 0, 0, 0, 0, 20, 23, 9, 0, 0, 0, 0],
|
||||||
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
[0, 10, 6, 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, 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],
|
||||||
],
|
],
|
||||||
@@ -87,9 +125,7 @@ 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, 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],
|
||||||
],
|
], */
|
||||||
];
|
|
||||||
*/
|
|
||||||
let currentLevelIndex = 0;
|
let currentLevelIndex = 0;
|
||||||
|
|
||||||
const initialMirrorAngles = [
|
const initialMirrorAngles = [
|
||||||
@@ -98,9 +134,9 @@ const initialMirrorAngles = [
|
|||||||
},
|
},
|
||||||
{},
|
{},
|
||||||
{
|
{
|
||||||
"3,4": 315,
|
"2,9": 225,
|
||||||
"7,8": 0,
|
|
||||||
},
|
},
|
||||||
|
{}
|
||||||
];
|
];
|
||||||
|
|
||||||
const buttonGroups = [
|
const buttonGroups = [
|
||||||
@@ -108,7 +144,9 @@ const buttonGroups = [
|
|||||||
"4,6": 1,
|
"4,6": 1,
|
||||||
},
|
},
|
||||||
{},
|
{},
|
||||||
{},
|
{
|
||||||
|
"9,4": 1,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const doorGroups = [
|
const doorGroups = [
|
||||||
@@ -132,6 +170,9 @@ const captorGroups = [
|
|||||||
const rotatorButtons = [
|
const rotatorButtons = [
|
||||||
{},
|
{},
|
||||||
{},
|
{},
|
||||||
|
{
|
||||||
|
"6,8": { mirrorX: 9, mirrorY: 2, step: 22.5, intervalMs: 1000 },
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"3,7": { mirrorX: 7, mirrorY: 7, step: -22.5, intervalMs: 1000 },
|
"3,7": { mirrorX: 7, mirrorY: 7, step: -22.5, intervalMs: 1000 },
|
||||||
},
|
},
|
||||||
@@ -148,6 +189,9 @@ let activeRotatorButtons = {};
|
|||||||
let rotatorIntervals = {};
|
let rotatorIntervals = {};
|
||||||
let toggledDoors = {};
|
let toggledDoors = {};
|
||||||
let poweredCaptors = {};
|
let poweredCaptors = {};
|
||||||
|
let draggedGlassColor = null;
|
||||||
|
let highestUnlockedLevelIndex = 0;
|
||||||
|
const unlockedLevelsStorageKey = "mirror-game-highest-unlocked-level";
|
||||||
|
|
||||||
function getCurrentLevel() {
|
function getCurrentLevel() {
|
||||||
return levels[currentLevelIndex];
|
return levels[currentLevelIndex];
|
||||||
@@ -157,6 +201,131 @@ function getCurrentLevelConfig(configByLevel) {
|
|||||||
return configByLevel[currentLevelIndex] || {};
|
return configByLevel[currentLevelIndex] || {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function loadUnlockedLevels() {
|
||||||
|
const savedValue = window.localStorage.getItem(unlockedLevelsStorageKey);
|
||||||
|
const parsedValue = Number.parseInt(savedValue || "0", 10);
|
||||||
|
|
||||||
|
if (Number.isNaN(parsedValue)) {
|
||||||
|
highestUnlockedLevelIndex = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
highestUnlockedLevelIndex = Math.max(0, Math.min(parsedValue, levels.length - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveUnlockedLevels() {
|
||||||
|
window.localStorage.setItem(unlockedLevelsStorageKey, String(highestUnlockedLevelIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
function unlockLevel(levelIndex) {
|
||||||
|
if (levelIndex <= highestUnlockedLevelIndex || levelIndex >= levels.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
highestUnlockedLevelIndex = levelIndex;
|
||||||
|
saveUnlockedLevels();
|
||||||
|
renderLevelMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleLevelMenu() {
|
||||||
|
const levelMenuPanel = document.getElementById("level-menu-panel");
|
||||||
|
const levelMenuToggle = document.getElementById("level-menu-toggle");
|
||||||
|
|
||||||
|
if (!levelMenuPanel || !levelMenuToggle) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const isOpening = levelMenuPanel.hasAttribute("hidden");
|
||||||
|
|
||||||
|
if (isOpening) {
|
||||||
|
levelMenuPanel.removeAttribute("hidden");
|
||||||
|
} else {
|
||||||
|
levelMenuPanel.setAttribute("hidden", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
levelMenuToggle.setAttribute("aria-expanded", String(isOpening));
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderLevelMenu() {
|
||||||
|
const levelMenuList = document.getElementById("level-menu-list");
|
||||||
|
|
||||||
|
if (!levelMenuList) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
levelMenuList.innerHTML = "";
|
||||||
|
|
||||||
|
for (let levelIndex = 0; levelIndex < levels.length; levelIndex++) {
|
||||||
|
const levelButton = document.createElement("button");
|
||||||
|
const isUnlocked = levelIndex <= highestUnlockedLevelIndex;
|
||||||
|
const isCurrentLevel = levelIndex === currentLevelIndex;
|
||||||
|
|
||||||
|
levelButton.type = "button";
|
||||||
|
levelButton.classList.add("level-menu-item");
|
||||||
|
levelButton.textContent = isUnlocked ? `Level ${levelIndex + 1}` : `Level ${levelIndex + 1} - Locked`;
|
||||||
|
levelButton.disabled = !isUnlocked;
|
||||||
|
|
||||||
|
if (isCurrentLevel) {
|
||||||
|
levelButton.classList.add("is-current");
|
||||||
|
}
|
||||||
|
|
||||||
|
levelButton.addEventListener("click", () => {
|
||||||
|
if (!isUnlocked) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
goToLevel(levelIndex);
|
||||||
|
const levelMenuPanel = document.getElementById("level-menu-panel");
|
||||||
|
const levelMenuToggle = document.getElementById("level-menu-toggle");
|
||||||
|
|
||||||
|
if (levelMenuPanel) {
|
||||||
|
levelMenuPanel.setAttribute("hidden", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (levelMenuToggle) {
|
||||||
|
levelMenuToggle.setAttribute("aria-expanded", "false");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
levelMenuList.appendChild(levelButton);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setupLevelMenu() {
|
||||||
|
const levelMenuToggle = document.getElementById("level-menu-toggle");
|
||||||
|
|
||||||
|
if (!levelMenuToggle) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
levelMenuToggle.addEventListener("click", toggleLevelMenu);
|
||||||
|
renderLevelMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCurrentGlassOptions() {
|
||||||
|
return glassOptions[currentLevelIndex] || [];
|
||||||
|
}
|
||||||
|
|
||||||
|
function getGlassOptionByColor(color) {
|
||||||
|
const currentGlassOptions = getCurrentGlassOptions();
|
||||||
|
|
||||||
|
for (let i = 0; i < currentGlassOptions.length; i++) {
|
||||||
|
if (currentGlassOptions[i].color === color) {
|
||||||
|
return currentGlassOptions[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetGlassInventory() {
|
||||||
|
const currentGlassOptions = getCurrentGlassOptions();
|
||||||
|
|
||||||
|
for (let i = 0; i < currentGlassOptions.length; i++) {
|
||||||
|
currentGlassOptions[i].currentAmount = currentGlassOptions[i].maxAmount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function normalizeLaserDirection(dx, dy) {
|
function normalizeLaserDirection(dx, dy) {
|
||||||
const epsilon = 0.0001;
|
const epsilon = 0.0001;
|
||||||
const normalizedDx = Math.abs(dx) < epsilon ? 0 : Math.sign(dx);
|
const normalizedDx = Math.abs(dx) < epsilon ? 0 : Math.sign(dx);
|
||||||
@@ -366,17 +535,40 @@ function createPalette() {
|
|||||||
|
|
||||||
palette.innerHTML = "";
|
palette.innerHTML = "";
|
||||||
|
|
||||||
for (let i = 0; i < glassOptions.length; i++) {
|
const currentGlassOptions = getCurrentGlassOptions();
|
||||||
const glassColor = glassOptions[i];
|
|
||||||
|
for (let i = 0; i < currentGlassOptions.length; i++) {
|
||||||
|
const glassOption = currentGlassOptions[i];
|
||||||
|
const glassColor = glassOption.color;
|
||||||
const glassButton = document.createElement("button");
|
const glassButton = document.createElement("button");
|
||||||
glassButton.type = "button";
|
glassButton.type = "button";
|
||||||
glassButton.classList.add("glass-item", `glass-${glassColor}`);
|
glassButton.classList.add("glass-item", `glass-${glassColor}`);
|
||||||
glassButton.draggable = true;
|
glassButton.draggable = glassOption.currentAmount > 0;
|
||||||
|
|
||||||
|
if (glassOption.currentAmount <= 0) {
|
||||||
|
glassButton.disabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const glassLabel = document.createElement("span");
|
||||||
|
glassLabel.classList.add("glass-item-label");
|
||||||
|
glassLabel.textContent = `${glassOption.currentAmount}/${glassOption.maxAmount}`;
|
||||||
|
glassButton.appendChild(glassLabel);
|
||||||
|
|
||||||
glassButton.addEventListener("dragstart", (event) => {
|
glassButton.addEventListener("dragstart", (event) => {
|
||||||
|
if (glassOption.currentAmount <= 0) {
|
||||||
|
event.preventDefault();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
draggedGlassColor = glassColor;
|
||||||
event.dataTransfer.effectAllowed = "copy";
|
event.dataTransfer.effectAllowed = "copy";
|
||||||
event.dataTransfer.setData("application/x-glass-color", glassColor);
|
event.dataTransfer.setData("application/x-glass-color", glassColor);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
glassButton.addEventListener("dragend", () => {
|
||||||
|
draggedGlassColor = null;
|
||||||
|
});
|
||||||
|
|
||||||
palette.appendChild(glassButton);
|
palette.appendChild(glassButton);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -387,7 +579,8 @@ function addDropEvents(cell, x, y) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!event.dataTransfer.types.includes("application/x-glass-color")) {
|
const transferTypes = event.dataTransfer ? Array.from(event.dataTransfer.types || []) : [];
|
||||||
|
if (!draggedGlassColor) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -396,6 +589,13 @@ function addDropEvents(cell, x, y) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const selectedColor = draggedGlassColor;
|
||||||
|
const glassOption = getGlassOptionByColor(selectedColor);
|
||||||
|
|
||||||
|
if (!glassOption || glassOption.currentAmount <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
cell.classList.add("can-drop");
|
cell.classList.add("can-drop");
|
||||||
});
|
});
|
||||||
@@ -409,7 +609,8 @@ function addDropEvents(cell, x, y) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const selectedColor = event.dataTransfer.getData("application/x-glass-color");
|
const transferredColor = event.dataTransfer ? event.dataTransfer.getData("application/x-glass-color") : "";
|
||||||
|
const selectedColor = transferredColor || draggedGlassColor;
|
||||||
cell.classList.remove("can-drop");
|
cell.classList.remove("can-drop");
|
||||||
|
|
||||||
if (!selectedColor) {
|
if (!selectedColor) {
|
||||||
@@ -420,8 +621,21 @@ function addDropEvents(cell, x, y) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isGlassOnCell(x, y)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const glassOption = getGlassOptionByColor(selectedColor);
|
||||||
|
|
||||||
|
if (!glassOption || glassOption.currentAmount <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
glassPlacements[`${y},${x}`] = selectedColor;
|
glassPlacements[`${y},${x}`] = selectedColor;
|
||||||
|
glassOption.currentAmount--;
|
||||||
|
draggedGlassColor = null;
|
||||||
|
createPalette();
|
||||||
traceLaser();
|
traceLaser();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -431,7 +645,16 @@ function addDropEvents(cell, x, y) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isGlassOnCell(x, y)) {
|
if (isGlassOnCell(x, y)) {
|
||||||
|
const glassColor = glassPlacements[`${y},${x}`];
|
||||||
|
const glassOption = getGlassOptionByColor(glassColor);
|
||||||
|
|
||||||
delete glassPlacements[`${y},${x}`];
|
delete glassPlacements[`${y},${x}`];
|
||||||
|
|
||||||
|
if (glassOption) {
|
||||||
|
glassOption.currentAmount = Math.min(glassOption.currentAmount + 1, glassOption.maxAmount);
|
||||||
|
}
|
||||||
|
|
||||||
|
createPalette();
|
||||||
traceLaser();
|
traceLaser();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -570,6 +793,27 @@ function loadGrid() {
|
|||||||
case legend.cableVertical:
|
case legend.cableVertical:
|
||||||
cell.classList.add("cable-vertical");
|
cell.classList.add("cable-vertical");
|
||||||
break;
|
break;
|
||||||
|
case legend.captorTurnReturn:
|
||||||
|
cell.classList.add("captor-turn-reverse");
|
||||||
|
break;
|
||||||
|
case legend.cableTurn:
|
||||||
|
cell.classList.add("cable-turn");
|
||||||
|
break;
|
||||||
|
case legend.horizontalSemi:
|
||||||
|
cell.classList.add("horizontal-semi");
|
||||||
|
break;
|
||||||
|
case legend.cableTurnHorizontale:
|
||||||
|
cell.classList.add("cable-turn-horizontale");
|
||||||
|
break;
|
||||||
|
case legend.cableTurnHorizontale2:
|
||||||
|
cell.classList.add("cable-turn-horizontale2");
|
||||||
|
break;
|
||||||
|
case legend.captorTurnHorizontal:
|
||||||
|
cell.classList.add("captor-turn-horizontale2");
|
||||||
|
break;
|
||||||
|
case legend.wallSemiAngle:
|
||||||
|
cell.classList.add("wall-semi-angle");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
drawLaserInCell(cell, laserSegments[`${y},${x}`]);
|
drawLaserInCell(cell, laserSegments[`${y},${x}`]);
|
||||||
@@ -641,10 +885,21 @@ function traceLaser() {
|
|||||||
currentLaserColor = glassColor;
|
currentLaserColor = glassColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (currentLaserColor === laserColors.yellow) {
|
||||||
|
saveLaserSegment(currentX, currentY, laserDirection, currentLaserColor);
|
||||||
|
|
||||||
|
if (cellType === legend.target) {
|
||||||
|
laserActive = false;
|
||||||
|
isLevelFinished = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
switch (cellType) {
|
switch (cellType) {
|
||||||
case legend.laser:
|
case legend.laser:
|
||||||
case legend.coloredLaser:
|
case legend.coloredLaser:
|
||||||
laserActive = false;
|
saveLaserSegment(currentX, currentY, laserDirection, currentLaserColor);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case legend.empty:
|
case legend.empty:
|
||||||
@@ -675,7 +930,27 @@ function traceLaser() {
|
|||||||
laserActive = false;
|
laserActive = false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case legend.wallSemiAngle:
|
||||||
|
if (currentLaserColor === laserColors.blue) {
|
||||||
|
laserDirection = reverseLaser(laserDirection);
|
||||||
|
} else if (currentLaserColor === laserColors.yellow) {
|
||||||
|
saveLaserSegment(currentX, currentY, laserDirection, currentLaserColor);
|
||||||
|
} else {
|
||||||
|
laserActive = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case legend.horizontalSemi:
|
||||||
|
if (currentLaserColor === laserColors.blue) {
|
||||||
|
saveLaserSegment(currentX, currentY, laserDirection, currentLaserColor);
|
||||||
|
laserDirection = reflectLaser(laserDirection, 0);
|
||||||
|
} else if (currentLaserColor === laserColors.yellow) {
|
||||||
|
saveLaserSegment(currentX, currentY, laserDirection, currentLaserColor);
|
||||||
|
} else {
|
||||||
|
laserActive = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case legend.cableVertical:
|
||||||
|
case legend.cableTurn:
|
||||||
case legend.door:
|
case legend.door:
|
||||||
case legend.doorOpen:
|
case legend.doorOpen:
|
||||||
if (openedDoors[`${currentY},${currentX}`] || cellType === legend.doorOpen) {
|
if (openedDoors[`${currentY},${currentX}`] || cellType === legend.doorOpen) {
|
||||||
@@ -704,6 +979,14 @@ function traceLaser() {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case legend.captor:
|
case legend.captor:
|
||||||
|
if (currentLaserColor === laserColors.blue) {
|
||||||
|
laserDirection = reverseLaser(laserDirection);
|
||||||
|
} else if (currentLaserColor === laserColors.yellow) {
|
||||||
|
saveLaserSegment(currentX, currentY, laserDirection, currentLaserColor);
|
||||||
|
} else {
|
||||||
|
laserActive = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case legend.captorTurn:
|
case legend.captorTurn:
|
||||||
if (currentLaserColor === laserColors.red) {
|
if (currentLaserColor === laserColors.red) {
|
||||||
const captorKey = `${currentY},${currentX}`;
|
const captorKey = `${currentY},${currentX}`;
|
||||||
@@ -723,7 +1006,44 @@ function traceLaser() {
|
|||||||
laserActive = false;
|
laserActive = false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case legend.captorTurnReturn:
|
||||||
|
if (currentLaserColor === laserColors.red) {
|
||||||
|
const captorKey = `${currentY},${currentX}`;
|
||||||
|
activatedButtons[captorKey] = true;
|
||||||
|
nextPoweredCaptors[captorKey] = true;
|
||||||
|
|
||||||
|
if (!poweredCaptors[captorKey]) {
|
||||||
|
toggleDoorsFromCaptor(currentX, currentY);
|
||||||
|
openedDoors = { ...toggledDoors };
|
||||||
|
}
|
||||||
|
|
||||||
|
saveLaserSegment(currentX, currentY, laserDirection, currentLaserColor);
|
||||||
|
laserActive = false;
|
||||||
|
}else if(currentLaserColor === laserColors.yellow) {
|
||||||
|
saveLaserSegment(currentX, currentY, laserDirection, currentLaserColor);
|
||||||
|
} else {
|
||||||
|
laserActive = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case legend.captorTurnHorizontal:
|
||||||
|
if (currentLaserColor === laserColors.red) {
|
||||||
|
const captorKey = `${currentY},${currentX}`;
|
||||||
|
activatedButtons[captorKey] = true;
|
||||||
|
nextPoweredCaptors[captorKey] = true;
|
||||||
|
|
||||||
|
if (!poweredCaptors[captorKey]) {
|
||||||
|
toggleDoorsFromCaptor(currentX, currentY);
|
||||||
|
openedDoors = { ...toggledDoors };
|
||||||
|
}
|
||||||
|
|
||||||
|
saveLaserSegment(currentX, currentY, laserDirection, currentLaserColor);
|
||||||
|
laserActive = false;
|
||||||
|
}else if(currentLaserColor === laserColors.yellow) {
|
||||||
|
saveLaserSegment(currentX, currentY, laserDirection, currentLaserColor);
|
||||||
|
} else {
|
||||||
|
laserActive = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case legend.rotatorButton:
|
case legend.rotatorButton:
|
||||||
if (currentLaserColor === laserColors.red) {
|
if (currentLaserColor === laserColors.red) {
|
||||||
const rotatorKey = `${currentY},${currentX}`;
|
const rotatorKey = `${currentY},${currentX}`;
|
||||||
@@ -742,25 +1062,37 @@ function traceLaser() {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case legend.demiWallCornerUpLeft:
|
case legend.demiWallCornerUpLeft:
|
||||||
if(currentLaserColor === laserColors.blue) {
|
if (currentLaserColor === laserColors.yellow) {
|
||||||
|
saveLaserSegment(currentX, currentY, laserDirection, currentLaserColor);
|
||||||
|
} else if (currentLaserColor === laserColors.blue) {
|
||||||
|
saveLaserSegment(currentX, currentY, laserDirection, currentLaserColor);
|
||||||
laserDirection = reflectLaser(laserDirection, 135);
|
laserDirection = reflectLaser(laserDirection, 135);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case legend.demiWallCornerUpRight:
|
case legend.demiWallCornerUpRight:
|
||||||
if(currentLaserColor === laserColors.blue) {
|
if (currentLaserColor === laserColors.yellow) {
|
||||||
|
saveLaserSegment(currentX, currentY, laserDirection, currentLaserColor);
|
||||||
|
} else if (currentLaserColor === laserColors.blue) {
|
||||||
|
saveLaserSegment(currentX, currentY, laserDirection, currentLaserColor);
|
||||||
laserDirection = reflectLaser(laserDirection, 45);
|
laserDirection = reflectLaser(laserDirection, 45);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case legend.demiWallCornerDownLeft:
|
case legend.demiWallCornerDownLeft:
|
||||||
if(currentLaserColor === laserColors.blue) {
|
if (currentLaserColor === laserColors.yellow) {
|
||||||
|
saveLaserSegment(currentX, currentY, laserDirection, currentLaserColor);
|
||||||
|
} else if (currentLaserColor === laserColors.blue) {
|
||||||
|
saveLaserSegment(currentX, currentY, laserDirection, currentLaserColor);
|
||||||
laserDirection = reflectLaser(laserDirection, 225);
|
laserDirection = reflectLaser(laserDirection, 225);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case legend.demiWallCornerDownRight:
|
case legend.demiWallCornerDownRight:
|
||||||
if(currentLaserColor === laserColors.blue) {
|
if (currentLaserColor === laserColors.yellow) {
|
||||||
|
saveLaserSegment(currentX, currentY, laserDirection, currentLaserColor);
|
||||||
|
} else if (currentLaserColor === laserColors.blue) {
|
||||||
|
saveLaserSegment(currentX, currentY, laserDirection, currentLaserColor);
|
||||||
laserDirection = reflectLaser(laserDirection, 315);
|
laserDirection = reflectLaser(laserDirection, 315);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -781,60 +1113,46 @@ function traceLaser() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function finish() {
|
function finish() {
|
||||||
|
unlockLevel(currentLevelIndex + 1);
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const winOverlay = document.querySelector(".win-overlay");
|
const winOverlay = document.querySelector(".win-overlay");
|
||||||
winOverlay.style.visibility = "visible";
|
winOverlay.style.visibility = "visible";
|
||||||
}, 100);
|
}, 100);
|
||||||
|
|
||||||
nextLevel();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function nextLevel () {
|
function goToLevel(levelIndex) {
|
||||||
currentLevelIndex++;
|
currentLevelIndex = levelIndex;
|
||||||
|
|
||||||
isLevelFinished = false;
|
|
||||||
|
|
||||||
if (currentLevelIndex >= levels.length) {
|
|
||||||
currentLevelIndex = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
initializeMirrorOrientations();
|
|
||||||
loadGrid();
|
|
||||||
laserSegments = {};
|
|
||||||
mirrorOrientations = {};
|
|
||||||
glassPlacements = {};
|
|
||||||
activatedButtons = {};
|
|
||||||
openedDoors = {};
|
|
||||||
traceLaser();
|
|
||||||
}
|
|
||||||
|
|
||||||
function nextLevel() {
|
|
||||||
currentLevelIndex++;
|
|
||||||
|
|
||||||
isLevelFinished = false;
|
isLevelFinished = false;
|
||||||
stopAllRotatorButtons();
|
stopAllRotatorButtons();
|
||||||
|
|
||||||
if (currentLevelIndex >= levels.length) {
|
|
||||||
currentLevelIndex = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
initializeMirrorOrientations();
|
|
||||||
loadGrid();
|
|
||||||
laserSegments = {};
|
|
||||||
mirrorOrientations = {};
|
mirrorOrientations = {};
|
||||||
glassPlacements = {};
|
laserSegments = {};
|
||||||
activatedButtons = {};
|
activatedButtons = {};
|
||||||
openedDoors = {};
|
openedDoors = {};
|
||||||
toggledDoors = {};
|
toggledDoors = {};
|
||||||
poweredCaptors = {};
|
poweredCaptors = {};
|
||||||
|
initializeMirrorOrientations();
|
||||||
|
glassPlacements = {};
|
||||||
|
resetGlassInventory();
|
||||||
|
createPalette();
|
||||||
|
loadGrid();
|
||||||
traceLaser();
|
traceLaser();
|
||||||
|
|
||||||
const winOverlay = document.querySelector(".win-overlay");
|
const winOverlay = document.querySelector(".win-overlay");
|
||||||
winOverlay.style.visibility = "hidden";
|
winOverlay.style.visibility = "hidden";
|
||||||
|
renderLevelMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function nextLevel() {
|
||||||
|
const nextLevelIndex = currentLevelIndex + 1 >= levels.length ? 0 : currentLevelIndex + 1;
|
||||||
|
goToLevel(nextLevelIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
loadUnlockedLevels();
|
||||||
|
resetGlassInventory();
|
||||||
createPalette();
|
createPalette();
|
||||||
initializeMirrorOrientations();
|
initializeMirrorOrientations();
|
||||||
blockBrowserDrop();
|
blockBrowserDrop();
|
||||||
|
setupLevelMenu();
|
||||||
traceLaser();
|
traceLaser();
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
function rotateMirror(mirror) {
|
|
||||||
let angle = 0;
|
|
||||||
if (mirror.style.transform == "") {
|
|
||||||
angle = 0;
|
|
||||||
} else {
|
|
||||||
angle = parseInt(mirror.style.transform.split("(")[1].split("deg")[0])%360;
|
|
||||||
}
|
|
||||||
mirror.style.transform = `rotate(${angle+45}deg)`;
|
|
||||||
}
|
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<link rel="stylesheet" href="/web/assets/css/game.css">
|
<link rel="stylesheet" href="/web/assets/web/assets/assets/css/game.css">
|
||||||
<title>Game</title>
|
<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='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>
|
<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>
|
||||||
@@ -15,6 +15,16 @@
|
|||||||
<button class="win-button" onclick="nextLevel()">Next Level</button>
|
<button class="win-button" onclick="nextLevel()">Next Level</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<aside class="level-menu-shell">
|
||||||
|
<button id="level-menu-toggle" class="level-menu-toggle" type="button" aria-expanded="false" aria-controls="level-menu-panel">
|
||||||
|
Levels
|
||||||
|
</button>
|
||||||
|
<div id="level-menu-panel" class="level-menu-panel" hidden>
|
||||||
|
<h2>Choose Level</h2>
|
||||||
|
<div id="level-menu-list" class="level-menu-list"></div>
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
atOptions = {
|
atOptions = {
|
||||||
'key' : '72b6ba1a1c26b9671167b66063c7e699',
|
'key' : '72b6ba1a1c26b9671167b66063c7e699',
|
||||||
@@ -46,6 +56,6 @@
|
|||||||
</script>
|
</script>
|
||||||
<script src="https://www.highperformanceformat.com/72b6ba1a1c26b9671167b66063c7e699/invoke.js"></script>
|
<script src="https://www.highperformanceformat.com/72b6ba1a1c26b9671167b66063c7e699/invoke.js"></script>
|
||||||
|
|
||||||
<script src="/web/assets/js/game.js" defer></script>
|
<script src="/web/assets//eb/assets/assets/js/game.js" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user