7 Commits

Author SHA1 Message Date
M1n-0
40fe732caa fix merge branch 2026-03-31 13:52:42 +02:00
M1n-0
15b585df02 testfile 2026-03-31 13:29:29 +02:00
M1n-0
f6347feff1 testfile 2026-03-31 13:29:29 +02:00
GreyRav
c7f0e747b1 fix : change port 2026-03-31 13:29:29 +02:00
GreyRav
1d28a75529 fix : html + css display 2026-03-31 13:29:29 +02:00
Sysy's
ecbf7a5b34 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-31 13:29:29 +02:00
GreyRav
46660bd921 fix : path to index.html 2026-03-31 13:29:29 +02:00
12 changed files with 184 additions and 632 deletions

49
backend/Cargo.lock generated
View File

@@ -91,6 +91,7 @@ dependencies = [
"axum-server", "axum-server",
"serde", "serde",
"tokio", "tokio",
"tower-http",
"tracing-subscriber", "tracing-subscriber",
] ]
@@ -256,6 +257,12 @@ dependencies = [
"pin-project-lite", "pin-project-lite",
] ]
[[package]]
name = "http-range-header"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9171a2ea8a68358193d15dd5d70c1c10a2afc3e7e4c5bc92bc9f025cebd7359c"
[[package]] [[package]]
name = "httparse" name = "httparse"
version = "1.10.1" version = "1.10.1"
@@ -366,6 +373,16 @@ version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
[[package]]
name = "mime_guess"
version = "2.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e"
dependencies = [
"mime",
"unicase",
]
[[package]] [[package]]
name = "mio" name = "mio"
version = "1.2.0" version = "1.2.0"
@@ -661,6 +678,32 @@ dependencies = [
"tracing", "tracing",
] ]
[[package]]
name = "tower-http"
version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8"
dependencies = [
"bitflags",
"bytes",
"futures-core",
"futures-util",
"http",
"http-body",
"http-body-util",
"http-range-header",
"httpdate",
"mime",
"mime_guess",
"percent-encoding",
"pin-project-lite",
"tokio",
"tokio-util",
"tower-layer",
"tower-service",
"tracing",
]
[[package]] [[package]]
name = "tower-layer" name = "tower-layer"
version = "0.3.3" version = "0.3.3"
@@ -719,6 +762,12 @@ dependencies = [
"tracing-log", "tracing-log",
] ]
[[package]]
name = "unicase"
version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142"
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"
version = "1.0.24" version = "1.0.24"

View File

@@ -9,3 +9,4 @@ axum-server = "0.8.0"
serde = "1.0.228" serde = "1.0.228"
tokio = { version = "1.50.0", features = ["full"] } tokio = { version = "1.50.0", features = ["full"] }
tracing-subscriber = "0.3.23" tracing-subscriber = "0.3.23"
tower-http = { version = "0.6", features = ["fs"] }

View File

@@ -1,14 +0,0 @@
struct Laser {
color : array,
}
struct Mirror {
color : array,
x : int,
y : int,
}
struct Spawn {
x : int,
y : int,
}

View File

@@ -1,14 +1,34 @@
use axum::{routing::get, Router}; use axum::{Router, response::Html, routing::get};
use std::net::SocketAddr; use std::net::SocketAddr;
use std::path::Path;
use tokio::fs::File;
use tokio::io::{self, AsyncReadExt};
use tower_http::services::ServeDir;
#[tokio::main] #[tokio::main]
async fn main() { async fn main() {
let app = Router::new().route("/", get(|| async { "Hello, world!" })); let app = Router::new()
.route("/", get(handler))
.nest_service("/assets", ServeDir::new("../web/assets"));
let addr = SocketAddr::from(([127, 0, 0, 1], 3000)); let addr = SocketAddr::from(([127, 0, 0, 1], 3500));
println!("listening on {}", addr); println!("listening on {}", addr);
axum_server::bind(addr) axum_server::bind(addr)
.serve(app.into_make_service()) .serve(app.into_make_service())
.await .await
.unwrap(); .unwrap();
} }
async fn handler() -> Html<String> {
let html_content = read_html_from_file("../web/templates/view/index.html")
.await
.unwrap_or_else(|_| "<h1>Error loading HTML file</h1>".to_string());
Html(html_content)
}
async fn read_html_from_file<P: AsRef<Path>>(path: P) -> io::Result<String> {
let mut file = File::open(path).await?;
let mut contents = String::new();
file.read_to_string(&mut contents).await?;
Ok(contents)
}

View File

