37 Commits

Author SHA1 Message Date
Sysy's
36fa5a9092 Support per-level game element configs
Convert global config maps (initialMirrorAngles, buttonGroups, doorGroups, captorGroups, rotatorButtons) into per-level arrays and add getCurrentLevelConfig(levelConfigs) helper. Update getButtonGroup, getDoorGroup, getCaptorGroup, getRotatorButtonConfig, isMirrorControlledByButton, syncRotatorButtons and initializeMirrorOrientations to pull configs for the current level. Also tweak a couple of level tiles and add a rotator button config for the third level ("3,7": { mirrorX: 7, mirrorY: 7, step: -22.5, intervalMs: 1000 }) while keeping empty objects for levels without overrides. These changes enable per-level customization of mirrors, buttons, doors, captors and rotators.
2026-03-31 13:39:58 +02:00
Sysy's
f9e94f5c18 Implement captors and color-dependent laser effects
Add captor support and related door-toggling state plus color-specific laser interactions. Changes include: replace one level tile value (15 -> 20), add captorGroups/getCaptorGroup, add toggleDoorsFromCaptor, and new state (toggledDoors, poweredCaptors). traceLaser now initializes openedDoors from toggledDoors, tracks nextPoweredCaptors, handles captor tiles (red lasers power/toggle door groups, yellow passes, others stop), updates poweredCaptors, and applies color-based behavior for rotator buttons and demi-wall reflections (only reflect for blue). Reset toggledDoors and poweredCaptors on next level. These changes implement captor mechanics that toggle door groups and ensure correct color-dependent laser effects.
2026-03-31 13:39:58 +02:00
Sysy's
1ad8282833 Remove rotatorButton on lvl 1 2026-03-31 13:39:58 +02:00
4b8a650c26 Level 3 2026-03-31 13:39:52 +02:00
Sysy's
94a60de6b2 Add rotator buttons and auto-rotating mirrors
Introduce a new rotator button tile and mirror auto-rotation feature. CSS adds styles for rotator buttons and locked mirror display. JS: add legend entry and rotatorButtons config, track activeRotatorButtons and rotatorIntervals, implement rotateMirrorStep, isMirrorControlledByButton, syncRotatorButtons and stopAllRotatorButtons; wire rotator behavior into traceLaser and loadGrid so rotator buttons activate intervals that rotate target mirrors automatically and lock out manual rotation. Refactor rotateMirror to reuse rotation step logic and ensure rotator intervals are cleared when advancing levels.
2026-03-31 13:38:24 +02:00
663e89de9e Level 2 2026-03-31 13:38:24 +02:00
0ccd551ef8 Level 2 2026-03-31 13:38:24 +02:00
7131b876cc Level 2 2026-03-31 13:38:24 +02:00
Sysy's
8517ac89da Add win overlay 2026-03-31 13:38:24 +02:00
Sysy's
be14f4513c Add game title and update layout styles
Adjust UI visuals: change page background to #FFF6E5, increase main container border-radius from 10px to 150px, and soften toolbox corners (5px → 15px). Add a new .game-title CSS rule (responsive font-size, weight, color, letter-spacing, centered) and insert an <h1 class="game-title">Mirror Game</h1> into the game template. These are visual polish changes only; no gameplay logic was modified.
2026-03-31 13:38:24 +02:00
Sysy's
0c2d989ad8 Make size bigger + add ads 2026-03-31 13:38:24 +02:00
Sysy's
1c59e7af7a Fix textures/button/lasers & add ads 2026-03-31 13:38:24 +02:00
63c4244e92 Resolution merge conflicts 2026-03-31 13:38:24 +02:00
4d1ed00f03 Map modified + sprites 2026-03-31 13:38:24 +02:00
Sysy's
40a8dee263 Add diagonal lasers 2026-03-31 13:38:24 +02:00
Sysy's
d8f56cb548 Remove player + right click change rotation mirror 2026-03-31 13:38:24 +02:00
Sysy's
853a6ae9ee Make mirror rotate on click 2026-03-31 13:38:24 +02:00
Sysy's
6d81f67ddf Track laser segments and update UI theme
Add per-cell laserSegments tracking and use it to render correct laser orientation: introduce laserSegments global, reset it at trace start, populate entries when tracing, and consult it in loadGrid to choose horizontal vs vertical classes. Update UI styling from a dark to a lighter theme (body and main backgrounds, cell/empty/mirror/wall colors and laser gradients), remove some borders/fit-content sizing, and add a "map" class to the map container in the HTML. These changes fix laser orientation rendering and refresh the game's visual theme.
2026-03-31 13:38:24 +02:00
2c03331663 Upgrade of design of light of laser + add posibility to move a cursor and rotate mirror with keyboard 2026-03-31 13:38:03 +02:00
3e6a2130e9 Laser print and reflect 2026-03-31 13:38:02 +02:00
2eb7bd46dc First version of button for mirrors 2026-03-31 13:38:02 +02:00
a9c4c653d2 Grid enlargement 2026-03-31 13:38:02 +02:00
e787094078 Rebase of feature/mirror + merge with the grid program 2026-03-31 13:38:02 +02:00
Sysy's
1ade298ff5 Add rotateMirror to rotate element 45°
Add a small utility function in web/assets/js/index.js that increments an element's CSS rotation by 45 degrees. The function reads the element's inline transform (handling an empty value), parses the current rotation angle modulo 360, and sets the new rotate(angle+45) value.
2026-03-31 13:38:02 +02:00
d5a84144ef Change index.js and index.css to game.js and game.css 2026-03-31 13:38:02 +02:00
1276edf2f2 End of grid 2026-03-31 13:38:02 +02:00
90e2064ec9 First version of laser 2026-03-31 13:38:02 +02:00
34b76b2cb9 Print grid on html + minimalist css (which will not be used) 2026-03-31 13:38:02 +02:00
ee415c3d8b add check command and user object in user.rs file 2026-03-31 11:40:03 +02:00
e77fb7cb1e Merge branch 'main' of https://git.ninolbt.com/Nono/Projet_48h 2026-03-31 09:22:55 +02:00
4c1a439319 update and add insert command in user.rs file 2026-03-31 09:22:43 +02:00
999d27936a Update README 2026-03-31 09:19:26 +02:00
b509c9f4c3 sql rust interaction file update 2026-03-30 17:01:50 +02:00
26cdc99701 add sql rust interaction file 2026-03-30 15:48:14 +02:00
554d44cebb Merge branch 'backend-axum' of https://git.ninolbt.com/Nono/Projet_48h 2026-03-30 12:14:20 +02:00
GreyRav
3ad5811566 add : all folder + files for backend project 2026-03-30 11:42:42 +02:00
GreyRav
a8a0f54cb7 add : gitignore for target forlder 2026-03-30 11:27:04 +02:00
9 changed files with 1246 additions and 59 deletions

