User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading '0')' in or related to this line: 'return;' Line Number: 578
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading '0')' in or related to this line: 'self.wispGraphics.rotation += 0.01;' Line Number: 226
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading '0')' in or related to this line: 'return;' Line Number: 575
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading '0')' in or related to this line: 'self.wispGraphics.rotation += 0.01;' Line Number: 224
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading '0')' in or related to this line: 'return;' Line Number: 572
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading '0')' in or related to this line: 'return;' Line Number: 572
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading '0')' in or related to this line: 'return;' Line Number: 572
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading '0')' in or related to this line: 'return;' Line Number: 572
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading '0')' in or related to this line: 'self.wispGraphics.rotation += 0.01;' Line Number: 218
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading '0')' in or related to this line: 'if (self.y > 2780) {' Line Number: 1100
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading '0')' in or related to this line: 'self.wispGraphics.rotation += 0.01;' Line Number: 214
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading '0')' in or related to this line: 'return;' Line Number: 562
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading '0')' in or related to this line: 'return;' Line Number: 562
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading '0')' in or related to this line: 'return;' Line Number: 562
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading '0')' in or related to this line: 'if (self.y > 2780) {' Line Number: 1092
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading '0')' in or related to this line: 'return;' Line Number: 562
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading '0')' in or related to this line: 'return;' Line Number: 562
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading '0')' in or related to this line: 'return;' Line Number: 562
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading '0')' in or related to this line: 'return;' Line Number: 562
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading '0')' in or related to this line: 'return;' Line Number: 562
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading '0')' in or related to this line: 'return;' Line Number: 562
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading '0')' in or related to this line: 'return;' Line Number: 562
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading '0')' in or related to this line: 'return;' Line Number: 562
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading '0')' in or related to this line: 'return;' Line Number: 562
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading '0')' in or related to this line: 'return;' Line Number: 562
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var AuraParticle = Container.expand(function (type) { var self = Container.call(this); self.type = type || 'green'; self.collected = false; var assetName = 'aura' + self.type.charAt(0).toUpperCase() + self.type.slice(1); var auraGraphics = self.attachAsset(assetName, { anchorX: 0.5, anchorY: 0.5 }); auraGraphics.alpha = 0.8; self.floatOffset = Math.random() * Math.PI * 2; self.floatSpeed = 0.02 + Math.random() * 0.03; self.pulseOffset = Math.random() * Math.PI * 2; self.initialY = 0; self.initialScale = 1.0; // Start gentle pulsing animation tween(auraGraphics, { scaleX: 1.2, scaleY: 1.2, alpha: 1.0 }, { duration: 1500 + Math.random() * 1000, easing: tween.easeInOut, onFinish: function onFinish() { if (!self.collected) { tween(auraGraphics, { scaleX: 0.8, scaleY: 0.8, alpha: 0.6 }, { duration: 1500 + Math.random() * 1000, easing: tween.easeInOut, onFinish: function onFinish() { if (!self.collected) { tween(auraGraphics, { scaleX: 1.0, scaleY: 1.0, alpha: 0.8 }, { duration: 1000, easing: tween.easeInOut }); } } }); } } }); self.update = function () { if (!self.collected) { self.y = self.initialY + Math.sin(LK.ticks * self.floatSpeed + self.floatOffset) * 8; auraGraphics.rotation += 0.015; } }; return self; }); var AuraWisp = Container.expand(function (wispType) { var self = Container.call(this); self.wispType = wispType || 'green'; self.collected = false; self.isMovingToPlayer = false; self.moveSpeed = 3.5; // Set wisp color based on type var wispColors = { green: 0xc8e6c9, blue: 0xb3d9ff, yellow: 0xfff8d1 }; self.wispGraphics = self.attachAsset('auraWisp', { anchorX: 0.5, anchorY: 0.5 }); // Apply wisp type color self.wispGraphics.tint = wispColors[self.wispType]; self.wispGraphics.alpha = 0.7; self.floatOffset = Math.random() * Math.PI * 2; self.floatSpeed = 0.025 + Math.random() * 0.015; self.pulseOffset = Math.random() * Math.PI * 2; self.initialY = 0; self.emergeDuration = 120; // 2 seconds to emerge self.emergeTimer = 0; // Start gentle emergence animation tween(self.wispGraphics, { alpha: 0.9, scaleX: 1.2, scaleY: 1.2 }, { duration: 1000 + Math.random() * 500, easing: tween.easeOut, onFinish: function onFinish() { if (!self.collected) { // Start floating towards player self.isMovingToPlayer = true; } } }); self.moveTowardsPlayer = function () { if (!player || self.collected) return; var dx = player.x - self.x; var dy = player.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 10) { // Gentle movement towards player self.x += dx / distance * self.moveSpeed; self.y += dy / distance * self.moveSpeed; } else { // Close enough to be collected self.collected = true; // Award small aura auraCount[self.wispType]++; updateUI(); // Gentle collection animation tween(self.wispGraphics, { scaleX: 1.8, scaleY: 1.8, alpha: 1.0 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(self.wispGraphics, { scaleX: 0, scaleY: 0, alpha: 0 }, { duration: 300, easing: tween.easeIn, onFinish: function onFinish() { self.destroy(); } }); } }); LK.getSound('collectAura').play(); } }; self.update = function () { // Ensure self and wispGraphics are properly defined before proceeding if (typeof self === 'undefined' || !self.wispGraphics) return; if (self.collected) return; // Comprehensive safety check for all required properties if (typeof self.isMovingToPlayer === 'undefined' || typeof self.initialY === 'undefined' || typeof self.floatSpeed === 'undefined' || typeof self.floatOffset === 'undefined' || typeof self.emergeTimer === 'undefined' || typeof self.emergeDuration === 'undefined' || typeof self.pulseOffset === 'undefined') { return; } if (!self.isMovingToPlayer) { // Gentle floating motion while emerging self.y = self.initialY + Math.sin(LK.ticks * self.floatSpeed + self.floatOffset) * 6; self.emergeTimer++; // Start moving towards player after emergence period if (self.emergeTimer >= self.emergeDuration) { self.isMovingToPlayer = true; } } else { // Move towards player with gentle floating motion if (typeof self.moveTowardsPlayer === 'function') { self.moveTowardsPlayer(); } // Add gentle floating while moving var floatMotion = Math.sin(LK.ticks * self.floatSpeed + self.floatOffset) * 4; self.y += floatMotion * 0.1; } // Comprehensive safety check for wispGraphics before accessing any properties if (self.wispGraphics && _typeof(self.wispGraphics) === 'object' && self.wispGraphics !== null) { // Check alpha property exists and is valid before modifying if (typeof self.wispGraphics.alpha !== 'undefined' && typeof self.wispGraphics.alpha === 'number') { self.wispGraphics.alpha = 0.6 + Math.sin(LK.ticks * 0.04 + self.pulseOffset) * 0.3; } // Check rotation property exists and is valid before modifying if (typeof self.wispGraphics.rotation !== 'undefined' && typeof self.wispGraphics.rotation === 'number') { self.wispGraphics.rotation += 0.01; } } }; return self; }); var DistantCloud = Container.expand(function () { var self = Container.call(this); var cloudGraphics = self.attachAsset('distantCloud', { anchorX: 0.5, anchorY: 0.5 }); cloudGraphics.alpha = 0.3 + Math.random() * 0.2; self.driftSpeed = 0.1 + Math.random() * 0.15; // Extremely slow drift self.initialX = 0; self.floatOffset = Math.random() * Math.PI * 2; self.floatSpeed = 0.003 + Math.random() * 0.005; // Very slow vertical float self.initialY = 0; // Start gentle size pulsing for natural cloud variation tween(cloudGraphics, { scaleX: 1.1 + Math.random() * 0.2, scaleY: 1.1 + Math.random() * 0.2 }, { duration: 8000 + Math.random() * 4000, easing: tween.easeInOut, onFinish: function onFinish() { tween(cloudGraphics, { scaleX: 0.9, scaleY: 0.9 }, { duration: 8000 + Math.random() * 4000, easing: tween.easeInOut }); } }); self.update = function () { // Imperceptibly slow horizontal drift - consistent with typical cloud movement // Enhanced with tween-based smooth transitions for more natural movement self.x += self.driftSpeed * 0.3; // Reduced to imperceptibly slow speed // Very subtle vertical floating motion self.y = self.initialY + Math.sin(LK.ticks * self.floatSpeed + self.floatOffset) * 8; // Reset cloud when it goes off screen if (self.x > 2100) { self.x = -200; self.initialX = self.x; // Add subtle tween variation when cloud resets for natural repositioning tween(self, { x: self.x + (Math.random() - 0.5) * 100, y: self.initialY + (Math.random() - 0.5) * 80 }, { duration: 5000 + Math.random() * 3000, easing: tween.easeInOut }); } }; return self; }); var EphemeralCreature = Container.expand(function (creatureType) { var self = Container.call(this); self.creatureType = creatureType || 'fox'; self.hasAppeared = false; self.isObserving = false; self.observeTimer = 0; self.observeDuration = 180; // 3 seconds at 60fps var assetName = 'ephemeral' + self.creatureType.charAt(0).toUpperCase() + self.creatureType.slice(1); var creatureGraphics = self.attachAsset(assetName, { anchorX: 0.5, anchorY: 0.5 }); // Start invisible creatureGraphics.alpha = 0; self.floatOffset = Math.random() * Math.PI * 2; self.floatSpeed = 0.015; self.initialY = 0; self.appear = function () { if (self.hasAppeared) return; self.hasAppeared = true; // Create sparkling shimmer effect during appearance self.createShimmerBurst(12); // Gentle fade in appearance tween(creatureGraphics, { alpha: 0.8, scaleX: 1.1, scaleY: 1.1 }, { duration: 1500, easing: tween.easeOut, onFinish: function onFinish() { self.isObserving = true; // Gentle glow pulsing while observing tween(creatureGraphics, { alpha: 1.0, scaleX: 1.0, scaleY: 1.0 }, { duration: 800, easing: tween.easeInOut, onFinish: function onFinish() { tween(creatureGraphics, { alpha: 0.7, scaleX: 1.1, scaleY: 1.1 }, { duration: 800, easing: tween.easeInOut }); } }); } }); }; self.fadeAway = function () { self.isObserving = false; // Create gentle dissipation shimmer effect self.createShimmerBurst(8); // Gentle fade out tween(creatureGraphics, { alpha: 0, scaleX: 0.8, scaleY: 0.8 }, { duration: 2000, easing: tween.easeIn, onFinish: function onFinish() { self.destroy(); } }); }; self.update = function () { if (self.hasAppeared && !self.isObserving) return; // Gentle floating motion self.y = self.initialY + Math.sin(LK.ticks * self.floatSpeed + self.floatOffset) * 12; // Subtle rotation for hummingbird if (self.creatureType === 'hummingbird') { creatureGraphics.rotation = Math.sin(LK.ticks * 0.08) * 0.1; } // Count observe timer if (self.isObserving) { self.observeTimer++; if (self.observeTimer >= self.observeDuration) { self.fadeAway(); } } }; self.createShimmerBurst = function (count) { for (var i = 0; i < count; i++) { var shimmer = new EphemeralShimmer(); // Position around creature with some spread var angle = Math.random() * Math.PI * 2; var distance = 30 + Math.random() * 60; shimmer.x = self.x + Math.cos(angle) * distance; shimmer.y = self.y + Math.sin(angle) * distance; // Add to global shimmer tracking ephemeralShimmers.push(shimmer); game.addChild(shimmer); // Gentle sparkle appearance tween(shimmer, { alpha: 0.7 + Math.random() * 0.3, scaleX: 1.2, scaleY: 1.2 }, { duration: 300 + Math.random() * 200, easing: tween.easeOut }); } }; return self; }); var EphemeralShimmer = Container.expand(function () { var self = Container.call(this); var shimmerGraphics = self.attachAsset('ephemeralShimmer', { anchorX: 0.5, anchorY: 0.5 }); shimmerGraphics.alpha = 0; self.speed = 1.5 + Math.random() * 2.0; self.driftX = (Math.random() - 0.5) * 4; self.driftY = -1 - Math.random() * 2; self.floatOffset = Math.random() * Math.PI * 2; self.floatSpeed = 0.05 + Math.random() * 0.03; self.lifetime = 90 + Math.random() * 60; // 1.5-2.5 seconds self.age = 0; self.update = function () { // Ensure age and lifetime are defined before using them if (typeof self.age === 'undefined') self.age = 0; if (typeof self.lifetime === 'undefined') self.lifetime = 90 + Math.random() * 60; self.age++; self.x += self.driftX; self.y += self.driftY; // Gentle floating motion self.x += Math.sin(LK.ticks * self.floatSpeed + self.floatOffset) * 0.5; // Fade out over lifetime var lifeProgress = self.age / self.lifetime; shimmerGraphics.alpha = (1 - lifeProgress) * 0.8; shimmerGraphics.scaleX = 1 - lifeProgress * 0.3; shimmerGraphics.scaleY = 1 - lifeProgress * 0.3; // Remove when lifetime exceeded if (self.age >= self.lifetime) { self.destroy(); } }; return self; }); var FloatingParticle = Container.expand(function () { var self = Container.call(this); var particleGraphics = self.attachAsset('floatingParticle', { anchorX: 0.5, anchorY: 0.5 }); particleGraphics.alpha = 0.3 + Math.random() * 0.4; self.driftSpeed = 0.5 + Math.random() * 1.0; self.floatOffset = Math.random() * Math.PI * 2; self.floatSpeed = 0.01 + Math.random() * 0.02; self.initialX = 0; self.update = function () { self.y -= self.driftSpeed; self.x = self.initialX + Math.sin(LK.ticks * self.floatSpeed + self.floatOffset) * 20; particleGraphics.rotation += 0.01; // Reset particle when it goes off screen if (self.y < -50) { self.y = 2800; self.x = Math.random() * 2048; self.initialX = self.x; } }; return self; }); var HavenDecoration = Container.expand(function (decorationType) { var self = Container.call(this); self.decorationType = decorationType || 'plant'; var assetName = self.decorationType + 'Decoration'; var decorationGraphics = self.attachAsset(assetName, { anchorX: 0.5, anchorY: 1.0 }); decorationGraphics.alpha = 0.9; self.swayOffset = Math.random() * Math.PI * 2; self.swaySpeed = 0.01 + Math.random() * 0.02; self.update = function () { // Gentle swaying animation for plants and light decorations if (self.decorationType === 'plant' || self.decorationType === 'light') { decorationGraphics.rotation = Math.sin(LK.ticks * self.swaySpeed + self.swayOffset) * 0.05; } // Subtle pulsing for light decorations if (self.decorationType === 'light') { decorationGraphics.alpha = 0.7 + Math.sin(LK.ticks * 0.03 + self.swayOffset) * 0.2; } }; return self; }); var HiddenVignette = Container.expand(function (vignetteType) { var self = Container.call(this); self.vignetteType = vignetteType || 'mushroom'; self.discovered = false; self.isActive = false; self.fireflies = []; // Create main vignette element var mainAsset = ''; if (self.vignetteType === 'mushroom') mainAsset = 'mushroomRing';else if (self.vignetteType === 'waterfall') mainAsset = 'hiddenWaterfall';else if (self.vignetteType === 'bear') mainAsset = 'sleepingBear'; var vignetteGraphics = self.attachAsset(mainAsset, { anchorX: 0.5, anchorY: 0.5 }); vignetteGraphics.alpha = 0; // Start invisible self.pulseOffset = Math.random() * Math.PI * 2; self.breathOffset = Math.random() * Math.PI * 2; // Discover animation self.discover = function () { if (self.discovered) return; self.discovered = true; self.isActive = true; // Gentle fade in discovery tween(vignetteGraphics, { alpha: 0.8, scaleX: 1.0, scaleY: 1.0 }, { duration: 2000, easing: tween.easeOut }); // Play vignette-specific sound var soundName = 'vignette' + self.vignetteType.charAt(0).toUpperCase() + self.vignetteType.slice(1); LK.getSound(soundName).play(); // Create special effects based on type if (self.vignetteType === 'mushroom') { self.createFireflies(); } else if (self.vignetteType === 'waterfall') { self.createRainbow(); } }; self.createFireflies = function () { // Create dancing fireflies around mushroom ring for (var i = 0; i < 8; i++) { var firefly = self.addChild(LK.getAsset('firefly', { anchorX: 0.5, anchorY: 0.5 })); firefly.alpha = 0; firefly.danceAngle = Math.PI * 2 / 8 * i; firefly.danceRadius = 80 + Math.random() * 40; firefly.danceSpeed = 0.02 + Math.random() * 0.02; firefly.pulseOffset = Math.random() * Math.PI * 2; self.fireflies.push(firefly); // Fade in firefly tween(firefly, { alpha: 0.7 + Math.random() * 0.3 }, { duration: 1000 + Math.random() * 1000, easing: tween.easeOut }); } }; self.createRainbow = function () { // Create subtle rainbow mist effect LK.effects.flashObject(vignetteGraphics, 0xff9800, 3000); // Add gentle shimmer tween(vignetteGraphics, { alpha: 1.0 }, { duration: 1500, easing: tween.easeInOut, onFinish: function onFinish() { tween(vignetteGraphics, { alpha: 0.6 }, { duration: 1500, easing: tween.easeInOut }); } }); }; self.update = function () { if (!self.isActive) return; // Gentle pulsing for mushroom ring if (self.vignetteType === 'mushroom') { vignetteGraphics.alpha = 0.6 + Math.sin(LK.ticks * 0.02 + self.pulseOffset) * 0.2; // Animate fireflies dancing for (var i = 0; i < self.fireflies.length; i++) { var firefly = self.fireflies[i]; firefly.danceAngle += firefly.danceSpeed; firefly.x = Math.cos(firefly.danceAngle) * firefly.danceRadius; firefly.y = Math.sin(firefly.danceAngle) * firefly.danceRadius; firefly.alpha = 0.4 + Math.sin(LK.ticks * 0.05 + firefly.pulseOffset) * 0.4; } } // Gentle breathing for sleeping bear else if (self.vignetteType === 'bear') { var breathScale = 1.0 + Math.sin(LK.ticks * 0.015 + self.breathOffset) * 0.05; vignetteGraphics.scaleX = breathScale; vignetteGraphics.scaleY = breathScale; } // Subtle shimmer for waterfall else if (self.vignetteType === 'waterfall') { vignetteGraphics.alpha = 0.7 + Math.sin(LK.ticks * 0.03 + self.pulseOffset) * 0.1; } }; return self; }); var LightShimmer = Container.expand(function () { var self = Container.call(this); var shimmerGraphics = self.attachAsset('lightShimmer', { anchorX: 0.5, anchorY: 0.5 }); shimmerGraphics.alpha = 0.1; self.pulseOffset = Math.random() * Math.PI * 2; self.pulseSpeed = 0.005 + Math.random() * 0.003; // Very slow, breathing-like pulse self.breathAmplitude = 0.05 + Math.random() * 0.03; // Very subtle intensity variation // Start gentle breathing animation using tween for smooth transitions self.startShimmer = function () { var breatheIn = function breatheIn() { tween(shimmerGraphics, { alpha: 0.15 + self.breathAmplitude, scaleX: 1.05, scaleY: 1.05 }, { duration: 8000 + Math.random() * 4000, // 8-12 seconds per breath easing: tween.easeInOut, onFinish: breatheOut }); }; var breatheOut = function breatheOut() { tween(shimmerGraphics, { alpha: 0.05, scaleX: 0.95, scaleY: 0.95 }, { duration: 8000 + Math.random() * 4000, // 8-12 seconds per breath easing: tween.easeInOut, onFinish: breatheIn }); }; // Start with random direction if (Math.random() < 0.5) { breatheIn(); } else { breatheOut(); } }; self.update = function () { // Additional very subtle pulsing using sine wave for natural variation var subtlePulse = Math.sin(LK.ticks * self.pulseSpeed + self.pulseOffset) * 0.02; shimmerGraphics.alpha += subtlePulse; // Ensure alpha stays within reasonable bounds shimmerGraphics.alpha = Math.max(0.02, Math.min(0.25, shimmerGraphics.alpha)); }; return self; }); var LuminescentParticle = Container.expand(function () { var self = Container.call(this); // Use alternating particle types for variety var assetName = Math.random() < 0.7 ? 'luminescentParticle' : 'luminescentParticleAlt'; var particleGraphics = self.attachAsset(assetName, { anchorX: 0.5, anchorY: 0.5 }); // Soft intensity with pastel colors var pastelColors = [0xe0ffff, 0xf0f8ff, 0xfffacd, 0xf0fff0, 0xffe4e1]; particleGraphics.tint = pastelColors[Math.floor(Math.random() * pastelColors.length)]; particleGraphics.alpha = 0.3 + Math.random() * 0.2; // Reduced for subtle effect // Enhanced movement properties for gentle floating self.driftSpeed = 0.08 + Math.random() * 0.12; // Very slow upward drift self.lateralAmplitude = 20 + Math.random() * 30; // Gentle S-curve amplitude self.lateralSpeed = 0.003 + Math.random() * 0.005; // Very slow lateral sway frequency self.initialX = 0; self.lateralOffset = Math.random() * Math.PI * 2; // Random phase for S-curve self.lateralDirection = Math.random() < 0.5 ? 1 : -1; // Random sway direction // Long lifetime properties self.age = 0; self.maxAge = 3600 + Math.random() * 1800; // 60-90 seconds lifetime for long traversal self.spawned = false; // Soft pulsing properties self.pulseOffset = Math.random() * Math.PI * 2; self.pulseSpeed = 0.008 + Math.random() * 0.007; // Very gentle pulse frequency self.baseAlpha = 0.25 + Math.random() * 0.15; // Soft base opacity // Start gentle emergence animation self.emerge = function () { if (self.spawned) return; self.spawned = true; // Gentle fade in and scale up tween(particleGraphics, { alpha: self.baseAlpha, scaleX: 1.0, scaleY: 1.0 }, { duration: 2000 + Math.random() * 1000, easing: tween.easeOut }); }; // Start gentle pulsing animation self.startPulse = function () { var pulseIn = function pulseIn() { if (self.age >= self.maxAge) return; tween(particleGraphics, { alpha: self.baseAlpha + 0.2, scaleX: 1.1, scaleY: 1.1 }, { duration: 3000 + Math.random() * 2000, easing: tween.easeInOut, onFinish: pulseOut }); }; var pulseOut = function pulseOut() { if (self.age >= self.maxAge) return; tween(particleGraphics, { alpha: self.baseAlpha - 0.1, scaleX: 0.9, scaleY: 0.9 }, { duration: 3000 + Math.random() * 2000, easing: tween.easeInOut, onFinish: pulseIn }); }; // Start with random direction if (Math.random() < 0.5) { pulseIn(); } else { pulseOut(); } }; // Enhanced floating movement system self.update = function () { if (!self.spawned) { self.emerge(); self.startPulse(); } self.age++; // Very slow upward drift - effortless floating self.y -= self.driftSpeed; // Gentle lateral sway in S-curve pattern var lateralSway = Math.sin(LK.ticks * self.lateralSpeed + self.lateralOffset) * self.lateralAmplitude * self.lateralDirection; var secondarySway = Math.cos(LK.ticks * self.lateralSpeed * 0.7 + self.lateralOffset + Math.PI) * self.lateralAmplitude * 0.3; self.x = self.initialX + lateralSway + secondarySway; // Additional very subtle sine wave variation for natural movement var microDrift = Math.sin(LK.ticks * 0.002 + self.lateralOffset) * 3; self.x += microDrift; // Subtle additional alpha variation for ethereal effect var additionalGlow = Math.sin(LK.ticks * self.pulseSpeed + self.pulseOffset) * 0.08; particleGraphics.alpha += additionalGlow; // Gentle rotation for natural floating particleGraphics.rotation += 0.003 * self.lateralDirection; // Reset particle when lifetime exceeded or goes off screen if (self.age >= self.maxAge || self.y < -100) { // Reset for reuse with long lifetime self.y = 2800 + Math.random() * 200; self.x = Math.random() * 2048; self.initialX = self.x; self.age = 0; self.spawned = false; // Randomize movement parameters for variety self.driftSpeed = 0.08 + Math.random() * 0.12; self.lateralAmplitude = 20 + Math.random() * 30; self.lateralSpeed = 0.003 + Math.random() * 0.005; self.lateralDirection = Math.random() < 0.5 ? 1 : -1; self.lateralOffset = Math.random() * Math.PI * 2; self.maxAge = 3600 + Math.random() * 1800; self.baseAlpha = 0.25 + Math.random() * 0.15; // Reset graphics properties particleGraphics.alpha = 0; particleGraphics.scaleX = 0.8; particleGraphics.scaleY = 0.8; } }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 8; self.targetX = 0; self.targetY = 0; self.update = function () { var dx = self.targetX - self.x; var dy = self.targetY - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 5) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; // Play footstep sounds based on biome if (LK.ticks - lastFootstepTime > footstepInterval * 60 / 1000) { var footstepSound = ''; if (currentBiome === 0) footstepSound = 'footstepsGrass'; // Woods else if (currentBiome === 1) footstepSound = 'footstepsPebbles'; // Caverns else if (currentBiome === 2) footstepSound = 'footstepsWater'; // Shore else footstepSound = 'footstepsGrass'; // Sanctuary LK.getSound(footstepSound).play(); lastFootstepTime = LK.ticks; } } }; return self; }); var RareAuraBloom = Container.expand(function () { var self = Container.call(this); self.collected = false; var bloomGraphics = self.attachAsset('rareAuraBloom', { anchorX: 0.5, anchorY: 0.5 }); bloomGraphics.alpha = 0.9; self.pulseOffset = Math.random() * Math.PI * 2; self.floatOffset = Math.random() * Math.PI * 2; self.floatSpeed = 0.03; self.initialY = 0; // Start dramatic pulsating animation tween(bloomGraphics, { scaleX: 1.5, scaleY: 1.5, alpha: 1.0 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { if (!self.collected) { tween(bloomGraphics, { scaleX: 1.0, scaleY: 1.0, alpha: 0.7 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { if (!self.collected) { tween(bloomGraphics, { scaleX: 1.5, scaleY: 1.5, alpha: 1.0 }, { duration: 1000, easing: tween.easeInOut }); } } }); } } }); self.update = function () { if (!self.collected) { self.y = self.initialY + Math.sin(LK.ticks * self.floatSpeed + self.floatOffset) * 15; bloomGraphics.rotation += 0.02; } }; return self; }); var RareBloomBurst = Container.expand(function () { var self = Container.call(this); var burstGraphics = self.attachAsset('rareBloomBurstParticle', { anchorX: 0.5, anchorY: 0.5 }); // Vibrant pastel mix colors var vibrantColors = [0xffd700, 0xff69b4, 0x98fb98, 0x87ceeb, 0xdda0dd, 0xf0e68c]; burstGraphics.tint = vibrantColors[Math.floor(Math.random() * vibrantColors.length)]; burstGraphics.alpha = 0; self.velocity = { x: (Math.random() - 0.5) * 8, y: -2 - Math.random() * 6 }; self.lifetime = 60; // 1 second burst duration self.age = 0; self.gravity = 0.2; // Start burst animation tween(burstGraphics, { alpha: 0.8, scaleX: 1.5, scaleY: 1.5 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(burstGraphics, { alpha: 0, scaleX: 0.5, scaleY: 0.5 }, { duration: 800, easing: tween.easeIn }); } }); self.update = function () { self.age++; self.x += self.velocity.x; self.y += self.velocity.y; self.velocity.y += self.gravity; burstGraphics.rotation += 0.1; // Remove when lifetime exceeded if (self.age >= self.lifetime) { self.destroy(); } }; return self; }); var TreeSwayBranch = Container.expand(function () { var self = Container.call(this); var branchGraphics = self.attachAsset('treeSwayBranch', { anchorX: 0.5, anchorY: 1.0 }); branchGraphics.alpha = 0.7; // Enhanced tree sway parameters for natural movement self.swayOffset = Math.random() * Math.PI * 2; // Random phase for variation between trees self.swaySpeed = 0.006 + Math.random() * 0.004; // Very low frequency (0.1-0.2 Hz equivalent) self.swayAmplitude = 0.02 + Math.random() * 0.015; // Small amplitude (1-3 degrees) self.secondarySwayOffset = Math.random() * Math.PI * 2; // Secondary sway for complexity self.secondarySwaySpeed = 0.004 + Math.random() * 0.003; // Even slower secondary movement self.windVariation = Math.random() * 0.5 + 0.5; // Random wind strength per tree // Enhanced continuous sway animation with multiple layers self.startSway = function () { // Primary sway motion - main side-to-side movement var primarySwayLeft = function primarySwayLeft() { tween(branchGraphics, { rotation: -self.swayAmplitude * self.windVariation }, { duration: 4000 + Math.random() * 3000, // 4-7 seconds per sway for calming rhythm easing: tween.easeInOut, onFinish: primarySwayRight }); }; var primarySwayRight = function primarySwayRight() { tween(branchGraphics, { rotation: self.swayAmplitude * self.windVariation }, { duration: 4000 + Math.random() * 3000, // 4-7 seconds per sway for calming rhythm easing: tween.easeInOut, onFinish: primarySwayLeft }); }; // Start with random direction for phase variation if (Math.random() < 0.5) { primarySwayLeft(); } else { primarySwayRight(); } }; self.update = function () { // Multi-layered natural sway simulation mimicking light breeze // Primary sine wave for main movement var primarySway = Math.sin(LK.ticks * self.swaySpeed + self.swayOffset) * 0.008 * self.windVariation; // Secondary sine wave for complexity and natural variation var secondarySway = Math.sin(LK.ticks * self.secondarySwaySpeed + self.secondarySwayOffset) * 0.004 * self.windVariation; // Tertiary micro-movement for realistic rustling var microSway = Math.sin(LK.ticks * 0.01 + self.swayOffset * 2) * 0.002; // Combine all movement layers for natural breeze effect var totalSway = primarySway + secondarySway + microSway; branchGraphics.rotation += totalSway; // Subtle scale variation to simulate depth movement in breeze var scaleVariation = 1.0 + Math.sin(LK.ticks * self.swaySpeed * 0.7 + self.swayOffset) * 0.01; branchGraphics.scaleX = scaleVariation; }; return self; }); var WaterRipple = Container.expand(function () { var self = Container.call(this); var rippleGraphics = self.attachAsset('waterRipple', { anchorX: 0.5, anchorY: 0.5 }); // Start invisible and small rippleGraphics.alpha = 0; rippleGraphics.scaleX = 0.05; rippleGraphics.scaleY = 0.05; self.isActive = false; self.maxScale = 0.8 + Math.random() * 0.4; // Very low amplitude for barely stirring water self.expandDuration = 15000 + Math.random() * 10000; // Extremely slow 15-25 seconds expansion // Enhanced shader-based animation properties self.noiseOffset = Math.random() * Math.PI * 2; self.noiseOffset2 = Math.random() * Math.PI * 2; self.noiseSpeed = 0.0003 + Math.random() * 0.0002; // Extremely slow noise scrolling self.distortionAmplitude = 0.008 + Math.random() * 0.005; // Minimal distortion for subtle undulations self.scrollDirection = Math.random() * Math.PI * 2; // Random scroll direction self.rippleFrequency = 0.1 + Math.random() * 0.05; // Infrequent pulse frequency self.noiseScrollX = 0; self.noiseScrollY = 0; self.radialOffset = Math.random() * Math.PI * 2; // For radial outward movement self.reflectionShift = 0; // For elongated reflection simulation self.startRipple = function () { if (self.isActive) return; self.isActive = true; // Reset noise pattern position self.noiseScrollX = 0; self.noiseScrollY = 0; self.reflectionShift = 0; // Extremely gentle fade in with very minimal alpha tween(rippleGraphics, { alpha: 0.08, scaleX: 0.1, scaleY: 0.1 }, { duration: 2000, easing: tween.easeOut, onFinish: function onFinish() { // Extremely slow main expansion phase with gradual fade tween(rippleGraphics, { alpha: 0, scaleX: self.maxScale, scaleY: self.maxScale }, { duration: self.expandDuration, easing: tween.easeOut, onFinish: function onFinish() { // Reset for reuse self.isActive = false; rippleGraphics.alpha = 0; rippleGraphics.scaleX = 0.05; rippleGraphics.scaleY = 0.05; } }); } }); }; self.update = function () { if (!self.isActive) return; // Enhanced shader-based noise pattern simulation for natural water movement self.noiseScrollX += Math.cos(self.scrollDirection) * self.noiseSpeed; self.noiseScrollY += Math.sin(self.scrollDirection) * self.noiseSpeed; // Multi-layered noise for complex water surface simulation var primaryNoise = Math.sin(LK.ticks * self.noiseSpeed + self.noiseOffset) * self.distortionAmplitude; var secondaryNoise = Math.cos(LK.ticks * self.noiseSpeed * 1.7 + self.noiseOffset2 + Math.PI) * self.distortionAmplitude * 0.6; var tertiaryNoise = Math.sin(LK.ticks * self.noiseSpeed * 0.5 + self.noiseOffset + Math.PI * 0.5) * self.distortionAmplitude * 0.3; // Radial outward movement simulation var radialPulse = Math.sin(LK.ticks * self.rippleFrequency + self.radialOffset) * 0.002; var radialExpansion = Math.cos(LK.ticks * self.rippleFrequency * 0.7 + self.radialOffset) * 0.001; // Apply extremely subtle rotation distortion for natural water movement rippleGraphics.rotation = (primaryNoise + secondaryNoise * 0.5) * 0.3; // Apply minimal position distortion for gentle drift rippleGraphics.x = (secondaryNoise + tertiaryNoise) * 1.5 + radialPulse * 50; rippleGraphics.y = (primaryNoise + tertiaryNoise * 0.8) * 1.2 + radialPulse * 30; // Simulate scrolling texture pattern with very subtle alpha variation var scrollPattern = Math.sin(self.noiseScrollX * 8) * Math.cos(self.noiseScrollY * 6) * 0.015; var reflectionPattern = Math.sin(self.reflectionShift * 0.1) * 0.01; self.reflectionShift += self.noiseSpeed * 100; // Apply elongated reflection shifts for sky/land reflection simulation rippleGraphics.skewX = (primaryNoise + reflectionPattern) * 0.02; rippleGraphics.skewY = (secondaryNoise + reflectionPattern * 0.7) * 0.015; // Combine all patterns for final alpha with natural pulsing var combinedAlpha = scrollPattern + reflectionPattern + radialExpansion; rippleGraphics.alpha = Math.max(0, Math.min(0.12, rippleGraphics.alpha + combinedAlpha)); }; return self; }); var WeatherParticle = Container.expand(function (weatherType) { var self = Container.call(this); self.weatherType = weatherType || 'rain'; self.speed = 0; self.drift = 0; self.initialX = 0; var assetName = weatherType === 'rain' ? 'rainDrop' : 'snowFlake'; var particleGraphics = self.attachAsset(assetName, { anchorX: 0.5, anchorY: 0.5 }); if (weatherType === 'rain') { particleGraphics.alpha = 0.6 + Math.random() * 0.4; self.speed = 8 + Math.random() * 4; self.drift = (Math.random() - 0.5) * 2; } else if (weatherType === 'snow') { particleGraphics.alpha = 0.7 + Math.random() * 0.3; self.speed = 2 + Math.random() * 2; self.drift = (Math.random() - 0.5) * 4; self.floatOffset = Math.random() * Math.PI * 2; self.floatSpeed = 0.02 + Math.random() * 0.02; } self.update = function () { // Ensure self is properly defined with all required properties if (typeof self === 'undefined' || !self || typeof self.weatherType === 'undefined') return; if (typeof self.y === 'undefined' || typeof self.x === 'undefined') return; if (typeof self.speed === 'undefined' || typeof self.drift === 'undefined') return; if (self.weatherType === 'rain') { self.y += self.speed; self.x += self.drift; } else if (self.weatherType === 'snow') { self.y += self.speed; // Ensure required properties exist for snow movement if (typeof self.initialX !== 'undefined' && typeof self.floatSpeed !== 'undefined' && typeof self.floatOffset !== 'undefined') { self.x = self.initialX + Math.sin(LK.ticks * self.floatSpeed + self.floatOffset) * 30; } // Ensure particleGraphics exists before accessing rotation if (particleGraphics && typeof particleGraphics.rotation !== 'undefined') { particleGraphics.rotation += 0.01; } } // Reset particle when it goes off screen - ensure y property exists if (typeof self.y !== 'undefined' && self.y > 2780) { self.y = -50; self.x = Math.random() * 2048; self.initialX = self.x; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1B5E20 }); /**** * Game Code ****/ // Game state function _typeof2(o) { "@babel/helpers - typeof"; return _typeof2 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof2(o); } function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } var gameState = 'exploration'; // 'exploration' or 'haven' var currentBiome = 0; var biomes = ['Whispering Woods', 'Crystal Caverns', 'Serene Shoreline', 'Starfall Sanctuary']; var biomeColors = [0xd7e4bd, 0xe1bee7, 0xb2dfdb, 0xc5cae9]; var biomeMusicTracks = ['whisperingWoods', 'crystalCaverns', 'sereneShore', 'starfallSanctuary']; var currentMusicTrack = null; var musicFadeTime = 2000; // ASMR ambient sound tracking var currentAmbientSounds = []; var lastFootstepTime = 0; var footstepInterval = 800; // milliseconds between footsteps var biomeAmbientSounds = [['birdChirps', 'lightRain'], // Whispering Woods ['caveDrops', 'fireflies'], // Crystal Caverns ['streamMurmur', 'windChimes'], // Serene Shoreline ['fireflies', 'gentleFire'] // Starfall Sanctuary ]; // Initialize vignetteTypes array globally var vignetteTypes = ['mushroom', 'waterfall', 'bear']; // Player and game objects var player = new Player(); var auraParticles = []; var havenDecorations = []; var floatingParticles = []; var luminescentParticles = []; var rareBloom = null; var rareBloomTimer = 0; var rareBloomSpawnInterval = 1800; // 30 seconds at 60fps var ephemeralCreature = null; var ephemeralTimer = 0; var ephemeralSpawnInterval = 3600; // 60 seconds at 60fps var ephemeralCreatureTypes = ['fox', 'hummingbird', 'spirit']; var hiddenVignettes = []; var vignetteDiscoveryRadius = 120; // Weather system var currentWeather = 'clear'; // 'clear', 'rain', 'snow' var weatherParticles = []; var weatherTimer = 0; var weatherCheckInterval = 1800; // 30 seconds at 60fps var weatherDuration = 3600; // 60 seconds at 60fps var weatherEndTimer = 0; var isWeatherActive = false; // Water ripple system var waterRipples = []; var rippleTimer = 0; var rippleSpawnInterval = 900 + Math.random() * 1200; // 15-35 seconds at 60fps for extremely slow, infrequent ripples var maxActiveRipples = 3; // Zen moment system var zenMomentTimer = 0; var zenMomentInterval = 4500; // 75 seconds at 60fps of continuous activity var isZenMomentActive = false; var zenMomentDuration = 480; // 8 seconds at 60fps var zenMomentEndTimer = 0; var originalBackgroundTint = 0x000000; var zenAffirmations = ['Find your calm', 'Embrace tranquility', 'You are here', 'Breathe deeply', 'Peace flows through you', 'This moment is yours', 'Feel the serenity']; var zenText = null; // Tree sway system var treeSwayBranches = []; // Light shimmer system var lightShimmers = []; // Global light shimmer system for subtle ambiance var globalLightShimmer = null; var globalShimmerTimer = 0; var globalShimmerCycle = 600; // 10 seconds per full cycle (extremely slow) var globalShimmerIntensity = 0.05; // Very small amplitude change // Aura wisp system var auraWisps = []; var wispSpawnTimer = 0; var wispSpawnInterval = 120 + Math.random() * 180; // 2-5 seconds at 60fps var maxActiveWisps = 6; // Ephemeral shimmer particles var ephemeralShimmers = []; // Distant cloud system var distantClouds = []; // Rare bloom burst particles var rareBloomBursts = []; var biomeBackground = null; var havenBackground = null; // Aura collection tracking var auraCount = storage.auraCount || { green: 0, blue: 0, yellow: 0 }; var totalAuras = auraCount.green + auraCount.blue + auraCount.yellow; // UI elements var auraCountText = new Text2('Auras: ' + totalAuras, { size: 80, fill: 0xFFFFFF }); auraCountText.anchor.set(0.5, 0); var biomeText = new Text2(biomes[currentBiome], { size: 60, fill: 0xFFFFFF }); biomeText.anchor.set(0.5, 0); var havenButton = new Text2('Haven', { size: 70, fill: 0xFFEB3B }); havenButton.anchor.set(1, 0); var exploreButton = new Text2('Explore', { size: 70, fill: 0x4CAF50 }); exploreButton.anchor.set(0, 0); // Add UI to GUI LK.gui.top.addChild(auraCountText); LK.gui.top.addChild(biomeText); LK.gui.topRight.addChild(havenButton); LK.gui.topLeft.addChild(exploreButton); // Position UI elements auraCountText.y = 20; biomeText.y = 120; havenButton.x = -20; havenButton.y = 20; exploreButton.x = 120; exploreButton.y = 20; // Initialize game function initializeExploration() { gameState = 'exploration'; // Clear existing objects if (biomeBackground) biomeBackground.destroy(); if (havenBackground) havenBackground.destroy(); // Create biome background biomeBackground = game.addChild(LK.getAsset('biomeBackground', { anchorX: 0, anchorY: 0, x: 0, y: 0, tint: biomeColors[currentBiome] })); // Add player player.x = 1024; player.y = 1366; player.targetX = player.x; player.targetY = player.y; game.addChild(player); // Generate aura particles generateAuraParticles(); // Generate floating ambient particles generateFloatingParticles(); // Generate luminescent particles for magical atmosphere generateLuminescentParticles(); // Generate gentle tree sway for natural ambiance generateTreeSway(); // Generate subtle light shimmer for sky ambiance generateLightShimmer(); // Initialize global light shimmer for ambient lighting if (!globalLightShimmer) { globalLightShimmer = game.addChild(LK.getAsset('lightShimmer', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366, scaleX: 3.0, scaleY: 3.0, alpha: 0.03 })); globalLightShimmer.blendMode = 'multiply'; // Subtle overlay effect globalShimmerTimer = Math.random() * globalShimmerCycle; // Random start phase } // Generate distant clouds for background movement generateDistantClouds(); // Spawn hidden vignettes for discovery spawnHiddenVignettes(); // Reset rare bloom timer rareBloomTimer = Math.floor(Math.random() * rareBloomSpawnInterval); // Clear ephemeral creature if (ephemeralCreature) { ephemeralCreature.destroy(); ephemeralCreature = null; } // Reset ephemeral timer ephemeralTimer = Math.floor(Math.random() * ephemeralSpawnInterval); // Reset weather timer weatherTimer = Math.floor(Math.random() * weatherCheckInterval); // Reset zen moment timer zenMomentTimer = Math.floor(Math.random() * zenMomentInterval); // Reset water ripple timer rippleTimer = Math.floor(Math.random() * rippleSpawnInterval); // Reset aura wisp timer wispSpawnTimer = Math.floor(Math.random() * wispSpawnInterval); // Update UI biomeText.setText(biomes[currentBiome]); biomeText.visible = true; exploreButton.visible = false; havenButton.visible = true; // Play biome-specific music and ambient sounds playBiomeMusic(currentBiome); playAmbientSounds(currentBiome); } function initializeHaven() { gameState = 'haven'; // Clear existing objects if (biomeBackground) biomeBackground.destroy(); clearAuraParticles(); clearFloatingParticles(); clearLuminescentParticles(); clearHiddenVignettes(); // Clear rare bloom if (rareBloom) { rareBloom.destroy(); rareBloom = null; } // Clear ephemeral creature if (ephemeralCreature) { ephemeralCreature.destroy(); ephemeralCreature = null; } // Clear weather effects if (isWeatherActive) { endWeatherTransformation(); } // Clear zen moment if (isZenMomentActive) { endZenMoment(); } // Clear water ripples clearWaterRipples(); // Clear tree sway clearTreeSway(); // Clear light shimmer clearLightShimmer(); // Clear global light shimmer if (globalLightShimmer) { globalLightShimmer.destroy(); globalLightShimmer = null; } // Clear aura wisps clearAuraWisps(); // Clear ephemeral shimmers clearEphemeralShimmers(); // Clear distant clouds clearDistantClouds(); // Clear rare bloom bursts clearRareBloomBursts(); // Create haven background havenBackground = game.addChild(LK.getAsset('havenBackground', { anchorX: 0, anchorY: 0, x: 0, y: 0 })); // Remove player from haven if (player.parent) player.parent.removeChild(player); // Load existing decorations loadHavenDecorations(); // Update UI biomeText.visible = false; exploreButton.visible = true; havenButton.visible = false; // Stop exploration ambient sounds for (var i = 0; i < currentAmbientSounds.length; i++) { var sound = LK.getSound(currentAmbientSounds[i]); sound.loop = false; sound.stop(); } currentAmbientSounds = []; // Play haven ambient music playHavenMusic(); } function generateAuraParticles() { clearAuraParticles(); var particleCount = 15 + Math.floor(Math.random() * 10); var auraTypes = ['green', 'blue', 'yellow']; for (var i = 0; i < particleCount; i++) { var auraType = auraTypes[Math.floor(Math.random() * auraTypes.length)]; var aura = new AuraParticle(auraType); aura.x = 100 + Math.random() * 1848; aura.y = 200 + Math.random() * 2332; aura.initialY = aura.y; auraParticles.push(aura); game.addChild(aura); } } function clearAuraParticles() { for (var i = auraParticles.length - 1; i >= 0; i--) { auraParticles[i].destroy(); auraParticles.splice(i, 1); } } function generateFloatingParticles() { clearFloatingParticles(); var particleCount = 20 + Math.floor(Math.random() * 15); for (var i = 0; i < particleCount; i++) { var particle = new FloatingParticle(); particle.x = Math.random() * 2048; particle.y = Math.random() * 2732; particle.initialX = particle.x; floatingParticles.push(particle); game.addChild(particle); } } function clearFloatingParticles() { for (var i = floatingParticles.length - 1; i >= 0; i--) { floatingParticles[i].destroy(); floatingParticles.splice(i, 1); } } function generateLuminescentParticles() { clearLuminescentParticles(); // Low spawn rate for sparse, ethereal feel var particleCount = 8 + Math.floor(Math.random() * 6); for (var i = 0; i < particleCount; i++) { var particle = new LuminescentParticle(); // Focus particles over magical areas with sparse distribution var spawnArea = Math.random(); if (spawnArea < 0.3) { // Over water area (magical reflections) particle.x = 300 + Math.random() * 1448; particle.y = 1600 + Math.random() * 1000; } else if (spawnArea < 0.6) { // Near mystical trees/edges particle.x = Math.random() < 0.5 ? Math.random() * 250 : 1798 + Math.random() * 250; particle.y = 200 + Math.random() * 2200; } else { // Scattered throughout for ambient magic particle.x = Math.random() * 2048; particle.y = 200 + Math.random() * 2200; } particle.initialX = particle.x; luminescentParticles.push(particle); game.addChild(particle); } } function clearLuminescentParticles() { for (var i = luminescentParticles.length - 1; i >= 0; i--) { luminescentParticles[i].destroy(); luminescentParticles.splice(i, 1); } } function clearEphemeralShimmers() { for (var i = ephemeralShimmers.length - 1; i >= 0; i--) { ephemeralShimmers[i].destroy(); ephemeralShimmers.splice(i, 1); } } function generateDistantClouds() { clearDistantClouds(); // Sparse cloud coverage for background ambiance var cloudCount = 3 + Math.floor(Math.random() * 4); for (var i = 0; i < cloudCount; i++) { var cloud = new DistantCloud(); // Position clouds in upper portion of sky cloud.x = Math.random() * 2400; // Start some off-screen cloud.y = 100 + Math.random() * 400; // Upper sky area cloud.initialX = cloud.x; cloud.initialY = cloud.y; // Vary cloud sizes for depth var depthScale = 0.4 + Math.random() * 0.8; cloud.scaleX = depthScale; cloud.scaleY = depthScale; distantClouds.push(cloud); game.addChild(cloud); } } function clearDistantClouds() { for (var i = distantClouds.length - 1; i >= 0; i--) { distantClouds[i].destroy(); distantClouds.splice(i, 1); } } function clearRareBloomBursts() { for (var i = rareBloomBursts.length - 1; i >= 0; i--) { rareBloomBursts[i].destroy(); rareBloomBursts.splice(i, 1); } } function spawnRareBloom() { if (rareBloom) return; // Only one rare bloom at a time rareBloom = new RareAuraBloom(); rareBloom.x = 200 + Math.random() * 1648; rareBloom.y = 300 + Math.random() * 2132; rareBloom.initialY = rareBloom.y; game.addChild(rareBloom); // Play appearance sound LK.getSound('rareBloomAppear').play(); // Create burst of light effect LK.effects.flashScreen(0xffd700, 800); // Reset timer for next spawn rareBloomTimer = 0; } function spawnEphemeralCreature() { if (ephemeralCreature) return; // Only one ephemeral creature at a time var creatureType = ephemeralCreatureTypes[Math.floor(Math.random() * ephemeralCreatureTypes.length)]; ephemeralCreature = new EphemeralCreature(creatureType); // Position away from player for mystical discovery var playerDistance = 300 + Math.random() * 400; var angle = Math.random() * Math.PI * 2; ephemeralCreature.x = Math.max(100, Math.min(1948, player.x + Math.cos(angle) * playerDistance)); ephemeralCreature.y = Math.max(200, Math.min(2532, player.y + Math.sin(angle) * playerDistance)); ephemeralCreature.initialY = ephemeralCreature.y; game.addChild(ephemeralCreature); // Play gentle appearance sound LK.getSound('ephemeralAppear').play(); // Trigger appearance animation ephemeralCreature.appear(); // Reset timer for next spawn ephemeralTimer = Math.floor(Math.random() * ephemeralSpawnInterval) + ephemeralSpawnInterval; } function spawnHiddenVignettes() { clearHiddenVignettes(); // Always use a safe, guaranteed array - no dependency on global state var safeVignetteTypes = ['mushroom', 'waterfall', 'bear']; // Ensure vignetteTypes global is properly initialized with comprehensive safety checks if (typeof vignetteTypes === 'undefined' || !vignetteTypes || !Array.isArray(vignetteTypes) || vignetteTypes.length === 0) { vignetteTypes = ['mushroom', 'waterfall', 'bear']; } // Additional safety check to ensure safeVignetteTypes is properly defined if (!safeVignetteTypes || !Array.isArray(safeVignetteTypes) || safeVignetteTypes.length === 0) { safeVignetteTypes = ['mushroom', 'waterfall', 'bear']; return; } // Spawn 2-4 vignettes per biome in obscure corners var vignetteCount = 2 + Math.floor(Math.random() * 3); for (var i = 0; i < vignetteCount; i++) { // Triple safety check: ensure safeVignetteTypes is valid before any access if (!safeVignetteTypes || !Array.isArray(safeVignetteTypes) || safeVignetteTypes.length === 0) { return; } // Additional safety: ensure we have at least one valid element var hasValidElements = false; for (var checkIndex = 0; checkIndex < safeVignetteTypes.length; checkIndex++) { if (safeVignetteTypes[checkIndex] && typeof safeVignetteTypes[checkIndex] === 'string') { hasValidElements = true; break; } } // If no valid elements found, exit safely if (!hasValidElements) { return; } // Ensure array length is valid before generating random index if (safeVignetteTypes.length <= 0) { return; } // Always use safe array with guaranteed valid elements and bounds checking var randomIndex = Math.floor(Math.random() * safeVignetteTypes.length); // Ensure randomIndex is within bounds if (randomIndex < 0 || randomIndex >= safeVignetteTypes.length) { randomIndex = 0; // Default to first element as safe fallback } // Final safety check before array access - verify array and index are valid var vignetteType = 'mushroom'; // Safe default if (safeVignetteTypes && Array.isArray(safeVignetteTypes) && safeVignetteTypes.length > 0 && randomIndex >= 0 && randomIndex < safeVignetteTypes.length) { var selectedType = safeVignetteTypes[randomIndex]; if (selectedType && typeof selectedType === 'string') { vignetteType = selectedType; } } // Validate vignetteType before creating vignette if (!vignetteType || typeof vignetteType !== 'string') { vignetteType = 'mushroom'; // Safe default } // Create vignette with validated type var vignette = new HiddenVignette(vignetteType); // Position in obscure corners and edges of map var cornerPositions = [{ x: 150, y: 250 }, // Top-left corner { x: 1900, y: 250 }, // Top-right corner { x: 150, y: 2500 }, // Bottom-left corner { x: 1900, y: 2500 }, // Bottom-right corner { x: 1024, y: 150 }, // Top center hidden { x: 100, y: 1366 }, // Left edge hidden { x: 1948, y: 1366 }, // Right edge hidden { x: 1024, y: 2600 } // Bottom center hidden ]; // Ensure cornerPositions array is valid before access if (!cornerPositions || !Array.isArray(cornerPositions) || cornerPositions.length === 0) { continue; // Skip this iteration if positions array is invalid } var positionIndex = Math.floor(Math.random() * cornerPositions.length); if (positionIndex < 0 || positionIndex >= cornerPositions.length) { positionIndex = 0; // Safe fallback } var position = cornerPositions[positionIndex]; if (!position || _typeof2(position) !== 'object') { continue; // Skip if position is invalid } // Add some randomness to exact position vignette.x = position.x + (Math.random() - 0.5) * 200; vignette.y = position.y + (Math.random() - 0.5) * 200; // Ensure vignette stays within bounds vignette.x = Math.max(100, Math.min(1948, vignette.x)); vignette.y = Math.max(200, Math.min(2532, vignette.y)); hiddenVignettes.push(vignette); game.addChild(vignette); } } function clearHiddenVignettes() { for (var i = hiddenVignettes.length - 1; i >= 0; i--) { hiddenVignettes[i].destroy(); hiddenVignettes.splice(i, 1); } } function loadHavenDecorations() { var savedDecorations = storage.havenDecorations || []; for (var i = 0; i < savedDecorations.length; i++) { var decorationData = savedDecorations[i]; var decoration = new HavenDecoration(decorationData.type); decoration.x = decorationData.x; decoration.y = decorationData.y; havenDecorations.push(decoration); game.addChild(decoration); } } function saveHavenDecorations() { var decorationData = []; for (var i = 0; i < havenDecorations.length; i++) { var decoration = havenDecorations[i]; decorationData.push({ type: decoration.decorationType, x: decoration.x, y: decoration.y }); } storage.havenDecorations = decorationData; } function updateUI() { totalAuras = auraCount.green + auraCount.blue + auraCount.yellow; auraCountText.setText('Auras: ' + totalAuras); storage.auraCount = auraCount; } function playAmbientSounds(biomeIndex) { // Stop current ambient sounds for (var i = 0; i < currentAmbientSounds.length; i++) { var sound = LK.getSound(currentAmbientSounds[i]); sound.loop = false; sound.stop(); } currentAmbientSounds = []; // Start new ambient sounds for this biome var sounds = biomeAmbientSounds[biomeIndex]; for (var j = 0; j < sounds.length; j++) { var sound = LK.getSound(sounds[j]); sound.loop = true; sound.play(); currentAmbientSounds.push(sounds[j]); } } function playBiomeMusic(biomeIndex) { var targetTrack = biomeMusicTracks[biomeIndex]; if (currentMusicTrack === targetTrack) return; if (currentMusicTrack) { // Fade out current music LK.playMusic(currentMusicTrack, { fade: { start: 0.7, end: 0, duration: musicFadeTime } }); LK.setTimeout(function () { // Fade in new music LK.playMusic(targetTrack, { fade: { start: 0, end: 0.7, duration: musicFadeTime } }); currentMusicTrack = targetTrack; }, musicFadeTime); } else { // First time playing music LK.playMusic(targetTrack, { fade: { start: 0, end: 0.7, duration: musicFadeTime } }); currentMusicTrack = targetTrack; } } function startWeatherTransformation() { if (isWeatherActive || gameState !== 'exploration') return; // Small chance for weather (10% chance each check) if (Math.random() > 0.1) return; // Choose weather type (equal chance for rain or snow) var weatherTypes = ['rain', 'snow']; currentWeather = weatherTypes[Math.floor(Math.random() * weatherTypes.length)]; isWeatherActive = true; weatherEndTimer = 0; // Create weather particles generateWeatherParticles(); // Play weather ambient sound var soundName = currentWeather === 'rain' ? 'gentleRain' : 'softSnow'; var weatherSound = LK.getSound(soundName); weatherSound.loop = true; weatherSound.play(); currentAmbientSounds.push(soundName); // Gentle screen tint for weather atmosphere if (currentWeather === 'rain') { tween(biomeBackground, { tint: 0x8fa5c7 }, { duration: 3000, easing: tween.easeInOut }); } else if (currentWeather === 'snow') { tween(biomeBackground, { tint: 0xc8d6e5 }, { duration: 3000, easing: tween.easeInOut }); } } function endWeatherTransformation() { if (!isWeatherActive) return; isWeatherActive = false; clearWeatherParticles(); // Stop weather ambient sound var soundName = currentWeather === 'rain' ? 'gentleRain' : 'softSnow'; var weatherSound = LK.getSound(soundName); weatherSound.loop = false; weatherSound.stop(); var soundIndex = currentAmbientSounds.indexOf(soundName); if (soundIndex > -1) { currentAmbientSounds.splice(soundIndex, 1); } // Restore original biome tint if (biomeBackground) { tween(biomeBackground, { tint: biomeColors[currentBiome] }, { duration: 3000, easing: tween.easeInOut }); } currentWeather = 'clear'; weatherTimer = Math.floor(Math.random() * weatherCheckInterval); } function generateWeatherParticles() { clearWeatherParticles(); var particleCount = currentWeather === 'rain' ? 25 : 20; for (var i = 0; i < particleCount; i++) { var particle = new WeatherParticle(currentWeather); particle.x = Math.random() * 2200; // Slightly wider than screen particle.y = Math.random() * 2800; particle.initialX = particle.x; weatherParticles.push(particle); game.addChild(particle); } } function clearWeatherParticles() { for (var i = weatherParticles.length - 1; i >= 0; i--) { weatherParticles[i].destroy(); weatherParticles.splice(i, 1); } } function generateWaterRipple() { // Only spawn ripples in Serene Shoreline biome (index 2) if (currentBiome !== 2 || gameState !== 'exploration') return; // Limit number of active ripples var activeRipples = 0; for (var i = 0; i < waterRipples.length; i++) { if (waterRipples[i].isActive) activeRipples++; } if (activeRipples >= maxActiveRipples) return; // Find an inactive ripple to reuse, or create new one var ripple = null; for (var j = 0; j < waterRipples.length; j++) { if (!waterRipples[j].isActive) { ripple = waterRipples[j]; break; } } if (!ripple) { ripple = new WaterRipple(); waterRipples.push(ripple); game.addChild(ripple); } // Position ripple in lower half of screen (lake area) ripple.x = 300 + Math.random() * 1448; // Avoid edges ripple.y = 1500 + Math.random() * 800; // Lower half for lake // Start the ripple animation ripple.startRipple(); // Reset timer with some randomness rippleTimer = 0; rippleSpawnInterval = 900 + Math.random() * 1200; // Extremely slow ripple spawn timing } function clearWaterRipples() { for (var i = waterRipples.length - 1; i >= 0; i--) { waterRipples[i].destroy(); waterRipples.splice(i, 1); } } function generateTreeSway() { clearTreeSway(); var branchCount = 8 + Math.floor(Math.random() * 6); // 8-14 swaying branches for (var i = 0; i < branchCount; i++) { var branch = new TreeSwayBranch(); // Position trees in foreground (edges) and mid-ground areas var positionArea = Math.random(); if (positionArea < 0.3) { // Left foreground trees branch.x = 50 + Math.random() * 300; branch.y = 400 + Math.random() * 1800; } else if (positionArea < 0.6) { // Right foreground trees branch.x = 1700 + Math.random() * 300; branch.y = 400 + Math.random() * 1800; } else { // Mid-ground scattered trees branch.x = 300 + Math.random() * 1400; branch.y = 200 + Math.random() * 1200; } // Vary branch sizes for depth var depthScale = 0.6 + Math.random() * 0.8; branch.scaleX = depthScale; branch.scaleY = depthScale; // Start the gentle swaying animation branch.startSway(); treeSwayBranches.push(branch); game.addChild(branch); } } function clearTreeSway() { for (var i = treeSwayBranches.length - 1; i >= 0; i--) { treeSwayBranches[i].destroy(); treeSwayBranches.splice(i, 1); } } function generateLightShimmer() { clearLightShimmer(); // Create 1-3 light sources depending on biome (sun/moon/stars) var shimmerCount = 1 + Math.floor(Math.random() * 3); for (var i = 0; i < shimmerCount; i++) { var shimmer = new LightShimmer(); // Position light sources in upper portion of sky if (shimmerCount === 1) { // Single main light source (sun/moon) positioned in upper third shimmer.x = 800 + Math.random() * 400; // Center-ish area shimmer.y = 200 + Math.random() * 400; // Upper third } else { // Multiple light sources (stars, etc.) scattered in upper half shimmer.x = 200 + Math.random() * 1648; shimmer.y = 100 + Math.random() * 600; } // Vary shimmer sizes for depth and variety var sizeScale = 0.5 + Math.random() * 1.0; shimmer.scaleX = sizeScale; shimmer.scaleY = sizeScale; // Start the gentle shimmer breathing animation shimmer.startShimmer(); lightShimmers.push(shimmer); game.addChild(shimmer); } } function clearLightShimmer() { for (var i = lightShimmers.length - 1; i >= 0; i--) { lightShimmers[i].destroy(); lightShimmers.splice(i, 1); } } function generateAuraWisp() { if (gameState !== 'exploration') return; // Limit number of active wisps var activeWisps = 0; for (var i = 0; i < auraWisps.length; i++) { if (!auraWisps[i].collected) activeWisps++; } if (activeWisps >= maxActiveWisps) return; // Choose wisp type based on current biome preference var wispTypes = ['green', 'blue', 'yellow']; var wispType = wispTypes[Math.floor(Math.random() * wispTypes.length)]; var wisp = new AuraWisp(wispType); // Position wisp to emerge from environmental elements var emergenceLocations = [ // From under rocks (bottom edges) { x: 100 + Math.random() * 300, y: 2400 + Math.random() * 200 }, { x: 1600 + Math.random() * 300, y: 2400 + Math.random() * 200 }, // Near glowing mushrooms (mid areas) { x: 400 + Math.random() * 1200, y: 1200 + Math.random() * 800 }, // From within tree trunks (forest edges) { x: 50 + Math.random() * 200, y: 600 + Math.random() * 1200 }, { x: 1800 + Math.random() * 200, y: 600 + Math.random() * 1200 }, // From crystal formations (upper areas for crystal caverns) { x: 300 + Math.random() * 1400, y: 300 + Math.random() * 600 }]; var location = emergenceLocations[Math.floor(Math.random() * emergenceLocations.length)]; // Add some randomness to exact position wisp.x = location.x + (Math.random() - 0.5) * 100; wisp.y = location.y + (Math.random() - 0.5) * 100; wisp.initialY = wisp.y; // Ensure wisp stays within bounds wisp.x = Math.max(50, Math.min(1998, wisp.x)); wisp.y = Math.max(200, Math.min(2532, wisp.y)); auraWisps.push(wisp); game.addChild(wisp); // Reset timer with some randomness wispSpawnTimer = 0; wispSpawnInterval = 120 + Math.random() * 180; } function clearAuraWisps() { for (var i = auraWisps.length - 1; i >= 0; i--) { auraWisps[i].destroy(); auraWisps.splice(i, 1); } } function triggerZenMoment() { if (isZenMomentActive || gameState !== 'exploration') return; isZenMomentActive = true; zenMomentEndTimer = 0; // Store original background tint if (biomeBackground) { originalBackgroundTint = biomeBackground.tint; // Subtle desaturation effect tween(biomeBackground, { tint: 0xb0b0b0 }, { duration: 2000, easing: tween.easeInOut }); } // Create zen affirmation text var affirmation = zenAffirmations[Math.floor(Math.random() * zenAffirmations.length)]; zenText = new Text2(affirmation, { size: 120, fill: 0xffffff }); zenText.anchor.set(0.5, 0.5); zenText.alpha = 0; // Position zen text in center LK.gui.center.addChild(zenText); // Gentle fade in for zen text - ensure zenText exists before tweening if (zenText) { tween(zenText, { alpha: 0.9, scaleX: 1.1, scaleY: 1.1 }, { duration: 1500, easing: tween.easeOut, onFinish: function onFinish() { // Gentle pulsing while displayed - check zenText still exists if (zenText) { tween(zenText, { alpha: 0.7, scaleX: 1.0, scaleY: 1.0 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { if (zenText) { tween(zenText, { alpha: 0.9, scaleX: 1.1, scaleY: 1.1 }, { duration: 1000, easing: tween.easeInOut }); } } }); } } }); } // Play gentle zen bell sound LK.getSound('zenMomentBell').play(); // Play zen moment music (very minimalistic) var currentVolume = 0.7; if (currentMusicTrack) { // Fade current music to lower volume LK.playMusic(currentMusicTrack, { fade: { start: currentVolume, end: 0.2, duration: 1500 } }); } // Start zen music softly LK.playMusic('zenMomentMusic', { fade: { start: 0, end: 0.3, duration: 1500 } }); } function endZenMoment() { if (!isZenMomentActive) return; isZenMomentActive = false; // Fade out zen text if (zenText && zenText.parent) { tween(zenText, { alpha: 0, scaleX: 0.8, scaleY: 0.8 }, { duration: 2000, easing: tween.easeIn, onFinish: function onFinish() { if (zenText && zenText.parent) { zenText.parent.removeChild(zenText); } zenText = null; } }); } else if (zenText) { // If zenText exists but has no parent, just set to null zenText = null; } // Restore original background tint if (biomeBackground) { tween(biomeBackground, { tint: originalBackgroundTint }, { duration: 2000, easing: tween.easeInOut }); } // Restore original music LK.playMusic('zenMomentMusic', { fade: { start: 0.3, end: 0, duration: 1500 } }); LK.setTimeout(function () { if (currentMusicTrack && currentMusicTrack !== 'zenMomentMusic') { LK.playMusic(currentMusicTrack, { fade: { start: 0.2, end: 0.7, duration: 1500 } }); } }, 1500); // Reset timer for next zen moment zenMomentTimer = Math.floor(Math.random() * zenMomentInterval) + zenMomentInterval; } function playHavenMusic() { if (currentMusicTrack === 'havenAmbient') return; if (currentMusicTrack) { // Fade out current music var prevTrack = currentMusicTrack; LK.playMusic(prevTrack, { fade: { start: 0.7, end: 0, duration: musicFadeTime } }); LK.setTimeout(function () { // Fade in haven music LK.playMusic('havenAmbient', { fade: { start: 0, end: 0.6, duration: musicFadeTime } }); currentMusicTrack = 'havenAmbient'; }, musicFadeTime); } else { // First time playing music LK.playMusic('havenAmbient', { fade: { start: 0, end: 0.6, duration: musicFadeTime } }); currentMusicTrack = 'havenAmbient'; } } // Touch/Mouse handlers var draggedDecoration = null; var isPlacingDecoration = false; game.move = function (x, y, obj) { if (gameState === 'exploration') { player.targetX = x; player.targetY = y; } else if (gameState === 'haven' && draggedDecoration) { draggedDecoration.x = x; draggedDecoration.y = y; } }; game.down = function (x, y, obj) { if (gameState === 'haven') { // Check if touching a decoration for (var i = 0; i < havenDecorations.length; i++) { var decoration = havenDecorations[i]; var dx = x - decoration.x; var dy = y - decoration.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 60) { draggedDecoration = decoration; // Play rustle sound for plant interactions if (decoration.decorationType === 'plant') { LK.getSound('plantRustle').play(); } break; } } // Try to place new decoration if not dragging if (!draggedDecoration && totalAuras >= 10) { var decorationTypes = ['plant', 'light', 'water']; var randomType = decorationTypes[Math.floor(Math.random() * decorationTypes.length)]; var newDecoration = new HavenDecoration(randomType); newDecoration.x = x; newDecoration.y = y; havenDecorations.push(newDecoration); game.addChild(newDecoration); auraCount.green = Math.max(0, auraCount.green - 4); auraCount.blue = Math.max(0, auraCount.blue - 3); auraCount.yellow = Math.max(0, auraCount.yellow - 3); updateUI(); saveHavenDecorations(); LK.getSound('placeItem').play(); } } }; game.up = function (x, y, obj) { if (draggedDecoration) { saveHavenDecorations(); draggedDecoration = null; } }; // Button handlers havenButton.down = function (x, y, obj) { if (gameState === 'exploration') { initializeHaven(); } }; exploreButton.down = function (x, y, obj) { if (gameState === 'haven') { initializeExploration(); } }; // Main game update loop game.update = function () { if (gameState === 'exploration') { // Check rare bloom spawning rareBloomTimer++; if (rareBloomTimer >= rareBloomSpawnInterval && !rareBloom) { spawnRareBloom(); } // Check ephemeral creature spawning ephemeralTimer++; if (ephemeralTimer >= ephemeralSpawnInterval && !ephemeralCreature) { spawnEphemeralCreature(); } // Check weather transformations weatherTimer++; if (weatherTimer >= weatherCheckInterval && !isWeatherActive) { startWeatherTransformation(); } // Check zen moment triggering zenMomentTimer++; if (zenMomentTimer >= zenMomentInterval && !isZenMomentActive) { triggerZenMoment(); } // Check water ripple spawning (only in Serene Shoreline) if (currentBiome === 2) { rippleTimer++; if (rippleTimer >= rippleSpawnInterval) { generateWaterRipple(); } } // Check aura wisp spawning wispSpawnTimer++; if (wispSpawnTimer >= wispSpawnInterval) { generateAuraWisp(); } // Update global light shimmer with extremely slow pulse if (globalLightShimmer) { globalShimmerTimer++; // Extremely slow rhythmic pulse - full cycle over several seconds var shimmerCycle = Math.sin(globalShimmerTimer / globalShimmerCycle * Math.PI * 2); // Very gentle fluctuation in brightness - barely noticeable var baseAlpha = 0.03; var alphaVariation = shimmerCycle * globalShimmerIntensity; globalLightShimmer.alpha = baseAlpha + alphaVariation; // Subtle scale variation for breathing effect var baseScale = 3.0; var scaleVariation = shimmerCycle * 0.02; // Very minimal scale change globalLightShimmer.scaleX = baseScale + scaleVariation; globalLightShimmer.scaleY = baseScale + scaleVariation; // Very slow rotation for natural light movement globalLightShimmer.rotation += 0.0001; // Reset timer to prevent overflow if (globalShimmerTimer >= globalShimmerCycle * 100) { globalShimmerTimer = 0; } } // Clean up collected wisps for (var w = auraWisps.length - 1; w >= 0; w--) { if (auraWisps[w].collected) { auraWisps.splice(w, 1); } } // Clean up expired ephemeral shimmers for (var s = ephemeralShimmers.length - 1; s >= 0; s--) { if (!ephemeralShimmers[s].parent) { ephemeralShimmers.splice(s, 1); } } // Clean up expired rare bloom burst particles for (var b = rareBloomBursts.length - 1; b >= 0; b--) { if (!rareBloomBursts[b].parent) { rareBloomBursts.splice(b, 1); } } // Check zen moment duration if (isZenMomentActive) { zenMomentEndTimer++; if (zenMomentEndTimer >= zenMomentDuration) { endZenMoment(); } } // Check weather duration if (isWeatherActive) { weatherEndTimer++; if (weatherEndTimer >= weatherDuration) { endWeatherTransformation(); } } // Check hidden vignette discovery for (var v = 0; v < hiddenVignettes.length; v++) { var vignette = hiddenVignettes[v]; if (!vignette.discovered) { var dx = player.x - vignette.x; var dy = player.y - vignette.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < vignetteDiscoveryRadius) { vignette.discover(); } } } // Check rare bloom collection if (rareBloom && !rareBloom.collected && player.intersects(rareBloom)) { rareBloom.collected = true; // Award significant auras (5 of each type) auraCount.green += 5; auraCount.blue += 5; auraCount.yellow += 5; updateUI(); // Play special collection sound LK.getSound('rareBloomCollect').play(); // Create spectacular visual effect LK.effects.flashScreen(0xffd700, 1500); // Create burst of glowing particles (medium count for spectacular effect) for (var b = 0; b < 12; b++) { var burstParticle = new RareBloomBurst(); burstParticle.x = rareBloom.x; burstParticle.y = rareBloom.y; rareBloomBursts.push(burstParticle); game.addChild(burstParticle); } // Burst animation with swirl of particles tween(rareBloom, { scaleX: 3.0, scaleY: 3.0, alpha: 1.0 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { tween(rareBloom, { scaleX: 0, scaleY: 0, alpha: 0 }, { duration: 800, easing: tween.easeInOut, onFinish: function onFinish() { rareBloom.destroy(); rareBloom = null; // Reset timer for next rare bloom rareBloomTimer = Math.floor(Math.random() * rareBloomSpawnInterval); } }); } }); } // Check aura collection for (var i = auraParticles.length - 1; i >= 0; i--) { var aura = auraParticles[i]; if (!aura.collected && player.intersects(aura)) { aura.collected = true; auraCount[aura.type]++; updateUI(); // Collect animation with gentle glow effect tween(aura, { scaleX: 2.0, scaleY: 2.0, alpha: 1.0 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(aura, { scaleX: 0, scaleY: 0, alpha: 0 }, { duration: 400, easing: tween.easeInOut, onFinish: function onFinish() { aura.destroy(); } }); } }); auraParticles.splice(i, 1); LK.getSound('collectAura').play(); } } // Check if all auras collected if (auraParticles.length === 0) { LK.setTimeout(function () { currentBiome = (currentBiome + 1) % biomes.length; generateAuraParticles(); // Update biome display and music biomeText.setText(biomes[currentBiome]); if (biomeBackground) { biomeBackground.tint = biomeColors[currentBiome]; } playBiomeMusic(currentBiome); playAmbientSounds(currentBiome); }, 1000); } } }; // Start the game initializeExploration();
===================================================================
--- original.js
+++ change.js
@@ -1048,8 +1048,16 @@
/****
* Game Code
****/
// Game state
+function _typeof2(o) {
+ "@babel/helpers - typeof";
+ return _typeof2 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
+ return typeof o;
+ } : function (o) {
+ return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
+ }, _typeof2(o);
+}
function _typeof(o) {
"@babel/helpers - typeof";
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
return typeof o;
@@ -1470,15 +1478,16 @@
}
// Additional safety check to ensure safeVignetteTypes is properly defined
if (!safeVignetteTypes || !Array.isArray(safeVignetteTypes) || safeVignetteTypes.length === 0) {
safeVignetteTypes = ['mushroom', 'waterfall', 'bear'];
+ return;
}
// Spawn 2-4 vignettes per biome in obscure corners
var vignetteCount = 2 + Math.floor(Math.random() * 3);
for (var i = 0; i < vignetteCount; i++) {
// Triple safety check: ensure safeVignetteTypes is valid before any access
if (!safeVignetteTypes || !Array.isArray(safeVignetteTypes) || safeVignetteTypes.length === 0) {
- safeVignetteTypes = ['mushroom', 'waterfall', 'bear'];
+ return;
}
// Additional safety: ensure we have at least one valid element
var hasValidElements = false;
for (var checkIndex = 0; checkIndex < safeVignetteTypes.length; checkIndex++) {
@@ -1486,22 +1495,29 @@
hasValidElements = true;
break;
}
}
- // If no valid elements found, reinitialize with safe defaults
+ // If no valid elements found, exit safely
if (!hasValidElements) {
- safeVignetteTypes = ['mushroom', 'waterfall', 'bear'];
+ return;
}
+ // Ensure array length is valid before generating random index
+ if (safeVignetteTypes.length <= 0) {
+ return;
+ }
// Always use safe array with guaranteed valid elements and bounds checking
var randomIndex = Math.floor(Math.random() * safeVignetteTypes.length);
// Ensure randomIndex is within bounds
if (randomIndex < 0 || randomIndex >= safeVignetteTypes.length) {
randomIndex = 0; // Default to first element as safe fallback
}
- // Final safety check before array access
+ // Final safety check before array access - verify array and index are valid
var vignetteType = 'mushroom'; // Safe default
- if (safeVignetteTypes && Array.isArray(safeVignetteTypes) && randomIndex >= 0 && randomIndex < safeVignetteTypes.length && safeVignetteTypes[randomIndex]) {
- vignetteType = safeVignetteTypes[randomIndex];
+ if (safeVignetteTypes && Array.isArray(safeVignetteTypes) && safeVignetteTypes.length > 0 && randomIndex >= 0 && randomIndex < safeVignetteTypes.length) {
+ var selectedType = safeVignetteTypes[randomIndex];
+ if (selectedType && typeof selectedType === 'string') {
+ vignetteType = selectedType;
+ }
}
// Validate vignetteType before creating vignette
if (!vignetteType || typeof vignetteType !== 'string') {
vignetteType = 'mushroom'; // Safe default
@@ -1548,9 +1564,20 @@
x: 1024,
y: 2600
} // Bottom center hidden
];
- var position = cornerPositions[Math.floor(Math.random() * cornerPositions.length)];
+ // Ensure cornerPositions array is valid before access
+ if (!cornerPositions || !Array.isArray(cornerPositions) || cornerPositions.length === 0) {
+ continue; // Skip this iteration if positions array is invalid
+ }
+ var positionIndex = Math.floor(Math.random() * cornerPositions.length);
+ if (positionIndex < 0 || positionIndex >= cornerPositions.length) {
+ positionIndex = 0; // Safe fallback
+ }
+ var position = cornerPositions[positionIndex];
+ if (!position || _typeof2(position) !== 'object') {
+ continue; // Skip if position is invalid
+ }
// Add some randomness to exact position
vignette.x = position.x + (Math.random() - 0.5) * 200;
vignette.y = position.y + (Math.random() - 0.5) * 200;
// Ensure vignette stays within bounds
auraBlue top view. In-Game asset. 2d. High contrast. No shadows
auraGreen top view. In-Game asset. 2d. High contrast. No shadows
auraWisp top view. In-Game asset. 2d. High contrast. No shadows
auraYellow top view. In-Game asset. 2d. High contrast. No shadows
biomeBackground top view. In-Game asset. 2d. High contrast. No shadows
distantCloud top view. In-Game asset. 2d. High contrast. No shadows
waterRipple top view. In-Game asset. 2d. High contrast. No shadows
waterDecoration top view. In-Game asset. 2d. High contrast. No shadows
tree Sway Branch top view. In-Game asset. 2d. High contrast. No shadows
rare Bloom Pulse top view. In-Game asset. 2d. High contrast. No shadows
snow Flake top view. In-Game asset. 2d. High contrast. No shadows
rare Bloom Burst Particle top view. In-Game asset. 2d. High contrast. No shadows
rare Bloom Burst top view. In-Game asset. 2d. High contrast. No shadows
sleeping Bear top view. In-Game asset. 2d. High contrast. No shadows
rare Aura Bloom top view. In-Game asset. 2d. High contrast. No shadows
raindrops. In-Game asset. 2d. High contrast. No shadows
light Shimmer top view. In-Game asset. 2d. High contrast. No shadows
light Decoration top view. In-Game asset. 2d. High contrast. No shadows
hiddenWaterfall. In-Game asset. 2d. High contrast. No shadows
havenBackground. In-Game asset. 2d. High contrast. No shadows
floatingParticle. In-Game asset. 2d. High contrast. No shadows
ephemeralHummingbird. In-Game asset. 2d. High contrast. No shadows
ephemeralFox. In-Game asset. 2d. High contrast. No shadows
ephemeralSpirit. In-Game asset. 2d. High contrast. No shadows
ephemeralShimmer. In-Game asset. 2d. High contrast. No shadows
plantDecoration. In-Game asset. 2d. High contrast. No shadows
mushroomRing. In-Game asset. 2d. High contrast. No shadows
luminescentParticleAlt. In-Game asset. 2d. High contrast. No shadows
luminescentParticle. In-Game asset. 2d. High contrast. No shadows
player aura image top view in space game.