@@ -20,71 +20,6 @@ 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;
@@ -173,7 +108,7 @@ main {
.laser { .laser {
background-color: #DADEEF; background-color: #DADEEF;
background-image: url("/web/assets/img/tiles/Laser.svg"); background-image: url("../img/tiles/Laser.svg");
background-size: 80%; background-size: 80%;
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: center; background-position: center;
@@ -182,7 +117,7 @@ main {
.colored-laser { .colored-laser {
background-color: #DADEEF; background-color: #DADEEF;
background-image: url("/web/assets/img/tiles/Prisme.svg"); background-image: url("../img/tiles/Prisme.svg");
background-size: 80%; background-size: 80%;
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: center; background-position: center;
@@ -202,31 +137,15 @@ main {
.wall { .wall {
background-color: #DADEEF; background-color: #DADEEF;
background-image: url("/web/assets/img/tiles/Tuile.svg"); background-image: url("../img/tiles/Tuile.svg");
background-size: 100%; background-size: 100%;
background-repeat: no-repeat; background-repeat: no-repeat;
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("../img/tiles/Capteur-1.svg");
background-size: 100%; background-size: 100%;
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: center; background-position: center;
@@ -235,24 +154,7 @@ main {
.captor-turn { .captor-turn {
background-color: #DADEEF; background-color: #DADEEF;
background-image: url("/web/assets/img/tiles/Capteur-2.svg"); background-image: url("../img/tiles/Capteur-2.svg");
background-size: 100%;
background-repeat: no-repeat;
background-position: center;
}
.captor-turn-reverse {
background-color: #DADEEF;
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-size: 100%;
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: center; background-position: center;
@@ -260,55 +162,31 @@ main {
.cable { .cable {
background-color: #DADEEF; background-color: #DADEEF;
background-image: url("/web/assets/img/tiles/CableH.svg"); background-image: url("../img/tiles/CableV.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 {
background-color: #DADEEF; background-color: #DADEEF;
background-image: url("/web/assets/img/tiles/CableV.svg"); background-image: url("../img/tiles/CableV.svg");
background-size: 100%; background-size: 100%;
background-repeat: no-repeat; background-repeat: no-repeat;
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("../img/tiles/WoodenDoor.svg");
background-size: contain; background-size: contain;
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: end; background-position: end;
} }
.door-open { .door-open {
background-image: url("/web/assets/img/tiles/WoodenDoor_openned.svg"); background-image: url("../img/tiles/WoodenDoor_openned.svg");
background-size: contain; background-size: contain;
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: end; background-position: end;
@@ -316,7 +194,7 @@ main {
.button { .button {
background-color: #DADEEF; background-color: #DADEEF;
background-image: url("/web/assets/img/tiles/ButtonComplete.svg"), url("/web/assets/img/tiles/Tuile.svg"); background-image: url("../img/tiles/ButtonComplete.svg"), url("../img/tiles/Tuile.svg");
background-size: 100% 100%; background-size: 100% 100%;
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: center; background-position: center;
@@ -324,7 +202,7 @@ main {
.button-2 { .button-2 {
background-color: #DADEEF; background-color: #DADEEF;
background-image: url("/web/assets/img/tiles/ButtonQuarter.svg"), url("/web/assets/img/tiles/Tuile.svg"); background-image: url("../img/tiles/ButtonQuarter.svg"), url("../img/tiles/Tuile.svg");
background-size: 100% 100%; background-size: 100% 100%;
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: center; background-position: center;
@@ -332,7 +210,7 @@ main {
.button-rotator { .button-rotator {
background-color: #DADEEF; background-color: #DADEEF;
background-image: url("/web/assets/img/tiles/ButtonProfile.svg"), url("/web/assets/img/tiles/Tuile.svg"); background-image: url("../img/tiles/ButtonProfile.svg"), url("../img/tiles/Tuile.svg");
background-size: 100% 100%; background-size: 100% 100%;
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: center; background-position: center;
@@ -344,7 +222,7 @@ main {
.target { .target {
background-color: #DADEEF; background-color: #DADEEF;
background-image: url("/web/assets/img/tiles/Trigger.svg"); background-image: url("../img/tiles/Trigger.svg");
background-size: 80%; background-size: 80%;
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: center; background-position: center;
@@ -352,7 +230,7 @@ main {
.demi-wall-corner-up-left { .demi-wall-corner-up-left {
background-color: #DADEEF; background-color: #DADEEF;
background-image: url("/web/assets/img/tiles/TopLeft.svg"); background-image: url("../img/tiles/TopLeft.svg");
background-size: 100%; background-size: 100%;
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: center; background-position: center;
@@ -360,7 +238,7 @@ main {
.demi-wall-corner-up-right { .demi-wall-corner-up-right {
background-color: #DADEEF; background-color: #DADEEF;
background-image: url("/web/assets/img/tiles/TopRight.svg"); background-image: url("../img/tiles/TopRight.svg");
background-size: 100%; background-size: 100%;
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: center; background-position: center;
@@ -368,7 +246,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/BottomLeftAngle.svg"); background-image: url("../img/tiles/BottomLeft.svg");
background-size: 100%; background-size: 100%;
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: center; background-position: center;
@@ -376,7 +254,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/BottomRightAngle.svg"); background-image: url("../img/tiles/BottomRight.svg");
background-size: 100%; background-size: 100%;
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: center; background-position: center;
@@ -463,24 +341,6 @@ 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: "";

View File

@@ -1,19 +1,17 @@
<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 1.61816L99 50.6182V99L1 99Z" fill="url(#paint0_linear_35_19)" stroke="url(#paint1_linear_35_19)" stroke-width="2"/> <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.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="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.5" transform="rotate(-180 5.5 13.5)" fill="#4A4A4A"/>
<circle cx="4.5" cy="8.5" r="1" transform="rotate(-180 4.5 8.5)" fill="#898989"/> <circle cx="5.5" cy="13.5" r="1" transform="rotate(-180 5.5 13.5)" fill="#898989"/>
<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.5" transform="rotate(-180 86.5 94.5)" fill="#4A4A4A"/>
<circle cx="94.5" cy="94.5" r="1" transform="rotate(-180 94.5 94.5)" fill="#898989"/> <circle cx="86.5" cy="94.5" r="1" transform="rotate(-180 86.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_35_19" x1="0" y1="0" x2="40" y2="80" gradientUnits="userSpaceOnUse"> <linearGradient id="paint0_linear_17_89" x1="0" y1="0" x2="100" y2="100" 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_35_19" x1="100" y1="50" x2="60" y2="-30" gradientUnits="userSpaceOnUse"> <linearGradient id="paint1_linear_17_89" x1="100" y1="100" x2="0" y2="0" 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.3 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1,19 +0,0 @@
<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>

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1,19 +1,17 @@
<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 99H1V50.6182L99 1.61816V99Z" fill="url(#paint0_linear_35_30)" stroke="url(#paint1_linear_35_30)" stroke-width="2"/> <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.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="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.5" transform="rotate(90 13.5 94.5)" fill="#4A4A4A"/>
<circle cx="5.5" cy="94.5" r="1" transform="rotate(90 5.5 94.5)" fill="#898989"/> <circle cx="13.5" cy="94.5" r="1" transform="rotate(90 13.5 94.5)" fill="#898989"/>
<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.5" transform="rotate(90 94.5 13.5)" fill="#4A4A4A"/>
<circle cx="5.5" cy="53.5" r="1" transform="rotate(90 5.5 53.5)" fill="#898989"/> <circle cx="94.5" cy="13.5" r="1" transform="rotate(90 94.5 13.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_35_30" x1="8.9049e-06" y1="1.50801e-06" x2="40" y2="80" gradientUnits="userSpaceOnUse"> <linearGradient id="paint0_linear_19_190" x1="0" y1="0" x2="100" y2="100" 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_35_30" x1="100" y1="50" x2="60" y2="-30" gradientUnits="userSpaceOnUse"> <linearGradient id="paint1_linear_19_190" x1="100" y1="100" x2="0" y2="0" 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.3 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1,19 +0,0 @@
<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>

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -20,14 +20,6 @@ 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 = {
@@ -38,64 +30,34 @@ const laserColors = {
}; };
const glassOptions = [ const glassOptions = [
[ laserColors.red,
{ color: laserColors.red, maxAmount: 1, currentAmount: 1 }, laserColors.blue,
{ color: laserColors.blue, maxAmount: 1, currentAmount: 1 }, laserColors.yellow,
{ 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 = [
[ [
[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, 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, 1, 0, 5, 4, 0, 10, 6, 6, 6, 6, 6], [0, 0, 0, 0, 1, 0, 5, 4, 0, 10, 6, 0, 0, 0, 0],
[6, 6, 6, 6, 7, 6, 6, 6, 6, 0, 6, 6, 6, 6, 6], [0, 0, 0, 0, 7, 6, 6, 6, 6, 0, 6, 0, 0, 0, 0],
[6, 6, 6, 6, 3, 0, 0, 0, 0, 12, 6, 6, 6, 6, 6], [0, 0, 0, 0, 3, 0, 0, 0, 0, 12, 6, 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, 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, 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, 6, 6, 6, 6, 6, 0, 10, 6, 6, 11, 0, 0, 0, 0], [0, 0, 6, 6, 6, 6, 6, 6, 6, 6, 11, 0, 0, 0, 0],
[7, 1, 0, 0, 0, 4, 0, 0, 0, 3, 21, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 17, 0, 0, 3, 6, 0, 0, 0, 0],
[0, 6, 6, 6, 6, 18, 6, 26, 22, 0, 18, 0, 0, 0, 0], [0, 0, 6, 6, 6, 6, 18, 6, 6, 0, 6, 0, 0, 0, 0],
[0, 6, 9, 0, 0, 19, 0, 0, 0, 12, 18, 0, 0, 0, 0], [0, 0, 7, 0, 0, 0, 4, 0, 0, 12, 6, 0, 0, 0, 0],
[0, 6, 0, 6, 6, 6, 6, 6, 6, 24, 23, 0, 0, 0, 0], [0, 0, 6, 6, 6, 6, 6, 6, 6, 6, 9, 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], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
], ],
@@ -125,7 +87,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;
@@ -136,9 +98,9 @@ const initialMirrorAngles = [
}, },
{}, {},
{ {
"2,9": 225, "3,4": 315,
"7,8": 0,
}, },
{}
]; ];
const buttonGroups = [ const buttonGroups = [
@@ -146,9 +108,7 @@ const buttonGroups = [
"4,6": 1, "4,6": 1,
}, },
{}, {},
{ {},
"9,4": 1,
},
]; ];
const doorGroups = [ const doorGroups = [
@@ -172,9 +132,6 @@ 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 },
}, },
@@ -191,9 +148,6 @@ 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];
@@ -203,131 +157,6 @@ 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);
@@ -537,40 +366,17 @@ function createPalette() {
palette.innerHTML = ""; palette.innerHTML = "";
const currentGlassOptions = getCurrentGlassOptions(); for (let i = 0; i < glassOptions.length; i++) {
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 = glassOption.currentAmount > 0; glassButton.draggable = true;
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);
} }
} }
@@ -581,8 +387,7 @@ function addDropEvents(cell, x, y) {
return; return;
} }
const transferTypes = event.dataTransfer ? Array.from(event.dataTransfer.types || []) : []; if (!event.dataTransfer.types.includes("application/x-glass-color")) {
if (!draggedGlassColor) {
return; return;
} }
@@ -591,13 +396,6 @@ 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");
}); });
@@ -611,8 +409,7 @@ function addDropEvents(cell, x, y) {
return; return;
} }
const transferredColor = event.dataTransfer ? event.dataTransfer.getData("application/x-glass-color") : ""; const selectedColor = 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) {
@@ -623,21 +420,8 @@ 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();
}); });
@@ -647,16 +431,7 @@ 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();
} }
}); });
@@ -713,7 +488,7 @@ function loadGrid() {
cell.classList.add("mirror"); cell.classList.add("mirror");
const currentAngle = mirrorOrientations[`${y},${x}`] || 0; const currentAngle = mirrorOrientations[`${y},${x}`] || 0;
const img = document.createElement("img"); const img = document.createElement("img");
img.src = "/web/assets/img/tiles/Mirror.svg"; img.src = "../../assets/img/tiles/Mirror.svg";
img.classList.add("mirror-img"); img.classList.add("mirror-img");
img.style.transform = `rotate(${currentAngle}deg)`; img.style.transform = `rotate(${currentAngle}deg)`;
@@ -795,27 +570,6 @@ 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}`]);
@@ -887,21 +641,10 @@ 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:
saveLaserSegment(currentX, currentY, laserDirection, currentLaserColor); laserActive = false;
break; break;
case legend.empty: case legend.empty:
@@ -932,27 +675,7 @@ 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) {
@@ -981,14 +704,6 @@ 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}`;
@@ -1008,44 +723,7 @@ 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}`;
@@ -1064,37 +742,25 @@ function traceLaser() {
break; break;
case legend.demiWallCornerUpLeft: case legend.demiWallCornerUpLeft:
if (currentLaserColor === laserColors.yellow) { if(currentLaserColor === laserColors.blue) {
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.yellow) { if(currentLaserColor === laserColors.blue) {
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.yellow) { if(currentLaserColor === laserColors.blue) {
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.yellow) { if(currentLaserColor === laserColors.blue) {
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;
@@ -1115,46 +781,59 @@ 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 goToLevel(levelIndex) { function nextLevel () {
currentLevelIndex = levelIndex; currentLevelIndex++;
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();
mirrorOrientations = {}; if (currentLevelIndex >= levels.length) {
currentLevelIndex = 0;
}
initializeMirrorOrientations();
loadGrid();
laserSegments = {}; laserSegments = {};
mirrorOrientations = {};
glassPlacements = {};
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();

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

@@ -0,0 +1,9 @@
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)`;
}

View File

@@ -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/web/assets/assets/css/game.css"> <link rel="stylesheet" href="../../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,16 +15,6 @@
<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',
@@ -56,6 +46,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//eb/assets/assets/js/game.js" defer></script> <script src="../../assets/js/game.js" defer></script>
</body> </body>
</html> </html>