View File

@@ -1,19 +1,31 @@
Règles : Règles :
Un rayon laser constant
Un ou plusieurs laser - Un rayon laser constant
Laser non movibles, on/off
Mirroirs orientables - Un ou plusieurs laser
Prisme (dédouble le laser ou le renvoi selon l'angle)
Vitre colorée fixe ou placable par le joueur (r,j,b) - Laser non movibles, peut-être allumé/éteins
Bouton allumable par clique souris (interaction porte, mirroir, etc)
Bouton allumable par laser spécifique (interaction porte, mirroir, etc) - Mirroirs orientables
- Prisme (dédouble le laser ou le renvoi selon l'angle)
- Vitre colorée fixe ou placable par le joueur (r,j,b)
- Bouton allumable par clique souris (interaction porte, mirroir, etc)
- Bouton allumable par laser spécifique (interaction porte, mirroir, etc)
Rayon : Rayon :
Blanc -> rebondis seulement sur les mirroirs et s'arrête contre les murs
Rouge -> Allumage boutons - Blanc -> Rebondis seulement sur les mirroirs et s'arrête contre les murs
Bleu -> Rebondis sur toutes les surfaces
Jaune -> Traverse tout (mirroir compris) - Rouge -> Allumage des récepteurs
- Bleu -> Rebondis sur toutes les surfaces (murs compris)
- Jaune -> Traverse tout (mirroir compris)
Systeme de placement d'objet par grille Systeme de placement d'objet par grille

759
backend/Cargo.lock generated Normal file
View File

@@ -0,0 +1,759 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "atomic-waker"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
[[package]]
name = "autocfg"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
[[package]]
name = "axum"
version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b52af3cb4058c895d37317bb27508dccc8e5f2d39454016b297bf4a400597b8"
dependencies = [
"axum-core",
"bytes",
"form_urlencoded",
"futures-util",
"http",
"http-body",
"http-body-util",
"hyper",
"hyper-util",
"itoa",
"matchit",
"memchr",
"mime",
"percent-encoding",
"pin-project-lite",
"serde_core",
"serde_json",
"serde_path_to_error",
"serde_urlencoded",
"sync_wrapper",
"tokio",
"tower",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "axum-core"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1"
dependencies = [
"bytes",
"futures-core",
"http",
"http-body",
"http-body-util",
"mime",
"pin-project-lite",
"sync_wrapper",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "axum-server"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1df331683d982a0b9492b38127151e6453639cd34926eb9c07d4cd8c6d22bfc"
dependencies = [
"bytes",
"either",
"fs-err",
"http",
"http-body",
"hyper",
"hyper-util",
"tokio",
"tower-service",
]
[[package]]
name = "backend"
version = "0.1.0"
dependencies = [
"axum",
"axum-server",
"serde",
"tokio",
"tracing-subscriber",
]
[[package]]
name = "bitflags"
version = "2.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
[[package]]
name = "bytes"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
[[package]]
name = "cfg-if"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "either"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
[[package]]
name = "equivalent"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
name = "errno"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
dependencies = [
"libc",
"windows-sys",
]
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "form_urlencoded"
version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf"
dependencies = [
"percent-encoding",
]
[[package]]
name = "fs-err"
version = "3.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73fde052dbfc920003cfd2c8e2c6e6d4cc7c1091538c3a24226cec0665ab08c0"
dependencies = [
"autocfg",
"tokio",
]
[[package]]
name = "futures-channel"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d"
dependencies = [
"futures-core",
]
[[package]]
name = "futures-core"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d"
[[package]]
name = "futures-sink"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893"
[[package]]
name = "futures-task"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393"
[[package]]
name = "futures-util"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6"
dependencies = [
"futures-core",
"futures-task",
"pin-project-lite",
"slab",
]
[[package]]
name = "h2"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54"
dependencies = [
"atomic-waker",
"bytes",
"fnv",
"futures-core",
"futures-sink",
"http",
"indexmap",
"slab",
"tokio",
"tokio-util",
"tracing",
]
[[package]]
name = "hashbrown"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
[[package]]
name = "http"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a"
dependencies = [
"bytes",
"itoa",
]
[[package]]
name = "http-body"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
dependencies = [
"bytes",
"http",
]
[[package]]
name = "http-body-util"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a"
dependencies = [
"bytes",
"futures-core",
"http",
"http-body",
"pin-project-lite",
]
[[package]]
name = "httparse"
version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
[[package]]
name = "httpdate"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
[[package]]
name = "hyper"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11"
dependencies = [
"atomic-waker",
"bytes",
"futures-channel",
"futures-core",
"h2",
"http",
"http-body",
"httparse",
"httpdate",
"itoa",
"pin-project-lite",
"pin-utils",
"smallvec",
"tokio",
]
[[package]]
name = "hyper-util"
version = "0.1.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0"
dependencies = [
"bytes",
"http",
"http-body",
"hyper",
"pin-project-lite",
"tokio",
"tower-service",
]
[[package]]
name = "indexmap"
version = "2.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017"
dependencies = [
"equivalent",
"hashbrown",
]
[[package]]
name = "itoa"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
[[package]]
name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "libc"
version = "0.2.183"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d"
[[package]]
name = "lock_api"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
dependencies = [
"scopeguard",
]
[[package]]
name = "log"
version = "0.4.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
[[package]]
name = "matchit"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3"
[[package]]
name = "memchr"
version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
[[package]]
name = "mime"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
[[package]]
name = "mio"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1"
dependencies = [
"libc",
"wasi",
"windows-sys",
]
[[package]]
name = "nu-ansi-term"
version = "0.50.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
dependencies = [
"windows-sys",
]
[[package]]
name = "once_cell"
version = "1.21.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
[[package]]
name = "parking_lot"
version = "0.12.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a"
dependencies = [
"lock_api",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.9.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"smallvec",
"windows-link",
]
[[package]]
name = "percent-encoding"
version = "2.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
[[package]]
name = "pin-project-lite"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
[[package]]
name = "pin-utils"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "proc-macro2"
version = "1.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
dependencies = [
"proc-macro2",
]
[[package]]
name = "redox_syscall"
version = "0.5.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
dependencies = [
"bitflags",
]
[[package]]
name = "ryu"
version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f"
[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "serde"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [
"serde_core",
]
[[package]]
name = "serde_core"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.149"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
dependencies = [
"itoa",
"memchr",
"serde",
"serde_core",
"zmij",
]
[[package]]
name = "serde_path_to_error"
version = "0.1.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457"
dependencies = [
"itoa",
"serde",
"serde_core",
]
[[package]]
name = "serde_urlencoded"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
dependencies = [
"form_urlencoded",
"itoa",
"ryu",
"serde",
]
[[package]]
name = "sharded-slab"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
dependencies = [
"lazy_static",
]
[[package]]
name = "signal-hook-registry"
version = "1.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b"
dependencies = [
"errno",
"libc",
]
[[package]]
name = "slab"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5"
[[package]]
name = "smallvec"
version = "1.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
[[package]]
name = "socket2"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e"
dependencies = [
"libc",
"windows-sys",
]
[[package]]
name = "syn"
version = "2.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "sync_wrapper"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263"
[[package]]
name = "thread_local"
version = "1.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185"
dependencies = [
"cfg-if",
]
[[package]]
name = "tokio"
version = "1.50.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27ad5e34374e03cfffefc301becb44e9dc3c17584f414349ebe29ed26661822d"
dependencies = [
"bytes",
"libc",
"mio",
"parking_lot",
"pin-project-lite",
"signal-hook-registry",
"socket2",
"tokio-macros",
"windows-sys",
]
[[package]]
name = "tokio-macros"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c55a2eff8b69ce66c84f85e1da1c233edc36ceb85a2058d11b0d6a3c7e7569c"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tokio-util"
version = "0.7.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098"
dependencies = [
"bytes",
"futures-core",
"futures-sink",
"pin-project-lite",
"tokio",
]
[[package]]
name = "tower"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4"
dependencies = [
"futures-core",
"futures-util",
"pin-project-lite",
"sync_wrapper",
"tokio",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "tower-layer"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e"
[[package]]
name = "tower-service"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"
[[package]]
name = "tracing"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100"
dependencies = [
"log",
"pin-project-lite",
"tracing-core",
]
[[package]]
name = "tracing-core"
version = "0.1.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a"
dependencies = [
"once_cell",
"valuable",
]
[[package]]
name = "tracing-log"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
dependencies = [
"log",
"once_cell",
"tracing-core",
]
[[package]]
name = "tracing-subscriber"
version = "0.3.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319"
dependencies = [
"nu-ansi-term",
"sharded-slab",
"smallvec",
"thread_local",
"tracing-core",
"tracing-log",
]
[[package]]
name = "unicode-ident"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
[[package]]
name = "valuable"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
[[package]]
name = "wasi"
version = "0.11.1+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
[[package]]
name = "windows-link"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
[[package]]
name = "windows-sys"
version = "0.61.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
dependencies = [
"windows-link",
]
[[package]]
name = "zmij"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"

11
backend/Cargo.toml Normal file
View File

@@ -0,0 +1,11 @@
[package]
name = "backend"
version = "0.1.0"
edition = "2024"
[dependencies]
axum = "0.8.8"
axum-server = "0.8.0"
serde = "1.0.228"
tokio = { version = "1.50.0", features = ["full"] }
tracing-subscriber = "0.3.23"

View File

14
backend/src/main.rs Normal file
View File

@@ -0,0 +1,14 @@
use axum::{routing::get, Router};
use std::net::SocketAddr;
#[tokio::main]
async fn main() {
let app = Router::new().route("/", get(|| async { "Hello, world!" }));
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
println!("listening on {}", addr);
axum_server::bind(addr)
.serve(app.into_make_service())
.await
.unwrap();
}

64
backend/user.rs Normal file
View File

@@ -0,0 +1,64 @@
use sqlite::Connection;
use sqlite::State;
pub struct User {
name: String,
level: u32,
password: String,
}
impl User {
pub fn open(name: String, level: u32, password: String) -> User {
User {name, level, password}
}
}
pub struct DataBase {
connection: Connection,
}
impl DataBase {
pub fn open(name: String) -> DataBase {
let connection = sqlite::open(name + ".db").unwrap();
DataBase { connection }
}
fn execute(&self, arg: String){
match self.connection.execute(arg){
_ => (),
Err(e) => panic!("Error : {}",e),
}
}
pub fn create_table(&self, table: &str, var: &str){
self.execute("CREATE TABLE ".to_owned() + &table.to_string() + "(" + &var.to_string() + ");");
}
pub fn add_column(&self, table: &str, arg: &str){
self.execute("ALTER TABLE ".to_owned() + &table.to_string() + " ADD " + &arg.to_string() + ";");
}
pub fn insert(&self, table: &str, arg: &str){
self.execute("INSERT INTO ".to_owned() + &table.to_string() + " VALUES (" + &arg.to_string() + ")" + ";");
}
pub fn check(&self, table: &str, arg: &str) -> bool {
let mut end = false;
self.connection.iterate("Select name FROM ".to_owned() + &table.to_string() + " WHERE name = " + &arg.to_string(), |pairs| {
for &(name, value) in pairs.iter() {
println!("{} = {}", name, value.unwrap());
if name == "name" {
println!("True");
end = true;
}
}
return end;
});
return end;
}
pub fn update(&self, table: &str, arg: &str, where_is: &str, arg2: &str){
self.execute("UPDATE ".to_owned() + &table.to_string() + " SET " + &arg.to_string() + " WHERE " + &where_is.to_string() + " = " + &arg2.to_string());
}
}

View File

@@ -143,6 +143,40 @@ main {
background-position: center; background-position: center;
} }
.captor {
background-color: #DADEEF;
background-image: url("../img/tiles/Capteur-1.svg");
background-size: 100%;
background-repeat: no-repeat;
background-position: center;
transform: rotate(180deg);
}
.captor-turn {
background-color: #DADEEF;
background-image: url("../img/tiles/Capteur-2.svg");
background-size: 100%;
background-repeat: no-repeat;
background-position: center;
}
.cable {
background-color: #DADEEF;
background-image: url("../img/tiles/CableV.svg");
background-size: 100%;
background-repeat: no-repeat;
background-position: center;
transform: rotate(90deg);
}
.cable-vertical {
background-color: #DADEEF;
background-image: url("../img/tiles/CableV.svg");
background-size: 100%;
background-repeat: no-repeat;
background-position: center;
}
.door { .door {
background-color: #DADEEF; background-color: #DADEEF;
background-image: url("../img/tiles/WoodenDoor.svg"); background-image: url("../img/tiles/WoodenDoor.svg");
@@ -174,6 +208,14 @@ main {
background-position: center; background-position: center;
} }
.button-rotator {
background-color: #DADEEF;
background-image: url("../img/tiles/ButtonProfile.svg"), url("../img/tiles/Tuile.svg");
background-size: 100% 100%;
background-repeat: no-repeat;
background-position: center;
}
.button-active { .button-active {
opacity: 0.7; opacity: 0.7;
} }
@@ -274,6 +316,10 @@ main {
justify-content: center; justify-content: center;
} }
.btn-mirror-locked {
cursor: default;
}
.mirror-img { .mirror-img {
width: 80%; width: 80%;
height: 80%; height: 80%;

View File

@@ -16,6 +16,10 @@ const legend = {
demiWallCornerDownRight: 12, demiWallCornerDownRight: 12,
doorOpen: 13, doorOpen: 13,
button2: 14, button2: 14,
captor: 15,
cable: 16,
captorTurn: 17,
cableVertical: 18,
}; };
const laserColors = { const laserColors = {
@@ -44,21 +48,94 @@ 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, 6, 6, 6, 6, 6, 6, 6, 6, 11, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 17, 0, 0, 3, 6, 0, 0, 0, 0],
[0, 0, 6, 6, 6, 6, 18, 6, 6, 0, 6, 0, 0, 0, 0],
[0, 0, 7, 0, 0, 0, 4, 0, 0, 12, 6, 0, 0, 0, 0],
[0, 0, 6, 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, 0, 0, 0, 6, 6, 6, 6, 6, 6, 11, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 10, 6, 0, 0, 0, 0],
[0, 0, 0, 3, 0, 16, 16, 20, 0, 3, 6, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 6, 0, 0, 0, 0],
[0, 0, 0, 0, 12, 6, 6, 6, 6, 6, 9, 0, 0, 0, 0],
[0, 0, 0, 0, 6, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 6, 0, 0, 3, 0, 0, 7, 0, 0, 0, 0],
[0, 0, 0, 0, 6, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 10, 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, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 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 = [
"6,4": 315, {
}; "6,4": 315,
},
{},
{
"3,4": 315,
"7,8": 0,
},
];
const buttonGroups = { const buttonGroups = [
"4,6": 1, {
}; "4,6": 1,
},
{},
{},
];
const doorGroups = { const doorGroups = [
"4,7": 1, {
}; "4,7": 1,
},
{
"4,6": 1,
},
{},
];
const captorGroups = [
{},
{
"2,6": 1,
},
{},
];
const rotatorButtons = [
{},
{},
{
"3,7": { mirrorX: 7, mirrorY: 7, step: -22.5, intervalMs: 1000 },
},
];
let laserDirection = { dx: 0, dy: 0 }; let laserDirection = { dx: 0, dy: 0 };
let laserSegments = {}; let laserSegments = {};
@@ -67,11 +144,19 @@ let glassPlacements = {};
let activatedButtons = {}; let activatedButtons = {};
let openedDoors = {}; let openedDoors = {};
let isLevelFinished = false; let isLevelFinished = false;
let activeRotatorButtons = {};
let rotatorIntervals = {};
let toggledDoors = {};
let poweredCaptors = {};
function getCurrentLevel() { function getCurrentLevel() {
return levels[currentLevelIndex]; return levels[currentLevelIndex];
} }
function getCurrentLevelConfig(configByLevel) {
return configByLevel[currentLevelIndex] || {};
}
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);
@@ -129,11 +214,15 @@ function getButtonGroup(x, y) {
return 2; return 2;
} }
return buttonGroups[`${y},${x}`] || 1; return getCurrentLevelConfig(buttonGroups)[`${y},${x}`] || 1;
} }
function getDoorGroup(x, y) { function getDoorGroup(x, y) {
return doorGroups[`${y},${x}`] || 1; return getCurrentLevelConfig(doorGroups)[`${y},${x}`] || 1;
}
function getCaptorGroup(x, y) {
return getCurrentLevelConfig(captorGroups)[`${y},${x}`] || getDoorGroup(x, y);
} }
function openDoorsFromButton(x, y) { function openDoorsFromButton(x, y) {
@@ -149,6 +238,90 @@ function openDoorsFromButton(x, y) {
} }
} }
function toggleDoorsFromCaptor(x, y) {
const captorGroup = getCaptorGroup(x, y);
const level = getCurrentLevel();
for (let doorY = 0; doorY < level.length; doorY++) {
for (let doorX = 0; doorX < level[doorY].length; doorX++) {
const coordKey = `${doorY},${doorX}`;
if (level[doorY][doorX] === legend.door && getDoorGroup(doorX, doorY) === captorGroup) {
toggledDoors[coordKey] = !toggledDoors[coordKey];
}
}
}
}
function getRotatorButtonConfig(x, y) {
return getCurrentLevelConfig(rotatorButtons)[`${y},${x}`];
}
function isMirrorControlledByButton(x, y) {
const rotatorEntries = Object.values(getCurrentLevelConfig(rotatorButtons));
for (let i = 0; i < rotatorEntries.length; i++) {
const rotatorConfig = rotatorEntries[i];
if (rotatorConfig.mirrorX === x && rotatorConfig.mirrorY === y) {
return true;
}
}
return false;
}
function rotateMirrorStep(x, y, angleStep) {
const coordKey = `${y},${x}`;
if (getCurrentLevel()[y][x] !== legend.mirror) {
return;
}
let currentAngle = mirrorOrientations[coordKey] || 0;
currentAngle = (currentAngle + angleStep) % 360;
if (currentAngle < 0) {
currentAngle += 360;
}
mirrorOrientations[coordKey] = currentAngle;
}
function syncRotatorButtons() {
const currentLevelRotatorButtons = getCurrentLevelConfig(rotatorButtons);
const rotatorKeys = Object.keys(currentLevelRotatorButtons);
for (let i = 0; i < rotatorKeys.length; i++) {
const key = rotatorKeys[i];
const config = currentLevelRotatorButtons[key];
const isActive = activeRotatorButtons[key] === true;
if (isActive && !rotatorIntervals[key]) {
rotatorIntervals[key] = window.setInterval(() => {
rotateMirrorStep(config.mirrorX, config.mirrorY, -22.5);
traceLaser();
}, 1000);
}
if (!isActive && rotatorIntervals[key]) {
window.clearInterval(rotatorIntervals[key]);
delete rotatorIntervals[key];
}
}
}
function stopAllRotatorButtons() {
const intervalKeys = Object.keys(rotatorIntervals);
for (let i = 0; i < intervalKeys.length; i++) {
const key = intervalKeys[i];
window.clearInterval(rotatorIntervals[key]);
}
rotatorIntervals = {};
}
function saveLaserSegment(x, y, direction, color) { function saveLaserSegment(x, y, direction, color) {
laserSegments[`${y},${x}`] = { laserSegments[`${y},${x}`] = {
direction: { ...direction }, direction: { ...direction },
@@ -281,7 +454,7 @@ function initializeMirrorOrientations() {
for (let y = 0; y < level.length; y++) { for (let y = 0; y < level.length; y++) {
for (let x = 0; x < level[y].length; x++) { for (let x = 0; x < level[y].length; x++) {
if (level[y][x] === legend.mirror) { if (level[y][x] === legend.mirror) {
mirrorOrientations[`${y},${x}`] = initialMirrorAngles[`${y},${x}`] || 0; mirrorOrientations[`${y},${x}`] = getCurrentLevelConfig(initialMirrorAngles)[`${y},${x}`] || 0;
} }
} }
} }
@@ -314,23 +487,31 @@ function loadGrid() {
case legend.mirror: case legend.mirror:
cell.classList.add("mirror"); cell.classList.add("mirror");
const currentAngle = mirrorOrientations[`${y},${x}`] || 0; const currentAngle = mirrorOrientations[`${y},${x}`] || 0;
const btnMirror = document.createElement("button");
btnMirror.classList.add("btn-mirror");
btnMirror.type = "button";
const img = document.createElement("img"); const img = document.createElement("img");
img.src = "../../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)`;
btnMirror.appendChild(img);
btnMirror.onmousedown = (event) => { if (isMirrorControlledByButton(x, y)) {
event.preventDefault(); const mirrorDisplay = document.createElement("div");
event.stopPropagation(); mirrorDisplay.classList.add("btn-mirror", "btn-mirror-locked");
if (!isLevelFinished) { mirrorDisplay.appendChild(img);
rotateMirror(x, y, event.button === 2); cell.appendChild(mirrorDisplay);
} } else {
}; const btnMirror = document.createElement("button");
btnMirror.oncontextmenu = (event) => event.preventDefault(); btnMirror.classList.add("btn-mirror");
cell.appendChild(btnMirror); btnMirror.type = "button";
btnMirror.appendChild(img);
btnMirror.onmousedown = (event) => {
event.preventDefault();
event.stopPropagation();
if (!isLevelFinished) {
rotateMirror(x, y, event.button === 2);
}
};
btnMirror.oncontextmenu = (event) => event.preventDefault();
cell.appendChild(btnMirror);
}
break; break;
case legend.door: case legend.door:
cell.classList.add("door"); cell.classList.add("door");
@@ -353,6 +534,12 @@ function loadGrid() {
cell.classList.add("button-active"); cell.classList.add("button-active");
} }
break; break;
case legend.rotatorButton:
cell.classList.add("button", "button-rotator");
if (activatedButtons[`${y},${x}`]) {
cell.classList.add("button-active");
}
break;
case legend.wall: case legend.wall:
cell.classList.add("wall"); cell.classList.add("wall");
break; break;
@@ -371,6 +558,18 @@ function loadGrid() {
case legend.demiWallCornerDownRight: case legend.demiWallCornerDownRight:
cell.classList.add("demi-wall-corner-down-right"); cell.classList.add("demi-wall-corner-down-right");
break; break;
case legend.captor:
cell.classList.add("captor");
break;
case legend.cable:
cell.classList.add("cable");
break;
case legend.captorTurn:
cell.classList.add("captor-turn");
break;
case legend.cableVertical:
cell.classList.add("cable-vertical");
break;
} }
drawLaserInCell(cell, laserSegments[`${y},${x}`]); drawLaserInCell(cell, laserSegments[`${y},${x}`]);
@@ -383,28 +582,17 @@ function loadGrid() {
} }
function rotateMirror(x, y, isRightClick) { function rotateMirror(x, y, isRightClick) {
const coordKey = `${y},${x}`; rotateMirrorStep(x, y, isRightClick ? 22.5 : -22.5);
if (getCurrentLevel()[y][x] !== legend.mirror) {
return;
}
let currentAngle = mirrorOrientations[coordKey] || 0;
currentAngle = (currentAngle + (isRightClick ? 22.5 : -22.5)) % 360;
if (currentAngle < 0) {
currentAngle += 360;
}
mirrorOrientations[coordKey] = currentAngle;
traceLaser(); traceLaser();
} }
function traceLaser() { function traceLaser() {
laserSegments = {}; laserSegments = {};
activatedButtons = {}; activatedButtons = {};
openedDoors = {}; openedDoors = { ...toggledDoors };
activeRotatorButtons = {};
isLevelFinished = false; isLevelFinished = false;
const nextPoweredCaptors = {};
const level = getCurrentLevel(); const level = getCurrentLevel();
let startLaserX; let startLaserX;
@@ -500,7 +688,6 @@ function traceLaser() {
laserActive = false; laserActive = false;
} }
break; break;
case legend.button: case legend.button:
case legend.button2: case legend.button2:
if (currentLaserColor === laserColors.red) { if (currentLaserColor === laserColors.red) {
@@ -516,20 +703,66 @@ function traceLaser() {
} }
break; break;
case legend.captor:
case legend.captorTurn:
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:
if (currentLaserColor === laserColors.red) {
const rotatorKey = `${currentY},${currentX}`;
activatedButtons[rotatorKey] = true;
activeRotatorButtons[rotatorKey] = true;
saveLaserSegment(currentX, currentY, laserDirection, currentLaserColor);
laserActive = false;
} else if (currentLaserColor === laserColors.yellow) {
saveLaserSegment(currentX, currentY, laserDirection, currentLaserColor);
} else if (currentLaserColor === laserColors.blue) {
laserDirection = reverseLaser(laserDirection);
laserActive = false;
} else {
laserActive = false;
}
break;
case legend.demiWallCornerUpLeft: case legend.demiWallCornerUpLeft:
laserDirection = reflectLaser(laserDirection, 135); if(currentLaserColor === laserColors.blue) {
laserDirection = reflectLaser(laserDirection, 135);
}
break; break;
case legend.demiWallCornerUpRight: case legend.demiWallCornerUpRight:
laserDirection = reflectLaser(laserDirection, 45); if(currentLaserColor === laserColors.blue) {
laserDirection = reflectLaser(laserDirection, 45);
}
break; break;
case legend.demiWallCornerDownLeft: case legend.demiWallCornerDownLeft:
laserDirection = reflectLaser(laserDirection, 225); if(currentLaserColor === laserColors.blue) {
laserDirection = reflectLaser(laserDirection, 225);
}
break; break;
case legend.demiWallCornerDownRight: case legend.demiWallCornerDownRight:
laserDirection = reflectLaser(laserDirection, 315); if(currentLaserColor === laserColors.blue) {
laserDirection = reflectLaser(laserDirection, 315);
}
break; break;
default: default:
@@ -538,6 +771,8 @@ function traceLaser() {
} }
} }
poweredCaptors = nextPoweredCaptors;
syncRotatorButtons();
loadGrid(); loadGrid();
if (isLevelFinished) { if (isLevelFinished) {
@@ -550,6 +785,52 @@ function finish() {
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 () {
currentLevelIndex++;
isLevelFinished = false;
if (currentLevelIndex >= levels.length) {
currentLevelIndex = 0;
}
initializeMirrorOrientations();
loadGrid();
laserSegments = {};
mirrorOrientations = {};
glassPlacements = {};
activatedButtons = {};
openedDoors = {};
traceLaser();
}
function nextLevel() {
currentLevelIndex++;
isLevelFinished = false;
stopAllRotatorButtons();
if (currentLevelIndex >= levels.length) {
currentLevelIndex = 0;
}
initializeMirrorOrientations();
loadGrid();
laserSegments = {};
mirrorOrientations = {};
glassPlacements = {};
activatedButtons = {};
openedDoors = {};
toggledDoors = {};
poweredCaptors = {};
traceLaser();
const winOverlay = document.querySelector(".win-overlay");
winOverlay.style.visibility = "hidden";
} }
createPalette(); createPalette();