XTaylorSpenceX

Lattice Labyrinth Legends

Oct 1st, 2025
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
HTML 26.63 KB | None | 0 0
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6.     <title>Lattice Labyrinth Legends - 2D</title>
  7.     <style>
  8.         * {
  9.             margin: 0;
  10.             padding: 0;
  11.             box-sizing: border-box;
  12.         }
  13.  
  14.         body {
  15.             background: linear-gradient(135deg, #0a0014, #1a0033, #0a0014);
  16.             background-size: 400% 400%;
  17.             animation: galaxyShift 20s ease infinite;
  18.             color: #fff;
  19.             font-family: 'Courier New', monospace;
  20.             overflow: hidden;
  21.             display: flex;
  22.             justify-content: center;
  23.             align-items: center;
  24.             min-height: 100vh;
  25.         }
  26.  
  27.         @keyframes galaxyShift {
  28.             0%, 100% { background-position: 0% 50%; }
  29.             50% { background-position: 100% 50%; }
  30.         }
  31.  
  32.         #gameContainer {
  33.             position: relative;
  34.             display: flex;
  35.             flex-direction: column;
  36.             align-items: center;
  37.             gap: 20px;
  38.         }
  39.  
  40.         #labyrinthWrapper {
  41.             position: relative;
  42.             padding: 20px;
  43.             background: rgba(0, 0, 0, 0.3);
  44.             border: 2px solid rgba(0, 255, 255, 0.2);
  45.             border-radius: 10px;
  46.             box-shadow: 0 0 30px rgba(0, 255, 255, 0.2);
  47.         }
  48.  
  49.         #labyrinth {
  50.             position: relative;
  51.             width: 550px;
  52.             height: 550px;
  53.             display: grid;
  54.             grid-template-columns: repeat(11, 1fr);
  55.             grid-template-rows: repeat(11, 1fr);
  56.             gap: 0;
  57.         }
  58.  
  59.         .latticeNode {
  60.             width: 50px;
  61.             height: 50px;
  62.             border: 1px solid rgba(0, 255, 255, 0.2);
  63.             background: rgba(0, 20, 40, 0.5);
  64.             position: relative;
  65.             transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
  66.         }
  67.  
  68.         .latticeNode.active {
  69.             background: radial-gradient(circle at center, rgba(0, 255, 255, 0.2), rgba(0, 255, 255, 0.05));
  70.             border-color: #00ffff;
  71.             box-shadow:
  72.                 0 0 15px rgba(0, 255, 255, 0.4),
  73.                 inset 0 0 10px rgba(0, 255, 255, 0.2);
  74.             animation: nodePulse 2s ease-in-out infinite;
  75.         }
  76.  
  77.         @keyframes nodePulse {
  78.             0%, 100% {
  79.                 border-color: #00ffff;
  80.                 box-shadow:
  81.                     0 0 15px rgba(0, 255, 255, 0.4),
  82.                     inset 0 0 10px rgba(0, 255, 255, 0.2);
  83.             }
  84.             50% {
  85.                 border-color: #00ff88;
  86.                 box-shadow:
  87.                     0 0 25px rgba(0, 255, 255, 0.6),
  88.                     inset 0 0 15px rgba(0, 255, 255, 0.3);
  89.             }
  90.         }
  91.  
  92.         .latticeNode.blocked {
  93.             background: radial-gradient(circle at center, rgba(255, 0, 102, 0.2), rgba(255, 0, 102, 0.05));
  94.             border-color: #ff0066;
  95.             box-shadow:
  96.                 0 0 10px rgba(255, 0, 102, 0.3),
  97.                 inset 0 0 5px rgba(255, 0, 102, 0.2);
  98.         }
  99.  
  100.         .latticeNode.start {
  101.             background: radial-gradient(circle at center, rgba(0, 255, 136, 0.3), rgba(0, 255, 136, 0.1)) !important;
  102.             border: 2px solid #00ff88 !important;
  103.             box-shadow:
  104.                 0 0 20px rgba(0, 255, 136, 0.5),
  105.                 inset 0 0 15px rgba(0, 255, 136, 0.3) !important;
  106.         }
  107.  
  108.         .latticeNode.end {
  109.             background: radial-gradient(circle at center, rgba(255, 215, 0, 0.3), rgba(255, 215, 0, 0.1)) !important;
  110.             border: 2px solid #ffd700 !important;
  111.             box-shadow:
  112.                 0 0 20px rgba(255, 215, 0, 0.5),
  113.                 inset 0 0 15px rgba(255, 215, 0, 0.3) !important;
  114.             animation: endPulse 1s ease-in-out infinite;
  115.         }
  116.  
  117.         @keyframes endPulse {
  118.             0%, 100% { transform: scale(1); }
  119.             50% { transform: scale(1.05); }
  120.         }
  121.  
  122.         #player {
  123.             position: absolute;
  124.             width: 30px;
  125.             height: 30px;
  126.             background: radial-gradient(circle at center, #ffffff, #00ff88, #00ff88);
  127.             border-radius: 50%;
  128.             box-shadow:
  129.                 0 0 20px #00ff88,
  130.                 0 0 40px #00ff88,
  131.                 0 0 60px rgba(0, 255, 136, 0.5),
  132.                 inset 0 0 15px rgba(255, 255, 255, 0.8);
  133.             z-index: 10;
  134.             transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
  135.             animation: playerGlow 1.5s ease-in-out infinite;
  136.             pointer-events: none;
  137.         }
  138.  
  139.         @keyframes playerGlow {
  140.             0%, 100% {
  141.                 box-shadow:
  142.                     0 0 20px #00ff88,
  143.                     0 0 40px #00ff88,
  144.                     0 0 60px rgba(0, 255, 136, 0.5),
  145.                     inset 0 0 15px rgba(255, 255, 255, 0.8);
  146.             }
  147.             50% {
  148.                 box-shadow:
  149.                     0 0 30px #00ff88,
  150.                     0 0 50px #00ff88,
  151.                     0 0 80px rgba(0, 255, 136, 0.7),
  152.                     inset 0 0 20px rgba(255, 255, 255, 1);
  153.             }
  154.         }
  155.  
  156.         .guardian {
  157.             position: absolute;
  158.             width: 35px;
  159.             height: 35px;
  160.             pointer-events: none;
  161.             z-index: 5;
  162.             opacity: 0;
  163.             transition: opacity 0.5s;
  164.         }
  165.  
  166.         .guardian.visible {
  167.             opacity: 1;
  168.             animation: guardianFloat 3s ease-in-out infinite;
  169.         }
  170.  
  171.         .guardian::before {
  172.             content: '◈';
  173.             font-size: 35px;
  174.             color: #ff00ff;
  175.             text-shadow:
  176.                 0 0 15px #ff00ff,
  177.                 0 0 30px #ff00ff,
  178.                 0 0 45px rgba(255, 0, 255, 0.5);
  179.             display: block;
  180.             animation: guardianSpin 4s linear infinite;
  181.         }
  182.  
  183.         @keyframes guardianFloat {
  184.             0%, 100% { transform: translateY(0); }
  185.             50% { transform: translateY(-5px); }
  186.         }
  187.  
  188.         @keyframes guardianSpin {
  189.             from { transform: rotate(0deg); }
  190.             to { transform: rotate(360deg); }
  191.         }
  192.  
  193.         #hud {
  194.             display: flex;
  195.             gap: 30px;
  196.             align-items: center;
  197.             background: rgba(0, 0, 0, 0.7);
  198.             padding: 15px 25px;
  199.             border: 1px solid #00ffff;
  200.             border-radius: 5px;
  201.             box-shadow: 0 0 20px rgba(0, 255, 255, 0.3);
  202.         }
  203.  
  204.         .hudItem {
  205.             font-size: 14px;
  206.             color: #00ffff;
  207.             text-shadow: 0 0 10px rgba(0, 255, 255, 0.5);
  208.             white-space: nowrap;
  209.         }
  210.  
  211.         .hudItem span {
  212.             color: #00ff88;
  213.             font-weight: bold;
  214.         }
  215.  
  216.         #cycleIndicator {
  217.             width: 150px;
  218.             height: 8px;
  219.             background: rgba(0, 0, 0, 0.8);
  220.             border: 1px solid #00ffff;
  221.             border-radius: 4px;
  222.             position: relative;
  223.             overflow: hidden;
  224.         }
  225.  
  226.         #cycleBar {
  227.             height: 100%;
  228.             background: linear-gradient(90deg, #00ff88, #00ffff);
  229.             width: 0%;
  230.             transition: width 0.1s linear;
  231.             box-shadow: 0 0 10px rgba(0, 255, 255, 0.8);
  232.         }
  233.  
  234.         #message {
  235.             position: fixed;
  236.             top: 20%;
  237.             left: 50%;
  238.             transform: translate(-50%, -50%);
  239.             font-size: 28px;
  240.             font-weight: bold;
  241.             color: #fff;
  242.             text-align: center;
  243.             text-shadow:
  244.                 0 0 20px rgba(255, 255, 255, 0.8),
  245.                 0 0 40px rgba(0, 255, 255, 0.6);
  246.             opacity: 0;
  247.             transition: opacity 0.5s;
  248.             z-index: 200;
  249.             pointer-events: none;
  250.         }
  251.  
  252.         #message.show {
  253.             opacity: 1;
  254.         }
  255.  
  256.         .particle {
  257.             position: absolute;
  258.             width: 3px;
  259.             height: 3px;
  260.             background: #00ffff;
  261.             border-radius: 50%;
  262.             pointer-events: none;
  263.             opacity: 0.6;
  264.             animation: particleDrift 4s linear infinite;
  265.         }
  266.  
  267.         @keyframes particleDrift {
  268.             0% {
  269.                 transform: translate(0, 0);
  270.                 opacity: 0;
  271.             }
  272.             10% {
  273.                 opacity: 0.6;
  274.             }
  275.             90% {
  276.                 opacity: 0.6;
  277.             }
  278.             100% {
  279.                 transform: translate(var(--drift-x), -100px);
  280.                 opacity: 0;
  281.             }
  282.         }
  283.  
  284.         #controls {
  285.             background: rgba(0, 0, 0, 0.7);
  286.             padding: 10px 20px;
  287.             border: 1px solid #00ffff;
  288.             border-radius: 5px;
  289.             text-align: center;
  290.         }
  291.  
  292.         .controlInfo {
  293.             color: #00ffff;
  294.             font-size: 12px;
  295.             margin: 3px;
  296.         }
  297.  
  298.         .pathIndicator {
  299.             position: absolute;
  300.             width: 100%;
  301.             height: 100%;
  302.             pointer-events: none;
  303.         }
  304.  
  305.         .pathIndicator::after {
  306.             content: '';
  307.             position: absolute;
  308.             top: 50%;
  309.             left: 50%;
  310.             transform: translate(-50%, -50%);
  311.             width: 10px;
  312.             height: 10px;
  313.             background: rgba(0, 255, 255, 0.5);
  314.             border-radius: 50%;
  315.             animation: pathDot 2s ease-in-out infinite;
  316.         }
  317.  
  318.         @keyframes pathDot {
  319.             0%, 100% { transform: translate(-50%, -50%) scale(1); opacity: 0.5; }
  320.             50% { transform: translate(-50%, -50%) scale(1.5); opacity: 0.8; }
  321.         }
  322.     </style>
  323. </head>
  324. <body>
  325.     <div id="gameContainer">
  326.         <div id="hud">
  327.             <div class="hudItem">ROUND: <span id="round">1</span></div>
  328.             <div class="hudItem">CRYSTALS: <span id="score">0</span></div>
  329.             <div class="hudItem">SHIFT CYCLE:</div>
  330.             <div id="cycleIndicator">
  331.                 <div id="cycleBar"></div>
  332.             </div>
  333.             <div class="hudItem">MOVES: <span id="moves">0</span></div>
  334.         </div>
  335.  
  336.         <div id="labyrinthWrapper">
  337.             <div id="labyrinth"></div>
  338.             <div id="player"></div>
  339.         </div>
  340.  
  341.         <div id="controls">
  342.             <div class="controlInfo">↑↓←→ or WASD to move | Watch the shift cycle!</div>
  343.             <div class="controlInfo">Navigate from GREEN (top-left) to GOLD (bottom-right)</div>
  344.         </div>
  345.  
  346.         <div id="message"></div>
  347.     </div>
  348.  
  349.     <script>
  350.         class LatticeLabyrinth {
  351.             constructor() {
  352.                 this.gridSize = 11;
  353.                 this.nodes = [];
  354.                 this.playerPos = { x: 0, y: 0 };
  355.                 this.startPos = { x: 0, y: 0 };
  356.                 this.endPos = { x: 10, y: 10 };
  357.                 this.score = 0;
  358.                 this.round = 1;
  359.                 this.moves = 0;
  360.                 this.cycleTime = 4000;
  361.                 this.currentCycle = 0;
  362.                 this.guardians = [];
  363.                 this.particles = [];
  364.                 this.shiftTimer = null;
  365.                 this.init();
  366.             }
  367.  
  368.             init() {
  369.                 this.createLattice();
  370.                 this.createGuardians();
  371.                 this.setupControls();
  372.                 this.startCycles();
  373.                 this.updatePlayerPosition();
  374.                 this.createParticleEffects();
  375.                 this.showMessage("Navigate to the GOLDEN EXIT!", 3000);
  376.             }
  377.  
  378.             createLattice() {
  379.                 const container = document.getElementById('labyrinth');
  380.                 container.innerHTML = '';
  381.  
  382.                 for (let y = 0; y < this.gridSize; y++) {
  383.                    this.nodes[y] = [];
  384.                    for (let x = 0; x < this.gridSize; x++) {
  385.                        const node = document.createElement('div');
  386.                        node.className = 'latticeNode';
  387.                        
  388.                        // Create initial maze pattern
  389.                        const isActive = this.generateInitialMaze(x, y);
  390.                        
  391.                        this.nodes[y][x] = {
  392.                            element: node,
  393.                            active: isActive,
  394.                            x, y
  395.                        };
  396.  
  397.                        if (isActive) {
  398.                            node.classList.add('active');
  399.                        } else {
  400.                            node.classList.add('blocked');
  401.                        }
  402.  
  403.                        // Mark start and end positions
  404.                        if (x === this.startPos.x && y === this.startPos.y) {
  405.                            node.classList.add('start');
  406.                            this.nodes[y][x].active = true;
  407.                        }
  408.                        if (x === this.endPos.x && y === this.endPos.y) {
  409.                            node.classList.add('end');
  410.                            this.nodes[y][x].active = true;
  411.                        }
  412.  
  413.                        container.appendChild(node);
  414.                    }
  415.                }
  416.  
  417.                // Ensure there's always a path
  418.                this.ensurePathExists();
  419.            }
  420.            generateInitialMaze(x, y) {
  421.                // Create an interesting initial pattern
  422.                const pattern = (x + y) % 3;
  423.                const diagonal = Math.abs(x - y) < 2;
  424.                const cross = (x === 5 || y === 5);
  425.                
  426.                // Combine patterns for variety
  427.                return pattern !== 0 || diagonal || cross || Math.random() > 0.3;
  428.             }
  429.  
  430.             ensurePathExists() {
  431.                 // Always ensure start and end are connected
  432.                 const path = this.findPath(this.startPos, this.endPos);
  433.                 if (!path) {
  434.                     // Create a simple guaranteed path
  435.                     for (let i = 0; i <= 10; i++) {
  436.                        this.nodes[i][i].active = true;
  437.                        this.nodes[i][i].element.classList.remove('blocked');
  438.                        this.nodes[i][i].element.classList.add('active');
  439.                    }
  440.                }
  441.            }
  442.  
  443.            findPath(start, end) {
  444.                // Simple pathfinding check (BFS)
  445.                const queue = [start];
  446.                const visited = new Set([`${start.x},${start.y}`]);
  447.  
  448.                while (queue.length > 0) {
  449.                     const current = queue.shift();
  450.                    
  451.                     if (current.x === end.x && current.y === end.y) {
  452.                        return true;
  453.                     }
  454.  
  455.                     const neighbors = [
  456.                         { x: current.x + 1, y: current.y },
  457.                         { x: current.x - 1, y: current.y },
  458.                         { x: current.x, y: current.y + 1 },
  459.                         { x: current.x, y: current.y - 1 }
  460.                     ];
  461.  
  462.                     for (const neighbor of neighbors) {
  463.                         const key = `${neighbor.x},${neighbor.y}`;
  464.                         if (neighbor.x >= 0 && neighbor.x < this.gridSize &&
  465.                            neighbor.y >= 0 && neighbor.y < this.gridSize &&
  466.                            !visited.has(key) &&
  467.                            this.nodes[neighbor.y][neighbor.x].active) {
  468.                            visited.add(key);
  469.                             queue.push(neighbor);
  470.                         }
  471.                     }
  472.                 }
  473.                 return false;
  474.             }
  475.  
  476.             createGuardians() {
  477.                 const positions = [
  478.                     { x: 5, y: 5 },
  479.                     { x: 3, y: 7 },
  480.                     { x: 7, y: 3 },
  481.                     { x: 8, y: 8 }
  482.                 ];
  483.  
  484.                 this.guardians = [];
  485.                 positions.forEach(pos => {
  486.                     const guardian = document.createElement('div');
  487.                     guardian.className = 'guardian';
  488.                     const node = this.nodes[pos.y][pos.x].element;
  489.                     const rect = node.getBoundingClientRect();
  490.                     const labRect = document.getElementById('labyrinth').getBoundingClientRect();
  491.                    
  492.                     guardian.style.left = `${rect.left - labRect.left + 7.5}px`;
  493.                     guardian.style.top = `${rect.top - labRect.top + 7.5}px`;
  494.                    
  495.                     document.getElementById('labyrinthWrapper').appendChild(guardian);
  496.                     this.guardians.push({ element: guardian, x: pos.x, y: pos.y });
  497.                 });
  498.             }
  499.  
  500.             createParticleEffects() {
  501.                 setInterval(() => {
  502.                     if (this.particles.length < 15) {
  503.                        const particle = document.createElement('div');
  504.                        particle.className = 'particle';
  505.                        const labyrinth = document.getElementById('labyrinthWrapper');
  506.                        
  507.                        particle.style.left = `${Math.random() * 550 + 20}px`;
  508.                        particle.style.top = `${550 + 20}px`;
  509.                        particle.style.setProperty('--drift-x', `${(Math.random() - 0.5) * 100}px`);
  510.                        
  511.                        labyrinth.appendChild(particle);
  512.                        this.particles.push(particle);
  513.  
  514.                        setTimeout(() => {
  515.                             particle.remove();
  516.                             this.particles = this.particles.filter(p => p !== particle);
  517.                         }, 4000);
  518.                     }
  519.                 }, 300);
  520.             }
  521.  
  522.             startCycles() {
  523.                 // Shift the maze periodically
  524.                 this.shiftTimer = setInterval(() => {
  525.                     this.shiftLattice();
  526.                     this.currentCycle++;
  527.                 }, this.cycleTime);
  528.  
  529.                 // Update cycle bar animation
  530.                 setInterval(() => {
  531.                     const progress = ((Date.now() % this.cycleTime) / this.cycleTime) * 100;
  532.                     document.getElementById('cycleBar').style.width = `${progress}%`;
  533.                 }, 50);
  534.             }
  535.  
  536.             shiftLattice() {
  537.                 const pattern = this.currentCycle % 5;
  538.                
  539.                 for (let y = 0; y < this.gridSize; y++) {
  540.                    for (let x = 0; x < this.gridSize; x++) {
  541.                        const node = this.nodes[y][x];
  542.                        const prevActive = node.active;
  543.                        
  544.                        // Skip start and end positions
  545.                        if ((x === this.startPos.x && y === this.startPos.y) ||
  546.                            (x === this.endPos.x && y === this.endPos.y)) {
  547.                            continue;
  548.                        }
  549.  
  550.                        switch(pattern) {
  551.                            case 0: // Horizontal wave
  552.                                node.active = Math.sin((x + this.currentCycle * 0.5)) > -0.3;
  553.                                 break;
  554.                             case 1: // Vertical wave
  555.                                 node.active = Math.sin((y + this.currentCycle * 0.5)) > -0.3;
  556.                                 break;
  557.                             case 2: // Spiral pattern
  558.                                 const dist = Math.sqrt(Math.pow(x - 5, 2) + Math.pow(y - 5, 2));
  559.                                 node.active = Math.sin(dist - this.currentCycle * 0.5) > -0.2;
  560.                                 break;
  561.                             case 3: // Checkerboard shift
  562.                                 node.active = ((x + y + this.currentCycle) % 3) !== 0;
  563.                                 break;
  564.                             case 4: // Random controlled chaos
  565.                                 if (Math.random() > 0.8) {
  566.                                     node.active = !node.active;
  567.                                 } else if (Math.random() > 0.6) {
  568.                                     node.active = true;
  569.                                 }
  570.                                 break;
  571.                         }
  572.  
  573.                         // Keep player's current position active
  574.                         if (x === this.playerPos.x && y === this.playerPos.y) {
  575.                            node.active = true;
  576.                         }
  577.  
  578.                         // Update visuals
  579.                         if (node.active !== prevActive) {
  580.                             if (node.active) {
  581.                                 node.element.classList.remove('blocked');
  582.                                 node.element.classList.add('active');
  583.                             } else {
  584.                                 node.element.classList.remove('active');
  585.                                 node.element.classList.add('blocked');
  586.                             }
  587.                         }
  588.                     }
  589.                 }
  590.  
  591.                 // Ensure path still exists
  592.                 this.ensurePathExists();
  593.                 this.updateGuardians();
  594.             }
  595.  
  596.             updateGuardians() {
  597.                 this.guardians.forEach(guardian => {
  598.                     const distance = Math.abs(guardian.x - this.playerPos.x) +
  599.                                    Math.abs(guardian.y - this.playerPos.y);
  600.                    
  601.                     if (distance < 3) {
  602.                        guardian.element.classList.add('visible');
  603.                        if (distance === 0) {
  604.                            this.collectCrystal();
  605.                            // Move guardian to new position
  606.                            guardian.x = Math.floor(Math.random() * this.gridSize);
  607.                            guardian.y = Math.floor(Math.random() * this.gridSize);
  608.                            const node = this.nodes[guardian.y][guardian.x].element;
  609.                            const rect = node.getBoundingClientRect();
  610.                            const labRect = document.getElementById('labyrinth').getBoundingClientRect();
  611.                            guardian.element.style.left = `${rect.left - labRect.left + 7.5}px`;
  612.                            guardian.element.style.top = `${rect.top - labRect.top + 7.5}px`;
  613.                        }
  614.                    } else {
  615.                        guardian.element.classList.remove('visible');
  616.                    }
  617.                });
  618.            }
  619.  
  620.            collectCrystal() {
  621.                this.score += 25;
  622.                document.getElementById('score').textContent = this.score;
  623.                this.showMessage("Memory Crystal +25!", 1500);
  624.            }
  625.  
  626.            setupControls() {
  627.                document.addEventListener('keydown', (e) => {
  628.                     let newX = this.playerPos.x;
  629.                     let newY = this.playerPos.y;
  630.  
  631.                     switch(e.key.toLowerCase()) {
  632.                         case 'arrowup':
  633.                         case 'w':
  634.                             newY--;
  635.                             break;
  636.                         case 'arrowdown':
  637.                         case 's':
  638.                             newY++;
  639.                             break;
  640.                         case 'arrowleft':
  641.                         case 'a':
  642.                             newX--;
  643.                             break;
  644.                         case 'arrowright':
  645.                         case 'd':
  646.                             newX++;
  647.                             break;
  648.                         default:
  649.                             return;
  650.                     }
  651.  
  652.                     e.preventDefault();
  653.  
  654.                     // Check bounds and if node is active
  655.                     if (newX >= 0 && newX < this.gridSize &&
  656.                        newY >= 0 && newY < this.gridSize &&
  657.                        this.nodes[newY][newX].active) {
  658.                        
  659.                        this.playerPos.x = newX;
  660.                         this.playerPos.y = newY;
  661.                         this.moves++;
  662.                         document.getElementById('moves').textContent = this.moves;
  663.                         this.updatePlayerPosition();
  664.  
  665.                         // Check win condition
  666.                         if (newX === this.endPos.x && newY === this.endPos.y) {
  667.                            this.completeRound();
  668.                         }
  669.                     } else {
  670.                         this.showMessage("Path blocked!", 800);
  671.                     }
  672.                 });
  673.             }
  674.  
  675.             updatePlayerPosition() {
  676.                 const player = document.getElementById('player');
  677.                 const node = this.nodes[this.playerPos.y][this.playerPos.x].element;
  678.                 const rect = node.getBoundingClientRect();
  679.                 const wrapperRect = document.getElementById('labyrinthWrapper').getBoundingClientRect();
  680.                
  681.                 player.style.left = `${rect.left - wrapperRect.left + 10}px`;
  682.                 player.style.top = `${rect.top - wrapperRect.top + 10}px`;
  683.             }
  684.  
  685.             showMessage(text, duration) {
  686.                 const msg = document.getElementById('message');
  687.                 msg.textContent = text;
  688.                 msg.classList.add('show');
  689.                 setTimeout(() => {
  690.                     msg.classList.remove('show');
  691.                 }, duration);
  692.             }
  693.  
  694.             completeRound() {
  695.                 this.score += 100;
  696.                 this.round++;
  697.                 document.getElementById('score').textContent = this.score;
  698.                 document.getElementById('round').textContent = this.round;
  699.                
  700.                 this.showMessage(`ROUND ${this.round - 1} COMPLETE! +100`, 2500);
  701.                
  702.                 setTimeout(() => {
  703.                     // Reset for next round
  704.                     this.playerPos = { x: 0, y: 0 };
  705.                     this.moves = 0;
  706.                     document.getElementById('moves').textContent = this.moves;
  707.                     this.currentCycle = 0;
  708.                    
  709.                     // Make maze progressively harder
  710.                     this.cycleTime = Math.max(2000, this.cycleTime - 200);
  711.                    
  712.                     // Regenerate maze
  713.                     this.createLattice();
  714.                     this.updatePlayerPosition();
  715.                     this.updateGuardians();
  716.                    
  717.                     this.showMessage(`ROUND ${this.round} - BEGIN!`, 2000);
  718.                 }, 2600);
  719.             }
  720.         }
  721.  
  722.         // Initialize the game
  723.         const game = new LatticeLabyrinth();
  724.  
  725.         // Handle window resize
  726.         window.addEventListener('resize', () => {
  727.             game.updatePlayerPosition();
  728.         });
  729.     </script>
  730. </body>
  731. </html>
  732.  
Advertisement
Add Comment
Please, Sign In to add comment