/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var CoreOrb = Container.expand(function () { var self = Container.call(this); var orbGlow = self.attachAsset('orbGlow', { anchorX: 0.5, anchorY: 0.5, alpha: 0.2 }); var orb = self.attachAsset('coreOrb', { anchorX: 0.5, anchorY: 0.5, alpha: 0.8 }); self.initialize = function (roomNumber, index) { var seed = roomNumber * 89 + index * 47; // Random position self.x = seed % 1000 / 1000 * 1800 + 124; self.y = seed * 3 % 1000 / 1000 * 2400 + 166; // Random colors var colorIndex = (seed + index * 29) % sciFiColors.length; orb.tint = sciFiColors[colorIndex]; orbGlow.tint = sciFiColors[(colorIndex + 2) % sciFiColors.length]; // Start pulsing animation self.startPulsing(); }; self.startPulsing = function () { var pulseDuration = 1500 + Math.random() * 1000; var targetScale = 0.7 + Math.random() * 0.6; var targetGlowScale = 0.8 + Math.random() * 0.8; tween(orb, { scaleX: targetScale, scaleY: targetScale, alpha: 0.6 + Math.random() * 0.3 }, { duration: pulseDuration, easing: tween.easeInOut, onFinish: function onFinish() { self.startPulsing(); } }); tween(orbGlow, { scaleX: targetGlowScale, scaleY: targetGlowScale, alpha: 0.1 + Math.random() * 0.2, rotation: orbGlow.rotation + Math.PI }, { duration: pulseDuration * 1.2, easing: tween.easeInOut }); }; return self; }); var DangerTimer = Container.expand(function () { var self = Container.call(this); self.timerText = new Text2('10', { size: 200, fill: 0xff4757 }); self.timerText.anchor.set(0.5, 0.5); self.addChild(self.timerText); self.warningText = new Text2('DANGER - HIDE IN LOCKER!', { size: 80, fill: 0xff3742 }); self.warningText.anchor.set(0.5, 0.5); self.warningText.y = -150; self.addChild(self.warningText); self.timeLeft = 10; self.isActive = false; self.countdown = null; self.startTimer = function () { self.isActive = true; // Much shorter warning timers further into the game var baseTime = Math.max(2, 8 - Math.floor(currentRoom / 5)); // Even shorter in very late rooms if (currentRoom > 50) { baseTime = Math.max(1, 3 - Math.floor((currentRoom - 50) / 10)); } // Add randomness to make it unpredictable (±1 second) self.timeLeft = baseTime + Math.floor(Math.random() * 3) - 1; self.timerText.setText(self.timeLeft.toString()); // Start warning text pulse self.startWarningPulse(); // Start countdown self.countdown = LK.setInterval(function () { self.timeLeft--; self.timerText.setText(self.timeLeft.toString()); // Change color as time runs out if (self.timeLeft <= 3) { self.timerText.tint = 0xff0000; self.warningText.tint = 0xff0000; } else if (self.timeLeft <= 5) { self.timerText.tint = 0xff6b35; self.warningText.tint = 0xff6b35; } // Timer reached zero if (self.timeLeft <= 0) { self.onTimerComplete(); } }, 1000); }; self.startWarningPulse = function () { if (self.isActive) { // More intense pulsing based on time left and room difficulty var intensity = 1.1 + (self.timeLeft <= 3 ? 0.3 : 0.1); var speed = self.timeLeft <= 3 ? 200 : self.timeLeft <= 5 ? 350 : 500; // Add screen shake for urgency in harder rooms if (self.timeLeft <= 2 && currentRoom > 10) { var shakeAmount = 5; tween(game, { x: game.x + shakeAmount, y: game.y + shakeAmount }, { duration: 50, onFinish: function onFinish() { tween(game, { x: game.x - shakeAmount, y: game.y - shakeAmount }, { duration: 50 }); } }); } tween(self.warningText, { scaleX: intensity, scaleY: intensity, alpha: 0.7 }, { duration: speed, easing: tween.easeInOut, onFinish: function onFinish() { tween(self.warningText, { scaleX: 1, scaleY: 1, alpha: 1 }, { duration: speed, easing: tween.easeInOut, onFinish: function onFinish() { self.startWarningPulse(); } }); } }); } }; self.onTimerComplete = function () { self.stopTimer(); // Check if player is hidden if (isPlayerHidden) { // Harder rooms have multiple phases if (!self.phaseCount) self.phaseCount = 0; self.phaseCount++; var maxPhases = Math.min(3, 1 + Math.floor(currentRoom / 8)); // More phases in later rooms if (self.phaseCount < maxPhases) { // Show false success and restart with shorter timer self.showFalseSuccess(); } else { // Actually completed all phases self.showSuccess(); } } else { // Player failed to hide - game over LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); } }; self.showFalseSuccess = function () { self.timerText.setText('WAIT...'); self.timerText.tint = 0xffa500; self.warningText.setText('Something is coming back!'); self.warningText.tint = 0xff6b35; // Flash screen orange to indicate false alarm LK.effects.flashScreen(0xffa500, 500); // Restart timer after short delay with reduced time LK.setTimeout(function () { if (self.phaseCount >= 2) { self.warningText.setText('MULTIPLE ENTITIES DETECTED!'); self.timerText.tint = 0xff0000; self.warningText.tint = 0xff0000; } self.startTimer(); }, 1000); }; self.showSuccess = function () { self.timerText.setText('SAFE!'); self.timerText.tint = 0x00d2d3; self.warningText.setText('All entities passed - you may continue'); self.warningText.tint = 0x00d2d3; // Stop warning pulse tween.stop(self.warningText); self.warningText.scaleX = 1; self.warningText.scaleY = 1; self.warningText.alpha = 1; // Set hasKeycard to true to allow progression hasKeycard = true; // Start green exit timer isExitWindowActive = true; var exitTimeLeft = 5 + Math.floor(currentRoom / 10); // 5-8 seconds based on room exitTimer = LK.setInterval(function () { exitTimeLeft--; if (self.timerText) { self.timerText.setText(exitTimeLeft.toString()); self.timerText.tint = 0x00ff00; // Green color } if (self.warningText) { self.warningText.setText('EXIT NOW - ' + exitTimeLeft + ' seconds left!'); self.warningText.tint = 0x00ff00; } if (exitTimeLeft <= 0) { // Exit window expired - entity returns LK.clearInterval(exitTimer); exitTimer = null; isExitWindowActive = false; hasKeycard = false; if (self.timerText) { self.timerText.setText('TOO LATE!'); self.timerText.tint = 0xff0000; } if (self.warningText) { self.warningText.setText('ENTITY RETURNED! HIDE AGAIN!'); self.warningText.tint = 0xff0000; } LK.effects.flashScreen(0xff6600, 500); // Restart the danger sequence LK.setTimeout(function () { self.startTimer(); }, 1000); } }, 1000); // Show forward button after short delay LK.setTimeout(function () { if (forwardButton) { forwardButton.visible = true; tween(forwardButton, { alpha: 1 }, { duration: 500, easing: tween.easeIn }); } // Hide locker after danger room completion if (currentLocker) { currentLocker.visible = false; } }, 1500); }; self.stopTimer = function () { self.isActive = false; if (self.countdown) { LK.clearInterval(self.countdown); self.countdown = null; } }; return self; }); var EnergyGrid = Container.expand(function () { var self = Container.call(this); self.gridLines = []; self.createGrid = function (roomNumber) { // Clear existing grid lines for (var i = 0; i < self.gridLines.length; i++) { self.gridLines[i].destroy(); } self.gridLines = []; var seed = roomNumber * 61; // Create horizontal grid lines var numHorizontal = 6 + roomNumber % 4; for (var i = 0; i < numHorizontal; i++) { var line = self.attachAsset('gridLine', { anchorX: 0.5, anchorY: 0.5, alpha: 0.1 + Math.random() * 0.2 }); line.x = 1024; line.y = (seed + i * 97) % 1000 / 1000 * 2732; line.scaleX = 0.3 + Math.random() * 0.7; var colorIndex = (seed + i * 53) % sciFiColors.length; line.tint = sciFiColors[colorIndex]; self.gridLines.push(line); self.animateGridLine(line, i, true); } // Create vertical grid lines var numVertical = 4 + roomNumber % 3; for (var i = 0; i < numVertical; i++) { var line = self.attachAsset('verticalGridLine', { anchorX: 0.5, anchorY: 0.5, alpha: 0.08 + Math.random() * 0.15 }); line.x = (seed + i * 113) % 1000 / 1000 * 2048; line.y = 1366; line.scaleY = 0.4 + Math.random() * 0.6; var colorIndex = (seed + i * 71) % sciFiColors.length; line.tint = sciFiColors[colorIndex]; self.gridLines.push(line); self.animateGridLine(line, i, false); } }; self.animateGridLine = function (line, index, isHorizontal) { var duration = 5000 + index * 300; var targetAlpha = 0.05 + Math.random() * 0.25; var targetScale = 0.2 + Math.random() * 0.8; var tweenProps = { alpha: targetAlpha }; if (isHorizontal) { tweenProps.scaleX = targetScale; } else { tweenProps.scaleY = targetScale; } tween(line, tweenProps, { duration: duration, easing: tween.easeInOut, onFinish: function onFinish() { self.animateGridLine(line, index, isHorizontal); } }); }; return self; }); var ForwardButton = Container.expand(function () { var self = Container.call(this); var buttonBackground = self.attachAsset('forwardArrow', { anchorX: 0.5, anchorY: 0.5 }); var arrow = self.attachAsset('arrowTriangle', { anchorX: 0.5, anchorY: 0.5, rotation: Math.PI / 2 }); self.down = function (x, y, obj) { tween(self, { scaleX: 0.95, scaleY: 0.95 }, { duration: 100 }); // Add glow effect on press tween(buttonBackground, { tint: 0x74b9ff }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(buttonBackground, { tint: 0x4a90e2 }, { duration: 300, easing: tween.easeIn }); } }); LK.getSound('roomAdvance').play(); advanceRoom(); }; self.up = function (x, y, obj) { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 100 }); }; return self; }); var GlowEffect = Container.expand(function () { var self = Container.call(this); self.glows = []; self.createGlows = function (roomNumber) { // Clear existing glows for (var i = 0; i < self.glows.length; i++) { self.glows[i].destroy(); } self.glows = []; var seed = roomNumber * 41; var numGlows = 3 + roomNumber % 4; for (var i = 0; i < numGlows; i++) { var glow = self.attachAsset('glow', { anchorX: 0.5, anchorY: 0.5, alpha: 0.1 + Math.random() * 0.15 }); // Position glows glow.x = (seed + i * 137) % 1000 / 1000 * 2048; glow.y = (seed + i * 193) % 1000 / 1000 * 2732; // Color variation var colorIndex = (seed + i * 67) % sciFiColors.length; glow.tint = sciFiColors[colorIndex]; // Random scale var scale = 0.3 + Math.random() * 0.7; glow.scaleX = scale; glow.scaleY = scale; self.glows.push(glow); self.animateGlow(glow, i); } }; self.animateGlow = function (glow, index) { var duration = 4000 + index * 500; var targetScale = 0.2 + Math.random() * 0.8; var targetAlpha = 0.05 + Math.random() * 0.2; tween(glow, { scaleX: targetScale, scaleY: targetScale, alpha: targetAlpha, rotation: glow.rotation + Math.PI }, { duration: duration, easing: tween.easeInOut, onFinish: function onFinish() { self.animateGlow(glow, index); } }); }; return self; }); var HolographicOverlay = Container.expand(function () { var self = Container.call(this); self.holoElements = []; self.createHoloElements = function (roomNumber) { // Clear existing holo elements for (var i = 0; i < self.holoElements.length; i++) { self.holoElements[i].destroy(); } self.holoElements = []; var seed = roomNumber * 73; var numElements = 6 + roomNumber % 8; for (var i = 0; i < numElements; i++) { var elementType = (seed + i * 29) % 3; var element; switch (elementType) { case 0: element = self.attachAsset('sciFiCircle', { anchorX: 0.5, anchorY: 0.5, alpha: 0.15 + Math.random() * 0.25 }); break; case 1: element = self.attachAsset('sciFiSmallCircle', { anchorX: 0.5, anchorY: 0.5, alpha: 0.2 + Math.random() * 0.3 }); break; case 2: element = self.attachAsset('sciFiRect', { anchorX: 0.5, anchorY: 0.5, alpha: 0.1 + Math.random() * 0.2 }); break; } // Position elements element.x = (seed + i * 179) % 1000 / 1000 * 2048; element.y = (seed + i * 233) % 1000 / 1000 * 2732; // Holographic cyan/blue tints var holoColors = [0x00ffff, 0x0080ff, 0x40e0d0, 0x7fffd4, 0x00bfff]; var colorIndex = (seed + i * 61) % holoColors.length; element.tint = holoColors[colorIndex]; // Random scale and rotation var scale = 0.4 + Math.random() * 0.8; element.scaleX = scale; element.scaleY = scale; element.rotation = (seed + i * 97) % 360 * Math.PI / 180; self.holoElements.push(element); self.animateHoloElement(element, i); } }; self.animateHoloElement = function (element, index) { var duration = 4000 + index * 400; var targetAlpha = 0.05 + Math.random() * 0.3; var targetScale = 0.2 + Math.random() * 1.0; var targetRotation = element.rotation + Math.PI * 1.5; // Add glitch effect occasionally if (Math.random() < 0.3) { var glitchDuration = 50 + Math.random() * 100; tween(element, { alpha: 0.8, scaleX: element.scaleX * 1.2, scaleY: element.scaleY * 0.8 }, { duration: glitchDuration, easing: tween.easeInOut, onFinish: function onFinish() { tween(element, { alpha: targetAlpha, scaleX: targetScale, scaleY: targetScale, rotation: targetRotation }, { duration: duration - glitchDuration, easing: tween.easeInOut, onFinish: function onFinish() { self.animateHoloElement(element, index); } }); } }); } else { tween(element, { alpha: targetAlpha, scaleX: targetScale, scaleY: targetScale, rotation: targetRotation }, { duration: duration, easing: tween.easeInOut, onFinish: function onFinish() { self.animateHoloElement(element, index); } }); } }; return self; }); var Keycard = Container.expand(function () { var self = Container.call(this); var cardBackground = self.attachAsset('sciFiRect', { anchorX: 0.5, anchorY: 0.5, alpha: 0.9 }); var cardGlow = self.attachAsset('glow', { anchorX: 0.5, anchorY: 0.5, alpha: 0.3, scaleX: 0.5, scaleY: 0.5 }); self.isCollected = false; self.initialize = function (roomNumber) { // Randomize keycard position based on room number var seed = roomNumber * 127; self.x = seed % 1000 / 1000 * 1600 + 224; // Random X between 224-1824 self.y = seed * 3 % 1000 / 1000 * 2000 + 366; // Random Y between 366-2366 // Keycard specific colors (golden/yellow for importance) cardBackground.tint = 0xffd700; cardGlow.tint = 0xffff00; cardBackground.scaleX = 0.6; cardBackground.scaleY = 1.2; // Start floating animation self.startFloating(); }; self.startFloating = function () { var floatDuration = 2000 + Math.random() * 1000; var targetY = self.y + (Math.random() - 0.5) * 40; var targetScale = 0.9 + Math.random() * 0.2; tween(self, { y: targetY, scaleX: targetScale, scaleY: targetScale, rotation: self.rotation + Math.PI * 0.1 }, { duration: floatDuration, easing: tween.easeInOut, onFinish: function onFinish() { if (!self.isCollected) { self.startFloating(); } } }); tween(cardGlow, { alpha: 0.1 + Math.random() * 0.4, scaleX: 0.3 + Math.random() * 0.4, scaleY: 0.3 + Math.random() * 0.4 }, { duration: floatDuration * 0.8, easing: tween.easeInOut }); }; self.down = function (x, y, obj) { if (!self.isCollected) { self.collect(); } }; self.collect = function () { self.isCollected = true; LK.getSound('roomAdvance').play(); // Collection animation tween(self, { scaleX: 1.5, scaleY: 1.5, alpha: 0, y: self.y - 100 }, { duration: 800, easing: tween.easeOut, onFinish: function onFinish() { self.destroy(); hasKeycard = true; // Show the forward button after keycard collection if (forwardButton) { forwardButton.visible = true; tween(forwardButton, { alpha: 1 }, { duration: 500, easing: tween.easeIn }); } } }); tween(cardGlow, { scaleX: 2, scaleY: 2, alpha: 0 }, { duration: 800, easing: tween.easeOut }); }; return self; }); var Locker = Container.expand(function () { var self = Container.call(this); var lockerBackground = self.attachAsset('sciFiLargeRect', { anchorX: 0.5, anchorY: 0.5, alpha: 0.8 }); var lockerGlow = self.attachAsset('glow', { anchorX: 0.5, anchorY: 0.5, alpha: 0.2, scaleX: 0.3, scaleY: 0.5 }); self.isPlayerHidden = false; self.initialize = function (roomNumber) { // Position locker on the side of screen self.x = 1700; self.y = 1366; // Locker colors (metallic blue/gray) lockerBackground.tint = 0x2c3e50; lockerGlow.tint = 0x3498db; lockerBackground.scaleX = 0.8; lockerBackground.scaleY = 2.5; // Start subtle glow animation self.startGlow(); }; self.startGlow = function () { var glowDuration = 2000 + Math.random() * 1000; tween(lockerGlow, { alpha: 0.1 + Math.random() * 0.3, scaleX: 0.2 + Math.random() * 0.2, scaleY: 0.4 + Math.random() * 0.3 }, { duration: glowDuration, easing: tween.easeInOut, onFinish: function onFinish() { self.startGlow(); } }); }; self.down = function (x, y, obj) { if (!self.isPlayerHidden) { self.hidePlayer(); } else { self.showPlayer(); } }; self.hidePlayer = function () { self.isPlayerHidden = true; isPlayerHidden = true; // Start anxiety buildup anxietyLevel = 0; // Show anxiety meter anxietyMeter.visible = true; anxietyTimer = LK.setInterval(function () { anxietyLevel += 1; // Update anxiety meter display anxietyMeter.setText('Anxiety: ' + anxietyLevel + '/' + maxAnxiety); // Change color based on anxiety level if (anxietyLevel >= 80) { anxietyMeter.tint = 0xff0000; // Red } else if (anxietyLevel >= 50) { anxietyMeter.tint = 0xff6600; // Orange } else if (anxietyLevel >= 25) { anxietyMeter.tint = 0xffff00; // Yellow } else { anxietyMeter.tint = 0x00ff00; // Green } if (anxietyLevel >= maxAnxiety) { // Player loses due to max anxiety LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); } // Visual anxiety effects - screen gets redder as anxiety increases var anxietyRatio = anxietyLevel / maxAnxiety; var redTint = Math.floor(255 * anxietyRatio); LK.effects.flashScreen(redTint << 16, 100); }, 200); // Increase anxiety every 200ms // Visual feedback for hiding tween(lockerBackground, { tint: 0x27ae60, scaleX: 0.9 }, { duration: 300, easing: tween.easeOut }); tween(lockerGlow, { alpha: 0.5, tint: 0x2ecc71 }, { duration: 300, easing: tween.easeOut }); }; self.showPlayer = function () { // Stop anxiety buildup if (anxietyTimer) { LK.clearInterval(anxietyTimer); anxietyTimer = null; } anxietyLevel = 0; // Hide anxiety meter anxietyMeter.visible = false; // Check if coming out too early during active danger timer OR not during exit window if (currentDangerTimer && currentDangerTimer.isActive && currentDangerTimer.timeLeft > 1) { // Penalty for early exit - flash red and restart timer LK.effects.flashScreen(0xff0000, 300); if (currentDangerTimer.phaseCount > 0) { // Extra harsh penalty in later phases currentDangerTimer.timeLeft = Math.max(2, currentDangerTimer.timeLeft - 2); currentDangerTimer.timerText.setText(currentDangerTimer.timeLeft.toString()); currentDangerTimer.warningText.setText('TOO EARLY! ENTITY NOTICED YOU!'); currentDangerTimer.warningText.tint = 0xff0000; } } else if (!isExitWindowActive && hasKeycard) { // Coming out when not in safe exit window - restart danger sequence LK.effects.flashScreen(0xff6600, 300); if (currentDangerTimer) { currentDangerTimer.warningText.setText('ENTITY RETURNED! HIDE AGAIN!'); currentDangerTimer.warningText.tint = 0xff6600; hasKeycard = false; currentDangerTimer.startTimer(); } } self.isPlayerHidden = false; isPlayerHidden = false; // Visual feedback for coming out tween(lockerBackground, { tint: 0x2c3e50, scaleX: 0.8 }, { duration: 300, easing: tween.easeOut }); tween(lockerGlow, { alpha: 0.2, tint: 0x3498db }, { duration: 300, easing: tween.easeOut }); }; return self; }); var NeonCircuit = Container.expand(function () { var self = Container.call(this); self.circuits = []; self.createCircuits = function (roomNumber) { // Clear existing circuits for (var i = 0; i < self.circuits.length; i++) { self.circuits[i].destroy(); } self.circuits = []; var seed = roomNumber * 31; var numCircuits = 4 + roomNumber % 6; for (var i = 0; i < numCircuits; i++) { var circuit = self.attachAsset('sciFiSmallRect', { anchorX: 0.5, anchorY: 0.5, alpha: 0.4 + Math.random() * 0.5 }); // Position circuits circuit.x = (seed + i * 157) % 1000 / 1000 * 1800 + 124; circuit.y = (seed + i * 211) % 1000 / 1000 * 2400 + 166; // Random rotation and scale circuit.rotation = (seed + i * 83) % 360 * Math.PI / 180; var scale = 0.5 + Math.random() * 1.0; circuit.scaleX = scale; circuit.scaleY = scale * 0.3; // Make them thinner like circuit traces // Bright neon colors var neonColors = [0x00ff41, 0xff073a, 0x39ff14, 0xff6600, 0x00ffff, 0xff00ff]; var colorIndex = (seed + i * 47) % neonColors.length; circuit.tint = neonColors[colorIndex]; self.circuits.push(circuit); self.animateCircuit(circuit, i); } }; self.animateCircuit = function (circuit, index) { var duration = 2000 + index * 300; var targetAlpha = 0.2 + Math.random() * 0.7; var pulseScale = 0.3 + Math.random() * 1.2; tween(circuit, { alpha: targetAlpha, scaleX: pulseScale, scaleY: pulseScale * 0.3, rotation: circuit.rotation + Math.PI * 0.25 }, { duration: duration, easing: tween.easeInOut, onFinish: function onFinish() { self.animateCircuit(circuit, index); } }); }; return self; }); var ParticleSystem = Container.expand(function () { var self = Container.call(this); self.particles = []; self.createParticles = function (count, roomNumber) { // Clear existing particles for (var i = 0; i < self.particles.length; i++) { self.particles[i].destroy(); } self.particles = []; var seed = roomNumber * 23; for (var i = 0; i < count; i++) { var particle = self.attachAsset('particle', { anchorX: 0.5, anchorY: 0.5, alpha: 0.6 + Math.random() * 0.4 }); // Random position particle.x = Math.random() * 2048; particle.y = Math.random() * 2732; // Random color from sci-fi palette var colorIndex = (seed + i * 31) % sciFiColors.length; particle.tint = sciFiColors[colorIndex]; // Random scale var scale = 0.5 + Math.random() * 1.5; particle.scaleX = scale; particle.scaleY = scale; self.particles.push(particle); self.animateParticle(particle, i); } }; self.animateParticle = function (particle, index) { var duration = 2000 + Math.random() * 3000; var targetX = Math.random() * 2048; var targetY = Math.random() * 2732; var targetAlpha = 0.2 + Math.random() * 0.6; tween(particle, { x: targetX, y: targetY, alpha: targetAlpha, rotation: particle.rotation + Math.PI * 2 }, { duration: duration, easing: tween.easeInOut, onFinish: function onFinish() { self.animateParticle(particle, index); } }); }; return self; }); var RoomDisplay = Container.expand(function () { var self = Container.call(this); var background = self.attachAsset('roomBackground', { anchorX: 0.5, anchorY: 0.5 }); self.updateRoom = function (roomNumber) { // Simple visual feedback for room change tween(self, { alpha: 0.7 }, { duration: 150, onFinish: function onFinish() { tween(self, { alpha: 1 }, { duration: 150 }); } }); }; return self; }); var SciFiBackground = Container.expand(function () { var self = Container.call(this); self.shapes = []; self.createBackground = function (roomNumber) { // Clear existing shapes for (var i = 0; i < self.shapes.length; i++) { self.shapes[i].destroy(); } self.shapes = []; // Create multiple geometric shapes based on room number var seed = roomNumber * 17; // Deterministic but varied var numShapes = 8 + roomNumber % 6; for (var i = 0; i < numShapes; i++) { var shapeType = (seed + i) % 5; var shape; switch (shapeType) { case 0: shape = self.attachAsset('sciFiCircle', { anchorX: 0.5, anchorY: 0.5, alpha: 0.3 + Math.random() * 0.4 }); break; case 1: shape = self.attachAsset('sciFiSmallCircle', { anchorX: 0.5, anchorY: 0.5, alpha: 0.2 + Math.random() * 0.3 }); break; case 2: shape = self.attachAsset('sciFiRect', { anchorX: 0.5, anchorY: 0.5, alpha: 0.25 + Math.random() * 0.35 }); break; case 3: shape = self.attachAsset('sciFiSmallRect', { anchorX: 0.5, anchorY: 0.5, alpha: 0.3 + Math.random() * 0.4 }); break; case 4: shape = self.attachAsset('sciFiLargeRect', { anchorX: 0.5, anchorY: 0.5, alpha: 0.2 + Math.random() * 0.3 }); break; } // Position shapes randomly but deterministically var posX = (seed + i * 73) % 1000 / 1000 * 1800 + 124; var posY = (seed + i * 127) % 1000 / 1000 * 2400 + 166; shape.x = posX; shape.y = posY; shape.rotation = (seed + i * 91) % 360 * Math.PI / 180; // Color variation var colorIndex = (seed + i * 43) % sciFiColors.length; shape.tint = sciFiColors[colorIndex]; self.shapes.push(shape); // Animate shapes self.animateShape(shape, i); } }; self.animateShape = function (shape, index) { var duration = 3000 + index * 200; var scale = 0.8 + Math.random() * 0.4; var targetX = shape.x + (Math.random() - 0.5) * 200; var targetY = shape.y + (Math.random() - 0.5) * 200; // Keep shapes within bounds targetX = Math.max(100, Math.min(1948, targetX)); targetY = Math.max(100, Math.min(2632, targetY)); tween(shape, { scaleX: scale, scaleY: scale, rotation: shape.rotation + Math.PI * 2, x: targetX, y: targetY, alpha: 0.2 + Math.random() * 0.4 }, { duration: duration, easing: tween.easeInOut, onFinish: function onFinish() { self.animateShape(shape, index); } }); }; return self; }); var StarField = Container.expand(function () { var self = Container.call(this); self.stars = []; self.createStars = function (roomNumber) { // Clear existing stars for (var i = 0; i < self.stars.length; i++) { self.stars[i].destroy(); } self.stars = []; var seed = roomNumber * 11; var numStars = 20 + roomNumber % 15; for (var i = 0; i < numStars; i++) { var star = self.attachAsset('particle', { anchorX: 0.5, anchorY: 0.5, alpha: 0.3 + Math.random() * 0.7 }); // Random position star.x = Math.random() * 2048; star.y = Math.random() * 2732; // Vary star sizes var scale = 0.3 + Math.random() * 1.2; star.scaleX = scale; star.scaleY = scale; // Bright white stars with occasional color tints if (Math.random() < 0.8) { star.tint = 0xffffff; } else { var colorIndex = (seed + i * 19) % sciFiColors.length; star.tint = sciFiColors[colorIndex]; } self.stars.push(star); self.animateStar(star, i); } }; self.animateStar = function (star, index) { var duration = 3000 + Math.random() * 4000; var targetAlpha = 0.1 + Math.random() * 0.8; var targetScale = 0.2 + Math.random() * 1.5; tween(star, { alpha: targetAlpha, scaleX: targetScale, scaleY: targetScale, rotation: star.rotation + Math.PI * 0.5 }, { duration: duration, easing: tween.easeInOut, onFinish: function onFinish() { self.animateStar(star, index); } }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x0a0a2e }); /**** * Game Code ****/ // Game state variables var currentRoom = storage.currentRoom || 1; // Reset to room 1 if currentRoom is 25 (game over condition) if (currentRoom === 25) { currentRoom = 1; storage.currentRoom = 1; } var maxRoom = 100; var isAdvancing = false; var hasKeycard = false; var currentKeycard = null; var isPlayerHidden = false; var currentLocker = null; var currentDangerTimer = null; var anxietyLevel = 0; var maxAnxiety = 100; var anxietyTimer = null; var exitTimer = null; var isExitWindowActive = false; // Room types: 0 = normal, 1 = keycard room, 2 = danger room var roomTypes = []; function generateRoomTypes() { roomTypes = []; for (var i = 1; i <= maxRoom; i++) { // Every 5th room starting from room 3 is a keycard room if (i > 2 && (i - 3) % 5 === 0) { roomTypes[i] = 1; // keycard room // Increase danger room frequency further into the game } else if (i > 3 && (i <= 20 && (i - 4) % 7 === 0 || i > 20 && i <= 50 && (i - 4) % 5 === 0 || i > 50 && (i - 4) % 3 === 0)) { roomTypes[i] = 2; // danger room } else { roomTypes[i] = 0; // normal room } } } function isKeycardRoom(roomNum) { return roomTypes[roomNum] === 1; } function isDangerRoom(roomNum) { return roomTypes[roomNum] === 2; } // Generate room types at start generateRoomTypes(); // Sci-fi color palette for procedural backgrounds var sciFiColors = [0x0a0a2e, 0x16213e, 0x0f3460, 0x533483, 0x7209b7, 0x2d1b69, 0x11998e, 0x38817a, 0x4a90e2, 0x6c5ce7, 0x74b9ff, 0x00b894, 0xa29bfe, 0xfd79a8, 0xfdcb6e, 0xe17055, 0x00cec9, 0x55a3ff, 0x5f27cd, 0x341f97]; // Function to get procedural background color based on room number function getSciFiBackgroundColor(roomNum) { // Use room number to create deterministic but varied color selection var baseIndex = (roomNum - 1) % sciFiColors.length; var variation = Math.floor((roomNum - 1) / sciFiColors.length) % 3; var colorIndex = (baseIndex + variation) % sciFiColors.length; return sciFiColors[colorIndex]; } // Create star field (deep background layer) var starField = game.addChild(new StarField()); starField.createStars(currentRoom); // Create energy grid (background layer) var energyGrid = game.addChild(new EnergyGrid()); energyGrid.createGrid(currentRoom); // Create glow effects (background layer) var glowEffect = game.addChild(new GlowEffect()); glowEffect.createGlows(currentRoom); // Create neon circuits (mid-background layer) var neonCircuit = game.addChild(new NeonCircuit()); neonCircuit.createCircuits(currentRoom); // Create sci-fi background var sciFiBackground = game.addChild(new SciFiBackground()); sciFiBackground.createBackground(currentRoom); // Create core orbs (mid layer) var coreOrbs = []; var numOrbs = 3 + currentRoom % 3; for (var i = 0; i < numOrbs; i++) { var orb = game.addChild(new CoreOrb()); orb.initialize(currentRoom, i); coreOrbs.push(orb); } // Create particle system (foreground layer) var particleSystem = game.addChild(new ParticleSystem()); particleSystem.createParticles(15 + currentRoom % 10, currentRoom); // Create holographic overlay (top layer) var holographicOverlay = game.addChild(new HolographicOverlay()); holographicOverlay.createHoloElements(currentRoom); // Create room display var roomDisplay = game.addChild(new RoomDisplay()); roomDisplay.x = 2048 / 2; roomDisplay.y = 2732 / 2 - 200; // Set initial sci-fi background color var initialBackgroundColor = getSciFiBackgroundColor(currentRoom); roomDisplay.children[0].tint = initialBackgroundColor; // Create forward button var forwardButton = game.addChild(new ForwardButton()); forwardButton.x = 2048 / 2; forwardButton.y = 2732 / 2 + 300; // Handle initial room setup if (isKeycardRoom(currentRoom)) { forwardButton.visible = false; forwardButton.alpha = 0; currentKeycard = game.addChild(new Keycard()); currentKeycard.initialize(currentRoom); hasKeycard = false; } else if (isDangerRoom(currentRoom)) { forwardButton.visible = false; forwardButton.alpha = 0; currentLocker = game.addChild(new Locker()); currentLocker.initialize(currentRoom); currentDangerTimer = game.addChild(new DangerTimer()); currentDangerTimer.x = 1024; currentDangerTimer.y = 400; currentDangerTimer.startTimer(); hasKeycard = false; } else { hasKeycard = true; // Normal rooms don't need keycards } // Create room counter text var roomTypeText = isKeycardRoom(currentRoom) ? ' (Keycard)' : isDangerRoom(currentRoom) ? ' (Danger)' : ''; var roomCounterText = new Text2('Room ' + currentRoom + '/' + maxRoom + roomTypeText, { size: 120, fill: 0x333333 }); roomCounterText.anchor.set(0.5, 0.5); roomCounterText.x = 2048 / 2; roomCounterText.y = 2732 / 2 - 100; game.addChild(roomCounterText); // Create title text var titleText = new Text2('Room Runner 100', { size: 80, fill: 0x666666 }); titleText.anchor.set(0.5, 0); LK.gui.top.addChild(titleText); titleText.y = 150; // Create anxiety meter var anxietyMeter = new Text2('Anxiety: 0/100', { size: 60, fill: 0x00ff00 }); anxietyMeter.anchor.set(0, 0); LK.gui.topLeft.addChild(anxietyMeter); anxietyMeter.x = 120; // Offset from left edge to avoid platform menu anxietyMeter.y = 50; anxietyMeter.visible = false; // Initially hidden // Function to advance to next room function advanceRoom() { if (currentRoom < maxRoom && !isAdvancing && hasKeycard) { isAdvancing = true; forwardButton.visible = false; // Hide button during transition // Clear any active timers if (anxietyTimer) { LK.clearInterval(anxietyTimer); anxietyTimer = null; } if (exitTimer) { LK.clearInterval(exitTimer); exitTimer = null; } anxietyLevel = 0; isExitWindowActive = false; // Hide anxiety meter when advancing rooms anxietyMeter.visible = false; // Clean up danger room objects if (currentLocker) { currentLocker.destroy(); currentLocker = null; } if (currentDangerTimer) { currentDangerTimer.destroy(); currentDangerTimer = null; } currentRoom++; storage.currentRoom = currentRoom; // Update room counter with room type var roomTypeText = isKeycardRoom(currentRoom) ? ' (Keycard)' : isDangerRoom(currentRoom) ? ' (Danger)' : ''; roomCounterText.setText('Room ' + currentRoom + '/' + maxRoom + roomTypeText); // Get new sci-fi background color var newBackgroundColor = getSciFiBackgroundColor(currentRoom); // Animate background color change tween(roomDisplay.children[0], { tint: newBackgroundColor }, { duration: 800, easing: tween.easeInOut }); // Update star field starField.createStars(currentRoom); // Update particle system particleSystem.createParticles(15 + currentRoom % 10, currentRoom); // Update energy grid energyGrid.createGrid(currentRoom); // Update glow effects glowEffect.createGlows(currentRoom); // Update neon circuits neonCircuit.createCircuits(currentRoom); // Update holographic overlay holographicOverlay.createHoloElements(currentRoom); // Update core orbs for (var i = 0; i < coreOrbs.length; i++) { coreOrbs[i].destroy(); } coreOrbs = []; var numOrbs = 3 + currentRoom % 3; for (var i = 0; i < numOrbs; i++) { var orb = game.addChild(new CoreOrb()); orb.initialize(currentRoom, i); coreOrbs.push(orb); } // Update sci-fi background with fade transition tween(sciFiBackground, { alpha: 0 }, { duration: 400, easing: tween.easeInOut, onFinish: function onFinish() { sciFiBackground.createBackground(currentRoom); tween(sciFiBackground, { alpha: 1 }, { duration: 400, easing: tween.easeInOut }); } }); // Update room display roomDisplay.updateRoom(currentRoom); // Add downtime before allowing next press LK.setTimeout(function () { isAdvancing = false; if (currentRoom < maxRoom) { // Check room type and setup accordingly if (isKeycardRoom(currentRoom)) { // Spawn keycard and hide button hasKeycard = false; currentKeycard = game.addChild(new Keycard()); currentKeycard.initialize(currentRoom); forwardButton.visible = false; forwardButton.alpha = 0; } else if (isDangerRoom(currentRoom)) { // Spawn locker and timer, hide button hasKeycard = false; isPlayerHidden = false; currentLocker = game.addChild(new Locker()); currentLocker.initialize(currentRoom); currentDangerTimer = game.addChild(new DangerTimer()); currentDangerTimer.x = 1024; currentDangerTimer.y = 400; currentDangerTimer.startTimer(); forwardButton.visible = false; forwardButton.alpha = 0; } else { // Normal room - show button immediately hasKeycard = true; forwardButton.visible = true; forwardButton.alpha = 1; } } }, 1200); // 1.2 second downtime // Check for completion if (currentRoom >= maxRoom) { LK.setTimeout(function () { // Reset game state before showing win storage.currentRoom = 1; currentRoom = 1; LK.showYouWin(); }, 500); } } } // Hide forward button if game is complete if (currentRoom >= maxRoom) { forwardButton.visible = false; roomCounterText.setText('Complete!'); // Auto-trigger win after short delay LK.setTimeout(function () { // Reset game state before showing win storage.currentRoom = 1; currentRoom = 1; LK.showYouWin(); }, 1000); } game.update = function () { // Simple idle animation for the forward button if (LK.ticks % 120 == 0 && currentRoom < maxRoom) { tween(forwardButton, { scaleX: 1.05, scaleY: 1.05 }, { duration: 300, easing: tween.easeInOut, onFinish: function onFinish() { tween(forwardButton, { scaleX: 1, scaleY: 1 }, { duration: 300, easing: tween.easeInOut }); } }); } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var CoreOrb = Container.expand(function () {
var self = Container.call(this);
var orbGlow = self.attachAsset('orbGlow', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.2
});
var orb = self.attachAsset('coreOrb', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.8
});
self.initialize = function (roomNumber, index) {
var seed = roomNumber * 89 + index * 47;
// Random position
self.x = seed % 1000 / 1000 * 1800 + 124;
self.y = seed * 3 % 1000 / 1000 * 2400 + 166;
// Random colors
var colorIndex = (seed + index * 29) % sciFiColors.length;
orb.tint = sciFiColors[colorIndex];
orbGlow.tint = sciFiColors[(colorIndex + 2) % sciFiColors.length];
// Start pulsing animation
self.startPulsing();
};
self.startPulsing = function () {
var pulseDuration = 1500 + Math.random() * 1000;
var targetScale = 0.7 + Math.random() * 0.6;
var targetGlowScale = 0.8 + Math.random() * 0.8;
tween(orb, {
scaleX: targetScale,
scaleY: targetScale,
alpha: 0.6 + Math.random() * 0.3
}, {
duration: pulseDuration,
easing: tween.easeInOut,
onFinish: function onFinish() {
self.startPulsing();
}
});
tween(orbGlow, {
scaleX: targetGlowScale,
scaleY: targetGlowScale,
alpha: 0.1 + Math.random() * 0.2,
rotation: orbGlow.rotation + Math.PI
}, {
duration: pulseDuration * 1.2,
easing: tween.easeInOut
});
};
return self;
});
var DangerTimer = Container.expand(function () {
var self = Container.call(this);
self.timerText = new Text2('10', {
size: 200,
fill: 0xff4757
});
self.timerText.anchor.set(0.5, 0.5);
self.addChild(self.timerText);
self.warningText = new Text2('DANGER - HIDE IN LOCKER!', {
size: 80,
fill: 0xff3742
});
self.warningText.anchor.set(0.5, 0.5);
self.warningText.y = -150;
self.addChild(self.warningText);
self.timeLeft = 10;
self.isActive = false;
self.countdown = null;
self.startTimer = function () {
self.isActive = true;
// Much shorter warning timers further into the game
var baseTime = Math.max(2, 8 - Math.floor(currentRoom / 5));
// Even shorter in very late rooms
if (currentRoom > 50) {
baseTime = Math.max(1, 3 - Math.floor((currentRoom - 50) / 10));
}
// Add randomness to make it unpredictable (±1 second)
self.timeLeft = baseTime + Math.floor(Math.random() * 3) - 1;
self.timerText.setText(self.timeLeft.toString());
// Start warning text pulse
self.startWarningPulse();
// Start countdown
self.countdown = LK.setInterval(function () {
self.timeLeft--;
self.timerText.setText(self.timeLeft.toString());
// Change color as time runs out
if (self.timeLeft <= 3) {
self.timerText.tint = 0xff0000;
self.warningText.tint = 0xff0000;
} else if (self.timeLeft <= 5) {
self.timerText.tint = 0xff6b35;
self.warningText.tint = 0xff6b35;
}
// Timer reached zero
if (self.timeLeft <= 0) {
self.onTimerComplete();
}
}, 1000);
};
self.startWarningPulse = function () {
if (self.isActive) {
// More intense pulsing based on time left and room difficulty
var intensity = 1.1 + (self.timeLeft <= 3 ? 0.3 : 0.1);
var speed = self.timeLeft <= 3 ? 200 : self.timeLeft <= 5 ? 350 : 500;
// Add screen shake for urgency in harder rooms
if (self.timeLeft <= 2 && currentRoom > 10) {
var shakeAmount = 5;
tween(game, {
x: game.x + shakeAmount,
y: game.y + shakeAmount
}, {
duration: 50,
onFinish: function onFinish() {
tween(game, {
x: game.x - shakeAmount,
y: game.y - shakeAmount
}, {
duration: 50
});
}
});
}
tween(self.warningText, {
scaleX: intensity,
scaleY: intensity,
alpha: 0.7
}, {
duration: speed,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(self.warningText, {
scaleX: 1,
scaleY: 1,
alpha: 1
}, {
duration: speed,
easing: tween.easeInOut,
onFinish: function onFinish() {
self.startWarningPulse();
}
});
}
});
}
};
self.onTimerComplete = function () {
self.stopTimer();
// Check if player is hidden
if (isPlayerHidden) {
// Harder rooms have multiple phases
if (!self.phaseCount) self.phaseCount = 0;
self.phaseCount++;
var maxPhases = Math.min(3, 1 + Math.floor(currentRoom / 8)); // More phases in later rooms
if (self.phaseCount < maxPhases) {
// Show false success and restart with shorter timer
self.showFalseSuccess();
} else {
// Actually completed all phases
self.showSuccess();
}
} else {
// Player failed to hide - game over
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
}
};
self.showFalseSuccess = function () {
self.timerText.setText('WAIT...');
self.timerText.tint = 0xffa500;
self.warningText.setText('Something is coming back!');
self.warningText.tint = 0xff6b35;
// Flash screen orange to indicate false alarm
LK.effects.flashScreen(0xffa500, 500);
// Restart timer after short delay with reduced time
LK.setTimeout(function () {
if (self.phaseCount >= 2) {
self.warningText.setText('MULTIPLE ENTITIES DETECTED!');
self.timerText.tint = 0xff0000;
self.warningText.tint = 0xff0000;
}
self.startTimer();
}, 1000);
};
self.showSuccess = function () {
self.timerText.setText('SAFE!');
self.timerText.tint = 0x00d2d3;
self.warningText.setText('All entities passed - you may continue');
self.warningText.tint = 0x00d2d3;
// Stop warning pulse
tween.stop(self.warningText);
self.warningText.scaleX = 1;
self.warningText.scaleY = 1;
self.warningText.alpha = 1;
// Set hasKeycard to true to allow progression
hasKeycard = true;
// Start green exit timer
isExitWindowActive = true;
var exitTimeLeft = 5 + Math.floor(currentRoom / 10); // 5-8 seconds based on room
exitTimer = LK.setInterval(function () {
exitTimeLeft--;
if (self.timerText) {
self.timerText.setText(exitTimeLeft.toString());
self.timerText.tint = 0x00ff00; // Green color
}
if (self.warningText) {
self.warningText.setText('EXIT NOW - ' + exitTimeLeft + ' seconds left!');
self.warningText.tint = 0x00ff00;
}
if (exitTimeLeft <= 0) {
// Exit window expired - entity returns
LK.clearInterval(exitTimer);
exitTimer = null;
isExitWindowActive = false;
hasKeycard = false;
if (self.timerText) {
self.timerText.setText('TOO LATE!');
self.timerText.tint = 0xff0000;
}
if (self.warningText) {
self.warningText.setText('ENTITY RETURNED! HIDE AGAIN!');
self.warningText.tint = 0xff0000;
}
LK.effects.flashScreen(0xff6600, 500);
// Restart the danger sequence
LK.setTimeout(function () {
self.startTimer();
}, 1000);
}
}, 1000);
// Show forward button after short delay
LK.setTimeout(function () {
if (forwardButton) {
forwardButton.visible = true;
tween(forwardButton, {
alpha: 1
}, {
duration: 500,
easing: tween.easeIn
});
}
// Hide locker after danger room completion
if (currentLocker) {
currentLocker.visible = false;
}
}, 1500);
};
self.stopTimer = function () {
self.isActive = false;
if (self.countdown) {
LK.clearInterval(self.countdown);
self.countdown = null;
}
};
return self;
});
var EnergyGrid = Container.expand(function () {
var self = Container.call(this);
self.gridLines = [];
self.createGrid = function (roomNumber) {
// Clear existing grid lines
for (var i = 0; i < self.gridLines.length; i++) {
self.gridLines[i].destroy();
}
self.gridLines = [];
var seed = roomNumber * 61;
// Create horizontal grid lines
var numHorizontal = 6 + roomNumber % 4;
for (var i = 0; i < numHorizontal; i++) {
var line = self.attachAsset('gridLine', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.1 + Math.random() * 0.2
});
line.x = 1024;
line.y = (seed + i * 97) % 1000 / 1000 * 2732;
line.scaleX = 0.3 + Math.random() * 0.7;
var colorIndex = (seed + i * 53) % sciFiColors.length;
line.tint = sciFiColors[colorIndex];
self.gridLines.push(line);
self.animateGridLine(line, i, true);
}
// Create vertical grid lines
var numVertical = 4 + roomNumber % 3;
for (var i = 0; i < numVertical; i++) {
var line = self.attachAsset('verticalGridLine', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.08 + Math.random() * 0.15
});
line.x = (seed + i * 113) % 1000 / 1000 * 2048;
line.y = 1366;
line.scaleY = 0.4 + Math.random() * 0.6;
var colorIndex = (seed + i * 71) % sciFiColors.length;
line.tint = sciFiColors[colorIndex];
self.gridLines.push(line);
self.animateGridLine(line, i, false);
}
};
self.animateGridLine = function (line, index, isHorizontal) {
var duration = 5000 + index * 300;
var targetAlpha = 0.05 + Math.random() * 0.25;
var targetScale = 0.2 + Math.random() * 0.8;
var tweenProps = {
alpha: targetAlpha
};
if (isHorizontal) {
tweenProps.scaleX = targetScale;
} else {
tweenProps.scaleY = targetScale;
}
tween(line, tweenProps, {
duration: duration,
easing: tween.easeInOut,
onFinish: function onFinish() {
self.animateGridLine(line, index, isHorizontal);
}
});
};
return self;
});
var ForwardButton = Container.expand(function () {
var self = Container.call(this);
var buttonBackground = self.attachAsset('forwardArrow', {
anchorX: 0.5,
anchorY: 0.5
});
var arrow = self.attachAsset('arrowTriangle', {
anchorX: 0.5,
anchorY: 0.5,
rotation: Math.PI / 2
});
self.down = function (x, y, obj) {
tween(self, {
scaleX: 0.95,
scaleY: 0.95
}, {
duration: 100
});
// Add glow effect on press
tween(buttonBackground, {
tint: 0x74b9ff
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(buttonBackground, {
tint: 0x4a90e2
}, {
duration: 300,
easing: tween.easeIn
});
}
});
LK.getSound('roomAdvance').play();
advanceRoom();
};
self.up = function (x, y, obj) {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
};
return self;
});
var GlowEffect = Container.expand(function () {
var self = Container.call(this);
self.glows = [];
self.createGlows = function (roomNumber) {
// Clear existing glows
for (var i = 0; i < self.glows.length; i++) {
self.glows[i].destroy();
}
self.glows = [];
var seed = roomNumber * 41;
var numGlows = 3 + roomNumber % 4;
for (var i = 0; i < numGlows; i++) {
var glow = self.attachAsset('glow', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.1 + Math.random() * 0.15
});
// Position glows
glow.x = (seed + i * 137) % 1000 / 1000 * 2048;
glow.y = (seed + i * 193) % 1000 / 1000 * 2732;
// Color variation
var colorIndex = (seed + i * 67) % sciFiColors.length;
glow.tint = sciFiColors[colorIndex];
// Random scale
var scale = 0.3 + Math.random() * 0.7;
glow.scaleX = scale;
glow.scaleY = scale;
self.glows.push(glow);
self.animateGlow(glow, i);
}
};
self.animateGlow = function (glow, index) {
var duration = 4000 + index * 500;
var targetScale = 0.2 + Math.random() * 0.8;
var targetAlpha = 0.05 + Math.random() * 0.2;
tween(glow, {
scaleX: targetScale,
scaleY: targetScale,
alpha: targetAlpha,
rotation: glow.rotation + Math.PI
}, {
duration: duration,
easing: tween.easeInOut,
onFinish: function onFinish() {
self.animateGlow(glow, index);
}
});
};
return self;
});
var HolographicOverlay = Container.expand(function () {
var self = Container.call(this);
self.holoElements = [];
self.createHoloElements = function (roomNumber) {
// Clear existing holo elements
for (var i = 0; i < self.holoElements.length; i++) {
self.holoElements[i].destroy();
}
self.holoElements = [];
var seed = roomNumber * 73;
var numElements = 6 + roomNumber % 8;
for (var i = 0; i < numElements; i++) {
var elementType = (seed + i * 29) % 3;
var element;
switch (elementType) {
case 0:
element = self.attachAsset('sciFiCircle', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.15 + Math.random() * 0.25
});
break;
case 1:
element = self.attachAsset('sciFiSmallCircle', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.2 + Math.random() * 0.3
});
break;
case 2:
element = self.attachAsset('sciFiRect', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.1 + Math.random() * 0.2
});
break;
}
// Position elements
element.x = (seed + i * 179) % 1000 / 1000 * 2048;
element.y = (seed + i * 233) % 1000 / 1000 * 2732;
// Holographic cyan/blue tints
var holoColors = [0x00ffff, 0x0080ff, 0x40e0d0, 0x7fffd4, 0x00bfff];
var colorIndex = (seed + i * 61) % holoColors.length;
element.tint = holoColors[colorIndex];
// Random scale and rotation
var scale = 0.4 + Math.random() * 0.8;
element.scaleX = scale;
element.scaleY = scale;
element.rotation = (seed + i * 97) % 360 * Math.PI / 180;
self.holoElements.push(element);
self.animateHoloElement(element, i);
}
};
self.animateHoloElement = function (element, index) {
var duration = 4000 + index * 400;
var targetAlpha = 0.05 + Math.random() * 0.3;
var targetScale = 0.2 + Math.random() * 1.0;
var targetRotation = element.rotation + Math.PI * 1.5;
// Add glitch effect occasionally
if (Math.random() < 0.3) {
var glitchDuration = 50 + Math.random() * 100;
tween(element, {
alpha: 0.8,
scaleX: element.scaleX * 1.2,
scaleY: element.scaleY * 0.8
}, {
duration: glitchDuration,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(element, {
alpha: targetAlpha,
scaleX: targetScale,
scaleY: targetScale,
rotation: targetRotation
}, {
duration: duration - glitchDuration,
easing: tween.easeInOut,
onFinish: function onFinish() {
self.animateHoloElement(element, index);
}
});
}
});
} else {
tween(element, {
alpha: targetAlpha,
scaleX: targetScale,
scaleY: targetScale,
rotation: targetRotation
}, {
duration: duration,
easing: tween.easeInOut,
onFinish: function onFinish() {
self.animateHoloElement(element, index);
}
});
}
};
return self;
});
var Keycard = Container.expand(function () {
var self = Container.call(this);
var cardBackground = self.attachAsset('sciFiRect', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.9
});
var cardGlow = self.attachAsset('glow', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3,
scaleX: 0.5,
scaleY: 0.5
});
self.isCollected = false;
self.initialize = function (roomNumber) {
// Randomize keycard position based on room number
var seed = roomNumber * 127;
self.x = seed % 1000 / 1000 * 1600 + 224; // Random X between 224-1824
self.y = seed * 3 % 1000 / 1000 * 2000 + 366; // Random Y between 366-2366
// Keycard specific colors (golden/yellow for importance)
cardBackground.tint = 0xffd700;
cardGlow.tint = 0xffff00;
cardBackground.scaleX = 0.6;
cardBackground.scaleY = 1.2;
// Start floating animation
self.startFloating();
};
self.startFloating = function () {
var floatDuration = 2000 + Math.random() * 1000;
var targetY = self.y + (Math.random() - 0.5) * 40;
var targetScale = 0.9 + Math.random() * 0.2;
tween(self, {
y: targetY,
scaleX: targetScale,
scaleY: targetScale,
rotation: self.rotation + Math.PI * 0.1
}, {
duration: floatDuration,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (!self.isCollected) {
self.startFloating();
}
}
});
tween(cardGlow, {
alpha: 0.1 + Math.random() * 0.4,
scaleX: 0.3 + Math.random() * 0.4,
scaleY: 0.3 + Math.random() * 0.4
}, {
duration: floatDuration * 0.8,
easing: tween.easeInOut
});
};
self.down = function (x, y, obj) {
if (!self.isCollected) {
self.collect();
}
};
self.collect = function () {
self.isCollected = true;
LK.getSound('roomAdvance').play();
// Collection animation
tween(self, {
scaleX: 1.5,
scaleY: 1.5,
alpha: 0,
y: self.y - 100
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
self.destroy();
hasKeycard = true;
// Show the forward button after keycard collection
if (forwardButton) {
forwardButton.visible = true;
tween(forwardButton, {
alpha: 1
}, {
duration: 500,
easing: tween.easeIn
});
}
}
});
tween(cardGlow, {
scaleX: 2,
scaleY: 2,
alpha: 0
}, {
duration: 800,
easing: tween.easeOut
});
};
return self;
});
var Locker = Container.expand(function () {
var self = Container.call(this);
var lockerBackground = self.attachAsset('sciFiLargeRect', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.8
});
var lockerGlow = self.attachAsset('glow', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.2,
scaleX: 0.3,
scaleY: 0.5
});
self.isPlayerHidden = false;
self.initialize = function (roomNumber) {
// Position locker on the side of screen
self.x = 1700;
self.y = 1366;
// Locker colors (metallic blue/gray)
lockerBackground.tint = 0x2c3e50;
lockerGlow.tint = 0x3498db;
lockerBackground.scaleX = 0.8;
lockerBackground.scaleY = 2.5;
// Start subtle glow animation
self.startGlow();
};
self.startGlow = function () {
var glowDuration = 2000 + Math.random() * 1000;
tween(lockerGlow, {
alpha: 0.1 + Math.random() * 0.3,
scaleX: 0.2 + Math.random() * 0.2,
scaleY: 0.4 + Math.random() * 0.3
}, {
duration: glowDuration,
easing: tween.easeInOut,
onFinish: function onFinish() {
self.startGlow();
}
});
};
self.down = function (x, y, obj) {
if (!self.isPlayerHidden) {
self.hidePlayer();
} else {
self.showPlayer();
}
};
self.hidePlayer = function () {
self.isPlayerHidden = true;
isPlayerHidden = true;
// Start anxiety buildup
anxietyLevel = 0;
// Show anxiety meter
anxietyMeter.visible = true;
anxietyTimer = LK.setInterval(function () {
anxietyLevel += 1;
// Update anxiety meter display
anxietyMeter.setText('Anxiety: ' + anxietyLevel + '/' + maxAnxiety);
// Change color based on anxiety level
if (anxietyLevel >= 80) {
anxietyMeter.tint = 0xff0000; // Red
} else if (anxietyLevel >= 50) {
anxietyMeter.tint = 0xff6600; // Orange
} else if (anxietyLevel >= 25) {
anxietyMeter.tint = 0xffff00; // Yellow
} else {
anxietyMeter.tint = 0x00ff00; // Green
}
if (anxietyLevel >= maxAnxiety) {
// Player loses due to max anxiety
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
}
// Visual anxiety effects - screen gets redder as anxiety increases
var anxietyRatio = anxietyLevel / maxAnxiety;
var redTint = Math.floor(255 * anxietyRatio);
LK.effects.flashScreen(redTint << 16, 100);
}, 200); // Increase anxiety every 200ms
// Visual feedback for hiding
tween(lockerBackground, {
tint: 0x27ae60,
scaleX: 0.9
}, {
duration: 300,
easing: tween.easeOut
});
tween(lockerGlow, {
alpha: 0.5,
tint: 0x2ecc71
}, {
duration: 300,
easing: tween.easeOut
});
};
self.showPlayer = function () {
// Stop anxiety buildup
if (anxietyTimer) {
LK.clearInterval(anxietyTimer);
anxietyTimer = null;
}
anxietyLevel = 0;
// Hide anxiety meter
anxietyMeter.visible = false;
// Check if coming out too early during active danger timer OR not during exit window
if (currentDangerTimer && currentDangerTimer.isActive && currentDangerTimer.timeLeft > 1) {
// Penalty for early exit - flash red and restart timer
LK.effects.flashScreen(0xff0000, 300);
if (currentDangerTimer.phaseCount > 0) {
// Extra harsh penalty in later phases
currentDangerTimer.timeLeft = Math.max(2, currentDangerTimer.timeLeft - 2);
currentDangerTimer.timerText.setText(currentDangerTimer.timeLeft.toString());
currentDangerTimer.warningText.setText('TOO EARLY! ENTITY NOTICED YOU!');
currentDangerTimer.warningText.tint = 0xff0000;
}
} else if (!isExitWindowActive && hasKeycard) {
// Coming out when not in safe exit window - restart danger sequence
LK.effects.flashScreen(0xff6600, 300);
if (currentDangerTimer) {
currentDangerTimer.warningText.setText('ENTITY RETURNED! HIDE AGAIN!');
currentDangerTimer.warningText.tint = 0xff6600;
hasKeycard = false;
currentDangerTimer.startTimer();
}
}
self.isPlayerHidden = false;
isPlayerHidden = false;
// Visual feedback for coming out
tween(lockerBackground, {
tint: 0x2c3e50,
scaleX: 0.8
}, {
duration: 300,
easing: tween.easeOut
});
tween(lockerGlow, {
alpha: 0.2,
tint: 0x3498db
}, {
duration: 300,
easing: tween.easeOut
});
};
return self;
});
var NeonCircuit = Container.expand(function () {
var self = Container.call(this);
self.circuits = [];
self.createCircuits = function (roomNumber) {
// Clear existing circuits
for (var i = 0; i < self.circuits.length; i++) {
self.circuits[i].destroy();
}
self.circuits = [];
var seed = roomNumber * 31;
var numCircuits = 4 + roomNumber % 6;
for (var i = 0; i < numCircuits; i++) {
var circuit = self.attachAsset('sciFiSmallRect', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.4 + Math.random() * 0.5
});
// Position circuits
circuit.x = (seed + i * 157) % 1000 / 1000 * 1800 + 124;
circuit.y = (seed + i * 211) % 1000 / 1000 * 2400 + 166;
// Random rotation and scale
circuit.rotation = (seed + i * 83) % 360 * Math.PI / 180;
var scale = 0.5 + Math.random() * 1.0;
circuit.scaleX = scale;
circuit.scaleY = scale * 0.3; // Make them thinner like circuit traces
// Bright neon colors
var neonColors = [0x00ff41, 0xff073a, 0x39ff14, 0xff6600, 0x00ffff, 0xff00ff];
var colorIndex = (seed + i * 47) % neonColors.length;
circuit.tint = neonColors[colorIndex];
self.circuits.push(circuit);
self.animateCircuit(circuit, i);
}
};
self.animateCircuit = function (circuit, index) {
var duration = 2000 + index * 300;
var targetAlpha = 0.2 + Math.random() * 0.7;
var pulseScale = 0.3 + Math.random() * 1.2;
tween(circuit, {
alpha: targetAlpha,
scaleX: pulseScale,
scaleY: pulseScale * 0.3,
rotation: circuit.rotation + Math.PI * 0.25
}, {
duration: duration,
easing: tween.easeInOut,
onFinish: function onFinish() {
self.animateCircuit(circuit, index);
}
});
};
return self;
});
var ParticleSystem = Container.expand(function () {
var self = Container.call(this);
self.particles = [];
self.createParticles = function (count, roomNumber) {
// Clear existing particles
for (var i = 0; i < self.particles.length; i++) {
self.particles[i].destroy();
}
self.particles = [];
var seed = roomNumber * 23;
for (var i = 0; i < count; i++) {
var particle = self.attachAsset('particle', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.6 + Math.random() * 0.4
});
// Random position
particle.x = Math.random() * 2048;
particle.y = Math.random() * 2732;
// Random color from sci-fi palette
var colorIndex = (seed + i * 31) % sciFiColors.length;
particle.tint = sciFiColors[colorIndex];
// Random scale
var scale = 0.5 + Math.random() * 1.5;
particle.scaleX = scale;
particle.scaleY = scale;
self.particles.push(particle);
self.animateParticle(particle, i);
}
};
self.animateParticle = function (particle, index) {
var duration = 2000 + Math.random() * 3000;
var targetX = Math.random() * 2048;
var targetY = Math.random() * 2732;
var targetAlpha = 0.2 + Math.random() * 0.6;
tween(particle, {
x: targetX,
y: targetY,
alpha: targetAlpha,
rotation: particle.rotation + Math.PI * 2
}, {
duration: duration,
easing: tween.easeInOut,
onFinish: function onFinish() {
self.animateParticle(particle, index);
}
});
};
return self;
});
var RoomDisplay = Container.expand(function () {
var self = Container.call(this);
var background = self.attachAsset('roomBackground', {
anchorX: 0.5,
anchorY: 0.5
});
self.updateRoom = function (roomNumber) {
// Simple visual feedback for room change
tween(self, {
alpha: 0.7
}, {
duration: 150,
onFinish: function onFinish() {
tween(self, {
alpha: 1
}, {
duration: 150
});
}
});
};
return self;
});
var SciFiBackground = Container.expand(function () {
var self = Container.call(this);
self.shapes = [];
self.createBackground = function (roomNumber) {
// Clear existing shapes
for (var i = 0; i < self.shapes.length; i++) {
self.shapes[i].destroy();
}
self.shapes = [];
// Create multiple geometric shapes based on room number
var seed = roomNumber * 17; // Deterministic but varied
var numShapes = 8 + roomNumber % 6;
for (var i = 0; i < numShapes; i++) {
var shapeType = (seed + i) % 5;
var shape;
switch (shapeType) {
case 0:
shape = self.attachAsset('sciFiCircle', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3 + Math.random() * 0.4
});
break;
case 1:
shape = self.attachAsset('sciFiSmallCircle', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.2 + Math.random() * 0.3
});
break;
case 2:
shape = self.attachAsset('sciFiRect', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.25 + Math.random() * 0.35
});
break;
case 3:
shape = self.attachAsset('sciFiSmallRect', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3 + Math.random() * 0.4
});
break;
case 4:
shape = self.attachAsset('sciFiLargeRect', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.2 + Math.random() * 0.3
});
break;
}
// Position shapes randomly but deterministically
var posX = (seed + i * 73) % 1000 / 1000 * 1800 + 124;
var posY = (seed + i * 127) % 1000 / 1000 * 2400 + 166;
shape.x = posX;
shape.y = posY;
shape.rotation = (seed + i * 91) % 360 * Math.PI / 180;
// Color variation
var colorIndex = (seed + i * 43) % sciFiColors.length;
shape.tint = sciFiColors[colorIndex];
self.shapes.push(shape);
// Animate shapes
self.animateShape(shape, i);
}
};
self.animateShape = function (shape, index) {
var duration = 3000 + index * 200;
var scale = 0.8 + Math.random() * 0.4;
var targetX = shape.x + (Math.random() - 0.5) * 200;
var targetY = shape.y + (Math.random() - 0.5) * 200;
// Keep shapes within bounds
targetX = Math.max(100, Math.min(1948, targetX));
targetY = Math.max(100, Math.min(2632, targetY));
tween(shape, {
scaleX: scale,
scaleY: scale,
rotation: shape.rotation + Math.PI * 2,
x: targetX,
y: targetY,
alpha: 0.2 + Math.random() * 0.4
}, {
duration: duration,
easing: tween.easeInOut,
onFinish: function onFinish() {
self.animateShape(shape, index);
}
});
};
return self;
});
var StarField = Container.expand(function () {
var self = Container.call(this);
self.stars = [];
self.createStars = function (roomNumber) {
// Clear existing stars
for (var i = 0; i < self.stars.length; i++) {
self.stars[i].destroy();
}
self.stars = [];
var seed = roomNumber * 11;
var numStars = 20 + roomNumber % 15;
for (var i = 0; i < numStars; i++) {
var star = self.attachAsset('particle', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3 + Math.random() * 0.7
});
// Random position
star.x = Math.random() * 2048;
star.y = Math.random() * 2732;
// Vary star sizes
var scale = 0.3 + Math.random() * 1.2;
star.scaleX = scale;
star.scaleY = scale;
// Bright white stars with occasional color tints
if (Math.random() < 0.8) {
star.tint = 0xffffff;
} else {
var colorIndex = (seed + i * 19) % sciFiColors.length;
star.tint = sciFiColors[colorIndex];
}
self.stars.push(star);
self.animateStar(star, i);
}
};
self.animateStar = function (star, index) {
var duration = 3000 + Math.random() * 4000;
var targetAlpha = 0.1 + Math.random() * 0.8;
var targetScale = 0.2 + Math.random() * 1.5;
tween(star, {
alpha: targetAlpha,
scaleX: targetScale,
scaleY: targetScale,
rotation: star.rotation + Math.PI * 0.5
}, {
duration: duration,
easing: tween.easeInOut,
onFinish: function onFinish() {
self.animateStar(star, index);
}
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x0a0a2e
});
/****
* Game Code
****/
// Game state variables
var currentRoom = storage.currentRoom || 1;
// Reset to room 1 if currentRoom is 25 (game over condition)
if (currentRoom === 25) {
currentRoom = 1;
storage.currentRoom = 1;
}
var maxRoom = 100;
var isAdvancing = false;
var hasKeycard = false;
var currentKeycard = null;
var isPlayerHidden = false;
var currentLocker = null;
var currentDangerTimer = null;
var anxietyLevel = 0;
var maxAnxiety = 100;
var anxietyTimer = null;
var exitTimer = null;
var isExitWindowActive = false;
// Room types: 0 = normal, 1 = keycard room, 2 = danger room
var roomTypes = [];
function generateRoomTypes() {
roomTypes = [];
for (var i = 1; i <= maxRoom; i++) {
// Every 5th room starting from room 3 is a keycard room
if (i > 2 && (i - 3) % 5 === 0) {
roomTypes[i] = 1; // keycard room
// Increase danger room frequency further into the game
} else if (i > 3 && (i <= 20 && (i - 4) % 7 === 0 || i > 20 && i <= 50 && (i - 4) % 5 === 0 || i > 50 && (i - 4) % 3 === 0)) {
roomTypes[i] = 2; // danger room
} else {
roomTypes[i] = 0; // normal room
}
}
}
function isKeycardRoom(roomNum) {
return roomTypes[roomNum] === 1;
}
function isDangerRoom(roomNum) {
return roomTypes[roomNum] === 2;
}
// Generate room types at start
generateRoomTypes();
// Sci-fi color palette for procedural backgrounds
var sciFiColors = [0x0a0a2e, 0x16213e, 0x0f3460, 0x533483, 0x7209b7, 0x2d1b69, 0x11998e, 0x38817a, 0x4a90e2, 0x6c5ce7, 0x74b9ff, 0x00b894, 0xa29bfe, 0xfd79a8, 0xfdcb6e, 0xe17055, 0x00cec9, 0x55a3ff, 0x5f27cd, 0x341f97];
// Function to get procedural background color based on room number
function getSciFiBackgroundColor(roomNum) {
// Use room number to create deterministic but varied color selection
var baseIndex = (roomNum - 1) % sciFiColors.length;
var variation = Math.floor((roomNum - 1) / sciFiColors.length) % 3;
var colorIndex = (baseIndex + variation) % sciFiColors.length;
return sciFiColors[colorIndex];
}
// Create star field (deep background layer)
var starField = game.addChild(new StarField());
starField.createStars(currentRoom);
// Create energy grid (background layer)
var energyGrid = game.addChild(new EnergyGrid());
energyGrid.createGrid(currentRoom);
// Create glow effects (background layer)
var glowEffect = game.addChild(new GlowEffect());
glowEffect.createGlows(currentRoom);
// Create neon circuits (mid-background layer)
var neonCircuit = game.addChild(new NeonCircuit());
neonCircuit.createCircuits(currentRoom);
// Create sci-fi background
var sciFiBackground = game.addChild(new SciFiBackground());
sciFiBackground.createBackground(currentRoom);
// Create core orbs (mid layer)
var coreOrbs = [];
var numOrbs = 3 + currentRoom % 3;
for (var i = 0; i < numOrbs; i++) {
var orb = game.addChild(new CoreOrb());
orb.initialize(currentRoom, i);
coreOrbs.push(orb);
}
// Create particle system (foreground layer)
var particleSystem = game.addChild(new ParticleSystem());
particleSystem.createParticles(15 + currentRoom % 10, currentRoom);
// Create holographic overlay (top layer)
var holographicOverlay = game.addChild(new HolographicOverlay());
holographicOverlay.createHoloElements(currentRoom);
// Create room display
var roomDisplay = game.addChild(new RoomDisplay());
roomDisplay.x = 2048 / 2;
roomDisplay.y = 2732 / 2 - 200;
// Set initial sci-fi background color
var initialBackgroundColor = getSciFiBackgroundColor(currentRoom);
roomDisplay.children[0].tint = initialBackgroundColor;
// Create forward button
var forwardButton = game.addChild(new ForwardButton());
forwardButton.x = 2048 / 2;
forwardButton.y = 2732 / 2 + 300;
// Handle initial room setup
if (isKeycardRoom(currentRoom)) {
forwardButton.visible = false;
forwardButton.alpha = 0;
currentKeycard = game.addChild(new Keycard());
currentKeycard.initialize(currentRoom);
hasKeycard = false;
} else if (isDangerRoom(currentRoom)) {
forwardButton.visible = false;
forwardButton.alpha = 0;
currentLocker = game.addChild(new Locker());
currentLocker.initialize(currentRoom);
currentDangerTimer = game.addChild(new DangerTimer());
currentDangerTimer.x = 1024;
currentDangerTimer.y = 400;
currentDangerTimer.startTimer();
hasKeycard = false;
} else {
hasKeycard = true; // Normal rooms don't need keycards
}
// Create room counter text
var roomTypeText = isKeycardRoom(currentRoom) ? ' (Keycard)' : isDangerRoom(currentRoom) ? ' (Danger)' : '';
var roomCounterText = new Text2('Room ' + currentRoom + '/' + maxRoom + roomTypeText, {
size: 120,
fill: 0x333333
});
roomCounterText.anchor.set(0.5, 0.5);
roomCounterText.x = 2048 / 2;
roomCounterText.y = 2732 / 2 - 100;
game.addChild(roomCounterText);
// Create title text
var titleText = new Text2('Room Runner 100', {
size: 80,
fill: 0x666666
});
titleText.anchor.set(0.5, 0);
LK.gui.top.addChild(titleText);
titleText.y = 150;
// Create anxiety meter
var anxietyMeter = new Text2('Anxiety: 0/100', {
size: 60,
fill: 0x00ff00
});
anxietyMeter.anchor.set(0, 0);
LK.gui.topLeft.addChild(anxietyMeter);
anxietyMeter.x = 120; // Offset from left edge to avoid platform menu
anxietyMeter.y = 50;
anxietyMeter.visible = false; // Initially hidden
// Function to advance to next room
function advanceRoom() {
if (currentRoom < maxRoom && !isAdvancing && hasKeycard) {
isAdvancing = true;
forwardButton.visible = false; // Hide button during transition
// Clear any active timers
if (anxietyTimer) {
LK.clearInterval(anxietyTimer);
anxietyTimer = null;
}
if (exitTimer) {
LK.clearInterval(exitTimer);
exitTimer = null;
}
anxietyLevel = 0;
isExitWindowActive = false;
// Hide anxiety meter when advancing rooms
anxietyMeter.visible = false;
// Clean up danger room objects
if (currentLocker) {
currentLocker.destroy();
currentLocker = null;
}
if (currentDangerTimer) {
currentDangerTimer.destroy();
currentDangerTimer = null;
}
currentRoom++;
storage.currentRoom = currentRoom;
// Update room counter with room type
var roomTypeText = isKeycardRoom(currentRoom) ? ' (Keycard)' : isDangerRoom(currentRoom) ? ' (Danger)' : '';
roomCounterText.setText('Room ' + currentRoom + '/' + maxRoom + roomTypeText);
// Get new sci-fi background color
var newBackgroundColor = getSciFiBackgroundColor(currentRoom);
// Animate background color change
tween(roomDisplay.children[0], {
tint: newBackgroundColor
}, {
duration: 800,
easing: tween.easeInOut
});
// Update star field
starField.createStars(currentRoom);
// Update particle system
particleSystem.createParticles(15 + currentRoom % 10, currentRoom);
// Update energy grid
energyGrid.createGrid(currentRoom);
// Update glow effects
glowEffect.createGlows(currentRoom);
// Update neon circuits
neonCircuit.createCircuits(currentRoom);
// Update holographic overlay
holographicOverlay.createHoloElements(currentRoom);
// Update core orbs
for (var i = 0; i < coreOrbs.length; i++) {
coreOrbs[i].destroy();
}
coreOrbs = [];
var numOrbs = 3 + currentRoom % 3;
for (var i = 0; i < numOrbs; i++) {
var orb = game.addChild(new CoreOrb());
orb.initialize(currentRoom, i);
coreOrbs.push(orb);
}
// Update sci-fi background with fade transition
tween(sciFiBackground, {
alpha: 0
}, {
duration: 400,
easing: tween.easeInOut,
onFinish: function onFinish() {
sciFiBackground.createBackground(currentRoom);
tween(sciFiBackground, {
alpha: 1
}, {
duration: 400,
easing: tween.easeInOut
});
}
});
// Update room display
roomDisplay.updateRoom(currentRoom);
// Add downtime before allowing next press
LK.setTimeout(function () {
isAdvancing = false;
if (currentRoom < maxRoom) {
// Check room type and setup accordingly
if (isKeycardRoom(currentRoom)) {
// Spawn keycard and hide button
hasKeycard = false;
currentKeycard = game.addChild(new Keycard());
currentKeycard.initialize(currentRoom);
forwardButton.visible = false;
forwardButton.alpha = 0;
} else if (isDangerRoom(currentRoom)) {
// Spawn locker and timer, hide button
hasKeycard = false;
isPlayerHidden = false;
currentLocker = game.addChild(new Locker());
currentLocker.initialize(currentRoom);
currentDangerTimer = game.addChild(new DangerTimer());
currentDangerTimer.x = 1024;
currentDangerTimer.y = 400;
currentDangerTimer.startTimer();
forwardButton.visible = false;
forwardButton.alpha = 0;
} else {
// Normal room - show button immediately
hasKeycard = true;
forwardButton.visible = true;
forwardButton.alpha = 1;
}
}
}, 1200); // 1.2 second downtime
// Check for completion
if (currentRoom >= maxRoom) {
LK.setTimeout(function () {
// Reset game state before showing win
storage.currentRoom = 1;
currentRoom = 1;
LK.showYouWin();
}, 500);
}
}
}
// Hide forward button if game is complete
if (currentRoom >= maxRoom) {
forwardButton.visible = false;
roomCounterText.setText('Complete!');
// Auto-trigger win after short delay
LK.setTimeout(function () {
// Reset game state before showing win
storage.currentRoom = 1;
currentRoom = 1;
LK.showYouWin();
}, 1000);
}
game.update = function () {
// Simple idle animation for the forward button
if (LK.ticks % 120 == 0 && currentRoom < maxRoom) {
tween(forwardButton, {
scaleX: 1.05,
scaleY: 1.05
}, {
duration: 300,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(forwardButton, {
scaleX: 1,
scaleY: 1
}, {
duration: 300,
easing: tween.easeInOut
});
}
});
}
};