User prompt
make the tutorial more understable
User prompt
fix the all assets hitbox
User prompt
In some levels, when we select one of the particles in dimension 0, the particle in dimension 2 moves with it. fix this error
User prompt
in someIn some levels, when we select one of the particles in dimension 0, the particle in dimension 2 moves with it.
User prompt
particle hit box not working probly
User prompt
tutorial not working probly
User prompt
fix the levels after level 5
User prompt
fix the levels particle errors
User prompt
tutorial not working probly
User prompt
make the game little bit easyer
User prompt
make the interference Field assets brighter
User prompt
make the assets more visibly
User prompt
tutorial not working probly
User prompt
make the tutorial more educational
User prompt
i want a add a tutorial level at the start
User prompt
powerups not working probly
User prompt
fix the powerups spawn time
User prompt
when choosing particle in the dimension other dimensions particle following it too
User prompt
dimensions not workin
User prompt
when the pick up powerups tell the specs
User prompt
cant use powerups
User prompt
add more level
User prompt
fix the all hitbox
User prompt
fix the particle hit box
User prompt
some time interferencefield not working correctly
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var BackgroundStar = Container.expand(function () { var self = Container.call(this); var starGraphics = self.attachAsset('star', { anchorX: 0.5, anchorY: 0.5 }); self.twinkleSpeed = 0.02 + Math.random() * 0.03; self.twinkleOffset = Math.random() * Math.PI * 2; self.baseAlpha = 0.3 + Math.random() * 0.7; self.update = function () { // Direct property updates instead of creating tweens every frame var twinkle = Math.sin(LK.ticks * self.twinkleSpeed + self.twinkleOffset) * 0.3 + 0.7; self.alpha = self.baseAlpha * twinkle; // Direct position updates for smooth movement self.x += Math.sin(LK.ticks * 0.01 + self.twinkleOffset) * 0.02; self.y += Math.cos(LK.ticks * 0.008 + self.twinkleOffset) * 0.015; }; return self; }); var InterferenceField = Container.expand(function () { var self = Container.call(this); var fieldGraphics = self.attachAsset('interferenceField', { anchorX: 0.5, anchorY: 0.5, tint: 0xff4444 }); self.dimension = 0; self.pulseDirection = 1; self.setDimension = function (dim) { self.dimension = dim; self.alpha = 0.8; }; self.update = function () { // Direct rotation update fieldGraphics.rotation += 0.015; // Direct alpha updates instead of creating tweens every frame if (self.dimension === currentDimension) { self.alpha = 0.9 + Math.sin(LK.ticks * 0.05) * 0.3; // Add bright glow effect with color cycling var glowIntensity = Math.sin(LK.ticks * 0.08) * 0.5 + 0.5; fieldGraphics.tint = 0xff0000 + Math.floor(glowIntensity * 0x4444); } else { self.alpha = 0.4; fieldGraphics.tint = 0xff4444; } // Direct position updates for moving fields - reduced speeds for easier gameplay if (self.moveDirection !== undefined) { var moveSpeed = 2.5; // Reduced from 4 to 2.5 // Increase speed for level 8+ if (level >= 8) { moveSpeed = 3.5; // Reduced from 6 to 3.5 } // Ultra-fast speed for level 16+ if (level >= 16) { moveSpeed = 5; // Reduced from 9 to 5 } // Extreme speed for level 11+ if (level >= 11) { moveSpeed = 4; // Reduced from 7 to 4 } self.x += self.moveDirection * moveSpeed; if (self.x <= self.minX || self.x >= self.maxX) { self.moveDirection *= -1; } } }; return self; }); var Particle = Container.expand(function () { var self = Container.call(this); var particleGraphics = self.attachAsset('particle', { anchorX: 0.5, anchorY: 0.5 }); self.dimension = 0; self.originalPosition = { x: 0, y: 0 }; self.isBeingDragged = false; self.isCollected = false; self.entangledWith = null; self.setDimension = function (dim) { self.dimension = dim; self.alpha = 1.0; }; self.startDrag = function () { self.isBeingDragged = true; tween(particleGraphics, { scaleX: 1.2, scaleY: 1.2 }, { duration: 200 }); }; self.stopDrag = function () { self.isBeingDragged = false; tween(particleGraphics, { scaleX: 1.0, scaleY: 1.0 }, { duration: 200 }); }; self.collect = function () { self.isCollected = true; // Enhanced collection animation with bounce effect tween(self, { scaleX: 1.5, scaleY: 1.5 }, { duration: 150, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { alpha: 0, scaleX: 0.1, scaleY: 0.1 }, { duration: 200, easing: tween.easeIn, onFinish: function onFinish() { self.visible = false; } }); } }); // Tutorial step progression for particle collection if (isTutorial) { if (tutorialStep === 1 || tutorialStep === 2) { tutorialStep = 2; LK.setTimeout(function () { updateTutorialStep(); }, 1000); } else if (tutorialStep === 5) { tutorialStep = 6; LK.setTimeout(function () { updateTutorialStep(); }, 1000); } } }; self.update = function () { if (self.isCollected) return; // Initialize collision tracking if (self.lastCoreIntersecting === undefined) { self.lastCoreIntersecting = false; } // Check collision with quantum core - only trigger on first contact var currentCoreIntersecting = false; if (self.dimension === currentDimension && quantumCore) { // Use actual asset dimensions for accurate collision detection var particleHalfWidth = particleGraphics.width / 2; // Use actual particle asset width var particleHalfHeight = particleGraphics.height / 2; // Use actual particle asset height var coreHalfWidth = quantumCore.width / 2; // Use actual quantum core asset width var coreHalfHeight = quantumCore.height / 2; // Use actual quantum core asset height currentCoreIntersecting = Math.abs(self.x - quantumCore.x) < particleHalfWidth + coreHalfWidth && Math.abs(self.y - quantumCore.y) < particleHalfHeight + coreHalfHeight; } if (!self.lastCoreIntersecting && currentCoreIntersecting) { self.collect(); LK.getSound('collectSound').play(); particlesCollected++; checkWinCondition(); } self.lastCoreIntersecting = currentCoreIntersecting; // Check collision with interference fields for (var i = 0; i < interferenceFields.length; i++) { var field = interferenceFields[i]; if (field.dimension === self.dimension) { // Use actual asset dimensions for accurate collision detection var particleHalfWidth = particleGraphics.width / 2; // Use actual particle asset width var particleHalfHeight = particleGraphics.height / 2; // Use actual particle asset height var fieldHalfWidth = field.children[0].width / 2; // Use actual interference field asset width var fieldHalfHeight = field.children[0].height / 2; // Use actual interference field asset height var isColliding = Math.abs(self.x - field.x) < particleHalfWidth + fieldHalfWidth && Math.abs(self.y - field.y) < particleHalfHeight + fieldHalfHeight; if (isColliding) { if (isTutorial) { // In tutorial, just show educational message instead of resetting if (tutorialStep >= 7) { tutorialText.setText('You touched an interference field!\nIn real levels, this would reset the level.'); LK.effects.flashObject(self, 0xff0000, 500); } } else { resetLevel(); return; } } } } // Handle entanglement if (self.entangledWith && !self.isBeingDragged && self.entangledWith.isBeingDragged) { self.x = self.entangledWith.x + 150; self.y = self.entangledWith.y; // Maintain proper alpha based on current dimension var targetAlpha = self.dimension === currentDimension ? 1.0 : 0.15; self.alpha = targetAlpha; } }; self.down = function (x, y, obj) { // Drag handling is now managed by game.down event handler }; return self; }); var Portal = Container.expand(function () { var self = Container.call(this); var portalGraphics = self.attachAsset('portal', { anchorX: 0.5, anchorY: 0.5 }); self.dimension = 0; self.targetDimension = 1; self.setDimension = function (dim) { self.dimension = dim; self.alpha = 1.0; }; self.update = function () { // Direct rotation update portalGraphics.rotation += 0.02; // Check if particles are transported through portal for (var i = 0; i < particles.length; i++) { var particle = particles[i]; if (particle.dimension === self.dimension && !particle.isBeingDragged) { // Use actual asset dimensions for accurate collision detection var portalHalfWidth = portalGraphics.width / 2; // Use actual portal asset width var portalHalfHeight = portalGraphics.height / 2; // Use actual portal asset height var particleHalfWidth = particle.children[0].width / 2; // Use actual particle asset width var particleHalfHeight = particle.children[0].height / 2; // Use actual particle asset height var isColliding = Math.abs(self.x - particle.x) < portalHalfWidth + particleHalfWidth && Math.abs(self.y - particle.y) < portalHalfHeight + particleHalfHeight; if (isColliding) { particle.setDimension(self.targetDimension); LK.getSound('portalSound').play(); LK.effects.flashObject(self, 0xffffff, 300); } } } }; return self; }); var PowerUp = Container.expand(function () { var self = Container.call(this); self.type = 'timeBoost'; // Default type self.dimension = 0; self.isCollected = false; self.powerUpGraphics = null; self.floatOffset = Math.random() * Math.PI * 2; self.floatSpeed = 0.02 + Math.random() * 0.01; self.glowDirection = 1; self.glowIntensity = 1.0; self.setType = function (type) { self.type = type; if (self.powerUpGraphics) { self.powerUpGraphics.destroy(); } var assetName = type === 'timeBoost' ? 'timeBoost' : type === 'shield' ? 'shieldPower' : 'slowMotion'; self.powerUpGraphics = self.attachAsset(assetName, { anchorX: 0.5, anchorY: 0.5 }); }; self.setDimension = function (dim) { self.dimension = dim; self.alpha = 1.0; }; self.collect = function () { self.isCollected = true; LK.getSound('powerUpSound').play(); // Collect animation with burst effect tween(self, { scaleX: 2.0, scaleY: 2.0, alpha: 0 }, { duration: 400, easing: tween.easeOut, onFinish: function onFinish() { self.visible = false; } }); // Apply power-up effect self.applyEffect(); }; self.applyEffect = function () { if (self.type === 'timeBoost') { timeRemaining += 15000; // Add 15 seconds (increased from 10) LK.effects.flashScreen(0x00ff00, 300); showPowerUpSpec('TIME BOOST', '+15 seconds', 0x00ff00); } else if (self.type === 'shield') { shieldActive = true; shieldTimeRemaining = 12000; // 12 seconds of shield (increased from 8) LK.effects.flashScreen(0x0088ff, 300); showPowerUpSpec('SHIELD', '12 seconds protection', 0x0088ff); } else if (self.type === 'slowMotion') { slowMotionActive = true; slowMotionTimeRemaining = 10000; // 10 seconds of slow motion (increased from 6) LK.effects.flashScreen(0xff8800, 300); showPowerUpSpec('SLOW MOTION', '10 seconds effect', 0xff8800); } }; self.update = function () { if (self.isCollected) return; // Initialize collision tracking if (self.lastPlayerIntersecting === undefined) { self.lastPlayerIntersecting = false; } // Floating animation self.y += Math.sin(LK.ticks * self.floatSpeed + self.floatOffset) * 0.5; // Glow effect self.glowIntensity += self.glowDirection * 0.02; if (self.glowIntensity > 1.3) { self.glowIntensity = 1.3; self.glowDirection = -1; } else if (self.glowIntensity < 0.7) { self.glowIntensity = 0.7; self.glowDirection = 1; } self.scaleX = self.glowIntensity; self.scaleY = self.glowIntensity; // Rotation for visual appeal if (self.powerUpGraphics) { self.powerUpGraphics.rotation += 0.03; } // Update visibility based on current dimension var targetAlpha = self.dimension === currentDimension ? self.glowIntensity : 0.15; if (Math.abs(self.alpha - targetAlpha) > 0.05) { self.alpha = targetAlpha; } // Check collision with all particles in current dimension var currentPlayerIntersecting = false; for (var p = 0; p < particles.length; p++) { var particle = particles[p]; if (particle.dimension === self.dimension && particle.dimension === currentDimension && !particle.isCollected) { // Use actual asset dimensions for accurate collision detection var powerUpHalfWidth = self.powerUpGraphics.width / 2; // Use actual power-up asset width var powerUpHalfHeight = self.powerUpGraphics.height / 2; // Use actual power-up asset height var particleHalfWidth = particle.children[0].width / 2; // Use actual particle asset width var particleHalfHeight = particle.children[0].height / 2; // Use actual particle asset height var isColliding = Math.abs(self.x - particle.x) < powerUpHalfWidth + particleHalfWidth && Math.abs(self.y - particle.y) < powerUpHalfHeight + particleHalfHeight; if (isColliding) { currentPlayerIntersecting = true; break; } } } if (!self.lastPlayerIntersecting && currentPlayerIntersecting) { self.collect(); } self.lastPlayerIntersecting = currentPlayerIntersecting; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000033 }); /**** * Game Code ****/ var currentDimension = 0; var totalDimensions = 2; var particles = []; var portals = []; var interferenceFields = []; var quantumCore; var draggedParticle = null; var dragOffset = { x: 0, y: 0 }; var particlesCollected = 0; var totalParticles = 0; var level = 0; // Start with tutorial level (level 0) var timeLimit = 25000; // 25 seconds in milliseconds var timeRemaining = timeLimit; var timerActive = false; var dimensionSwitches = 0; var maxDimensionSwitches = 5; var backgroundStars = []; var powerUps = []; var shieldActive = false; var shieldTimeRemaining = 0; var slowMotionActive = false; var slowMotionTimeRemaining = 0; var powerUpSpawnTimer = 0; var powerUpSpawnInterval = 8000; // Spawn power-up every 8 seconds var isTutorial = true; var tutorialStep = 0; var tutorialComplete = false; var tutorialText = null; // UI Elements var dimensionText = new Text2('Dimension: 0', { size: 60, fill: 0xFFFFFF }); dimensionText.anchor.set(0.5, 0); LK.gui.top.addChild(dimensionText); var levelText = new Text2('Level: 1', { size: 50, fill: 0xFFFFFF }); levelText.anchor.set(0.5, 0); levelText.y = 100; LK.gui.top.addChild(levelText); var instructionText = new Text2('Tap to switch dimensions', { size: 40, fill: 0xCCCCCC }); instructionText.anchor.set(0.5, 1); LK.gui.bottom.addChild(instructionText); var timerText = new Text2('Time: 25s', { size: 50, fill: 0xFFFFFF }); timerText.anchor.set(0.5, 0); timerText.y = 160; LK.gui.top.addChild(timerText); var shieldText = new Text2('SHIELD ACTIVE', { size: 45, fill: 0x0088ff }); shieldText.anchor.set(0.5, 0); shieldText.y = 220; shieldText.visible = false; LK.gui.top.addChild(shieldText); var slowMotionText = new Text2('SLOW MOTION', { size: 45, fill: 0xff8800 }); slowMotionText.anchor.set(0.5, 0); slowMotionText.y = 280; slowMotionText.visible = false; LK.gui.top.addChild(slowMotionText); // Tutorial text tutorialText = new Text2('Welcome to Quantum Dimensions!', { size: 50, fill: 0x00ff88 }); tutorialText.anchor.set(0.5, 0.5); tutorialText.x = 1024; tutorialText.y = 400; tutorialText.visible = false; game.addChild(tutorialText); // Create dimension indicators var dimensionIndicators = []; for (var d = 0; d < totalDimensions; d++) { var indicator = LK.getAsset('dimensionIndicator', { anchorX: 0.5, anchorY: 0.5, x: 1024 + d * 60, y: 150 }); dimensionIndicators.push(indicator); LK.gui.addChild(indicator); } function initializeLevel() { // Clear existing elements for (var i = 0; i < particles.length; i++) { particles[i].destroy(); } for (var i = 0; i < portals.length; i++) { portals[i].destroy(); } for (var i = 0; i < interferenceFields.length; i++) { interferenceFields[i].destroy(); } for (var i = 0; i < backgroundStars.length; i++) { backgroundStars[i].destroy(); } for (var i = 0; i < powerUps.length; i++) { powerUps[i].destroy(); } backgroundStars = []; particles = []; portals = []; interferenceFields = []; powerUps = []; particlesCollected = 0; currentDimension = 0; // Reset and start timer - reduced time penalty for easier gameplay var timeReduction = (level - 1) * 800; // Reduced from 1500 to 800 // Extra time reduction for extreme levels - less harsh if (level >= 11) { timeReduction += (level - 10) * 200; // Reduced from 500 to 200 } if (level >= 16) { timeReduction += (level - 15) * 100; // Reduced from 300 to 100 } timeRemaining = Math.max(12000, timeLimit - timeReduction); // Increased minimum from 6 to 12 seconds timerActive = true; dimensionSwitches = 0; maxDimensionSwitches = Math.max(12, 18 - Math.min(level, 4)); // More switches allowed, minimum 12 (increased from 8) // Reset power-up system shieldActive = false; shieldTimeRemaining = 0; slowMotionActive = false; slowMotionTimeRemaining = 0; powerUpSpawnTimer = 0; shieldText.visible = false; slowMotionText.visible = false; // Create quantum core if (quantumCore) { quantumCore.destroy(); } quantumCore = game.addChild(LK.getAsset('quantumCore', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 800 })); // Create background star field var numStars = 80 + level * 15; for (var i = 0; i < numStars; i++) { var star = game.addChild(new BackgroundStar()); star.x = Math.random() * 2048; star.y = Math.random() * 2732; star.scaleX = 0.5 + Math.random() * 1.5; star.scaleY = star.scaleX; backgroundStars.push(star); } // Create orbital particles around quantum core for (var i = 0; i < 8; i++) { var orbitalStar = game.addChild(new BackgroundStar()); var angle = i / 8 * Math.PI * 2; var radius = 200 + Math.random() * 100; orbitalStar.x = quantumCore.x + Math.cos(angle) * radius; orbitalStar.y = quantumCore.y + Math.sin(angle) * radius; orbitalStar.scaleX = 1.5; orbitalStar.scaleY = 1.5; orbitalStar.orbitalAngle = angle; orbitalStar.orbitalRadius = radius; orbitalStar.orbitalSpeed = 0.01 + Math.random() * 0.02; backgroundStars.push(orbitalStar); } // Tutorial level setup (Level 0) if (level === 0) { isTutorial = true; tutorialStep = 0; tutorialComplete = false; timerActive = false; // No timer pressure in tutorial maxDimensionSwitches = 999; // Unlimited switches for tutorial tutorialText.visible = true; tutorialText.setText('Welcome to Quantum Dimensions!'); // Single particle in dimension 0 for simple drag tutorial var tutorialParticle = game.addChild(new Particle()); tutorialParticle.x = 300; tutorialParticle.y = 1800; tutorialParticle.setDimension(0); tutorialParticle.lastCoreIntersecting = false; tutorialParticle.isBeingDragged = false; tutorialParticle.isCollected = false; tutorialParticle.dimension = 0; // Ensure dimension is properly set particles.push(tutorialParticle); // Add a second particle in dimension 1 to demonstrate dimension switching var tutorialParticle2 = game.addChild(new Particle()); tutorialParticle2.x = 1700; tutorialParticle2.y = 1800; tutorialParticle2.setDimension(1); tutorialParticle2.lastCoreIntersecting = false; tutorialParticle2.isBeingDragged = false; tutorialParticle2.isCollected = false; tutorialParticle2.dimension = 1; // Ensure dimension is properly set particles.push(tutorialParticle2); // Add a safe interference field for demonstration (not dangerous in tutorial) var demoField = game.addChild(new InterferenceField()); demoField.x = 1024; demoField.y = 2200; demoField.setDimension(0); demoField.alpha = 0.3; // Make it less threatening interferenceFields.push(demoField); // Add a portal for demonstration var demoPortal = game.addChild(new Portal()); demoPortal.x = 1024; demoPortal.y = 1400; demoPortal.dimension = 0; demoPortal.targetDimension = 1; demoPortal.setDimension(0); demoPortal.alpha = 0.5; // Make it visible but not distracting portals.push(demoPortal); totalParticles = 2; // Count both particles for tutorial completion // Show tutorial instructions immediately LK.setTimeout(function () { updateTutorialStep(); }, 500); } else if (level === 1) { // Reset tutorial flags for actual gameplay isTutorial = false; tutorialText.visible = false; timerActive = true; // Simple particles in different dimensions var particle1 = game.addChild(new Particle()); particle1.x = 300; particle1.y = 1600; particle1.setDimension(0); particle1.lastCoreIntersecting = false; particle1.isBeingDragged = false; particle1.isCollected = false; particles.push(particle1); var particle2 = game.addChild(new Particle()); particle2.x = 1700; particle2.y = 1600; particle2.setDimension(1); particle2.lastCoreIntersecting = false; particle2.isBeingDragged = false; particle2.isCollected = false; particles.push(particle2); // Portal to connect dimensions var portal1 = game.addChild(new Portal()); portal1.x = 1024; portal1.y = 1600; portal1.dimension = 0; portal1.targetDimension = 1; portal1.setDimension(0); portals.push(portal1); totalParticles = 2; } else { // Progressive levels with more complexity - reduced interference fields var numParticles = Math.min(level + 1, 4); var numFields = Math.min(Math.max(0, level - 1), 4); // Fewer interference fields, starting from level 2 for (var i = 0; i < numParticles; i++) { var particle = game.addChild(new Particle()); particle.x = 200 + i * 400; particle.y = 1800 + i % 2 * 400; particle.setDimension(i % totalDimensions); particle.lastCoreIntersecting = false; particle.isBeingDragged = false; particle.isCollected = false; particles.push(particle); } // Create entangled pairs for higher levels if (level >= 3 && particles.length >= 2) { particles[0].entangledWith = particles[1]; particles[1].entangledWith = particles[0]; } // Create portals for (var i = 0; i < 2; i++) { var portal = game.addChild(new Portal()); portal.x = 400 + i * 1200; portal.y = 1200; portal.dimension = i; portal.targetDimension = (i + 1) % totalDimensions; portal.setDimension(i); portals.push(portal); } // Create interference fields for (var i = 0; i < numFields; i++) { var field = game.addChild(new InterferenceField()); field.x = 300 + i * 600; field.y = 1000 + i % 2 * 400; field.setDimension(i % totalDimensions); // Add movement to interference fields for higher levels if (level >= 2) { field.moveDirection = i % 2 === 0 ? 1 : -1; field.minX = 100; field.maxX = 1948; } interferenceFields.push(field); } // Add additional moving barriers for higher levels if (level >= 2) { var movingField = game.addChild(new InterferenceField()); movingField.x = 1024; movingField.y = 1400; movingField.setDimension(0); movingField.moveDirection = 1; movingField.minX = 200; movingField.maxX = 1848; interferenceFields.push(movingField); } // Add second moving barrier for level 3+ if (level >= 3) { var movingField2 = game.addChild(new InterferenceField()); movingField2.x = 500; movingField2.y = 2000; movingField2.setDimension(1); movingField2.moveDirection = -1; movingField2.minX = 100; movingField2.maxX = 1948; interferenceFields.push(movingField2); } // Add third moving barrier for level 4+ if (level >= 4) { var movingField3 = game.addChild(new InterferenceField()); movingField3.x = 1500; movingField3.y = 1600; movingField3.setDimension(0); movingField3.moveDirection = 1; movingField3.minX = 300; movingField3.maxX = 1700; interferenceFields.push(movingField3); } // Add fourth moving barrier for level 5+ if (level >= 5) { var movingField4 = game.addChild(new InterferenceField()); movingField4.x = 800; movingField4.y = 1800; movingField4.setDimension(1); movingField4.moveDirection = -1; movingField4.minX = 200; movingField4.maxX = 1800; interferenceFields.push(movingField4); } // Advanced levels 6-10 with additional challenges if (level >= 6) { // Add more particles for higher levels var extraParticles = Math.min(level - 5, 3); for (var j = 0; j < extraParticles; j++) { var extraParticle = game.addChild(new Particle()); extraParticle.x = 400 + j * 300; extraParticle.y = 2200 + j % 2 * 200; extraParticle.setDimension(j % totalDimensions); extraParticle.lastCoreIntersecting = false; extraParticle.isBeingDragged = false; extraParticle.isCollected = false; particles.push(extraParticle); } totalParticles += extraParticles; // Add additional moving barriers var numExtraFields = Math.min(level - 5, 4); for (var k = 0; k < numExtraFields; k++) { var extraField = game.addChild(new InterferenceField()); extraField.x = 200 + k * 400; extraField.y = 1300 + k % 2 * 300; extraField.setDimension(k % totalDimensions); extraField.moveDirection = k % 2 === 0 ? 1 : -1; extraField.minX = 100; extraField.maxX = 1948; interferenceFields.push(extraField); } } // Level 8+ speed increase is now handled in the InterferenceField update method // Level 10 gets entangled triplets if (level >= 10 && particles.length >= 3) { particles[0].entangledWith = particles[1]; particles[1].entangledWith = particles[2]; particles[2].entangledWith = particles[0]; } // Advanced levels 11-15 with extreme challenges if (level >= 11) { // Add even more particles for extreme levels var extremeParticles = Math.min(level - 10, 5); for (var m = 0; m < extremeParticles; m++) { var extremeParticle = game.addChild(new Particle()); extremeParticle.x = 150 + m * 250; extremeParticle.y = 2400 + m % 2 * 150; extremeParticle.setDimension(m % totalDimensions); extremeParticle.lastCoreIntersecting = false; extremeParticle.isBeingDragged = false; extremeParticle.isCollected = false; particles.push(extremeParticle); } totalParticles += extremeParticles; // Add maze-like interference field patterns var mazeFields = Math.min(level - 10, 6); for (var n = 0; n < mazeFields; n++) { var mazeField = game.addChild(new InterferenceField()); mazeField.x = 300 + n * 200; mazeField.y = 1100 + n % 3 * 200; mazeField.setDimension(n % totalDimensions); mazeField.moveDirection = n % 2 === 0 ? 1 : -1; mazeField.minX = 50; mazeField.maxX = 1998; interferenceFields.push(mazeField); } } // Master levels 16-20 with ultimate difficulty if (level >= 16) { // Add master-level particles var masterParticles = Math.min(level - 15, 4); for (var p = 0; p < masterParticles; p++) { var masterParticle = game.addChild(new Particle()); masterParticle.x = 200 + p * 400; masterParticle.y = 2500 + p % 2 * 100; masterParticle.setDimension(p % totalDimensions); masterParticle.lastCoreIntersecting = false; masterParticle.isBeingDragged = false; masterParticle.isCollected = false; particles.push(masterParticle); } totalParticles += masterParticles; // Create complex entanglement networks if (particles.length >= 4) { for (var q = 0; q < Math.min(particles.length - 1, 6); q++) { if (q + 1 < particles.length) { particles[q].entangledWith = particles[q + 1]; } } } // Add ultra-fast moving barriers var ultraFields = Math.min(level - 15, 8); for (var r = 0; r < ultraFields; r++) { var ultraField = game.addChild(new InterferenceField()); ultraField.x = 100 + r * 180; ultraField.y = 1200 + r % 4 * 150; ultraField.setDimension(r % totalDimensions); ultraField.moveDirection = r % 2 === 0 ? 1 : -1; ultraField.minX = 50; ultraField.maxX = 1998; interferenceFields.push(ultraField); } } // Calculate total particles correctly for all levels totalParticles = particles.length; } updateDimensionDisplay(); if (level === 0) { levelText.setText('Tutorial'); } else { levelText.setText('Level: ' + level); } } function updateDimensionDisplay() { dimensionText.setText('Dimension: ' + currentDimension); instructionText.setText('Switches: ' + dimensionSwitches + '/' + maxDimensionSwitches + ' - Tap to switch'); for (var i = 0; i < dimensionIndicators.length; i++) { var indicator = dimensionIndicators[i]; tween(indicator, { alpha: i === currentDimension ? 1.0 : 0.3, scaleX: i === currentDimension ? 1.5 : 1.0, scaleY: i === currentDimension ? 1.5 : 1.0 }, { duration: 300, easing: tween.easeOut }); } // Update all objects for dimension visibility for (var i = 0; i < particles.length; i++) { var targetAlpha = particles[i].dimension === currentDimension ? 1.0 : 0.15; tween(particles[i], { alpha: targetAlpha }, { duration: 200, easing: tween.easeInOut }); } for (var i = 0; i < portals.length; i++) { var targetAlpha = portals[i].dimension === currentDimension ? 1.0 : 0.1; tween(portals[i], { alpha: targetAlpha }, { duration: 200, easing: tween.easeInOut }); } for (var i = 0; i < interferenceFields.length; i++) { var targetAlpha = interferenceFields[i].dimension === currentDimension ? 0.8 : 0.1; tween(interferenceFields[i], { alpha: targetAlpha }, { duration: 200, easing: tween.easeInOut }); } for (var i = 0; i < powerUps.length; i++) { var targetAlpha = powerUps[i].dimension === currentDimension ? 1.0 : 0.15; tween(powerUps[i], { alpha: targetAlpha }, { duration: 200, easing: tween.easeInOut }); } } function switchDimension() { if (dimensionSwitches >= maxDimensionSwitches && !isTutorial) { LK.effects.flashScreen(0xFF0000, 200); return; // No more switches allowed (except in tutorial) } dimensionSwitches++; // Remove time penalty to make dimension switching more accessible currentDimension = (currentDimension + 1) % totalDimensions; updateDimensionDisplay(); LK.getSound('dimensionShift').play(); LK.effects.flashScreen(0x440088, 200); // Tutorial progress tracking if (isTutorial) { if (tutorialStep === 3) { tutorialStep = 4; LK.setTimeout(function () { updateTutorialStep(); }, 500); } else if (tutorialStep === 4 && currentDimension === 1) { // Player successfully switched to dimension 1 tutorialStep = 5; LK.setTimeout(function () { updateTutorialStep(); }, 1000); } } } function checkWinCondition() { if (particlesCollected >= totalParticles) { timerActive = false; // Stop timer when level complete if (isTutorial) { if (particlesCollected === 1 && tutorialStep <= 3) { // First particle collected, advance tutorial tutorialStep = 3; updateTutorialStep(); return; } else if (particlesCollected >= 2) { // All particles collected in tutorial, complete it if (tutorialStep < 6) { tutorialStep = 6; updateTutorialStep(); } else if (tutorialComplete || tutorialStep >= 10) { // Tutorial is complete, move to level 1 level = 1; isTutorial = false; tutorialText.visible = false; initializeLevel(); } return; } } level++; LK.setTimeout(function () { if (level > 20) { LK.showYouWin(); } else { initializeLevel(); } }, 1000); } } function resetLevel() { // Check if shield is active to prevent death if (shieldActive) { shieldActive = false; shieldTimeRemaining = 0; shieldText.visible = false; LK.effects.flashScreen(0x0088ff, 300); return; // Shield absorbed the hit } LK.effects.flashScreen(0xff0000, 500); LK.setTimeout(function () { initializeLevel(); }, 600); } function spawnPowerUp() { if (powerUps.length >= 2) return; // Maximum 2 power-ups on screen var powerUp = game.addChild(new PowerUp()); // Ensure power-ups spawn in safe areas away from interference fields var safePosition = false; var attempts = 0; var spawnX, spawnY; while (!safePosition && attempts < 10) { spawnX = 300 + Math.random() * 1448; spawnY = 600 + Math.random() * 800; // Check distance from interference fields safePosition = true; for (var f = 0; f < interferenceFields.length; f++) { var field = interferenceFields[f]; var distance = Math.sqrt((spawnX - field.x) * (spawnX - field.x) + (spawnY - field.y) * (spawnY - field.y)); if (distance < 200) { safePosition = false; break; } } attempts++; } powerUp.x = spawnX || 300 + Math.random() * 1448; powerUp.y = spawnY || 600 + Math.random() * 800; powerUp.setDimension(currentDimension); // Always spawn in current dimension for better accessibility // Random power-up type var types = ['timeBoost', 'shield', 'slowMotion']; var randomType = types[Math.floor(Math.random() * types.length)]; powerUp.setType(randomType); powerUp.lastPlayerIntersecting = false; powerUps.push(powerUp); } // Event handlers game.down = function (x, y, obj) { var hitParticle = false; for (var i = 0; i < particles.length; i++) { var particle = particles[i]; if (particle.dimension === currentDimension && !particle.isCollected && particle.alpha > 0.5) { // Use actual asset dimensions for accurate touch detection var halfWidth = particle.children[0].width / 2; // Use actual particle asset width var halfHeight = particle.children[0].height / 2; // Use actual particle asset height // Check if touch point is within particle bounds if (x >= particle.x - halfWidth && x <= particle.x + halfWidth && y >= particle.y - halfHeight && y <= particle.y + halfHeight) { draggedParticle = particle; particle.startDrag(); dragOffset.x = x - particle.x; dragOffset.y = y - particle.y; hitParticle = true; break; } } } if (!hitParticle) { switchDimension(); } }; game.move = function (x, y, obj) { if (draggedParticle && !draggedParticle.isCollected) { var targetX = x - dragOffset.x; var targetY = y - dragOffset.y; // Keep particle within bounds targetX = Math.max(80, Math.min(1968, targetX)); targetY = Math.max(80, Math.min(2652, targetY)); // Direct position update for responsive dragging draggedParticle.x = targetX; draggedParticle.y = targetY; // Reduce trail effect frequency to improve performance if (LK.ticks % 10 === 0) { var trailStar = game.addChild(new BackgroundStar()); trailStar.x = draggedParticle.x + (Math.random() - 0.5) * 20; trailStar.y = draggedParticle.y + (Math.random() - 0.5) * 20; trailStar.scaleX = 0.8; trailStar.scaleY = 0.8; trailStar.alpha = 0.8; // Fade out trail particle tween(trailStar, { alpha: 0, scaleX: 0.1, scaleY: 0.1 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { trailStar.destroy(); } }); } // Handle entangled particle movement with direct updates if (draggedParticle.entangledWith) { // Only move entangled particles when BOTH the dragged particle AND the entangled particle are in the current dimension // This prevents cross-dimensional interference where particles in other dimensions move unexpectedly if (draggedParticle.dimension === currentDimension && draggedParticle.entangledWith.dimension === currentDimension) { draggedParticle.entangledWith.x = targetX + 150; draggedParticle.entangledWith.y = targetY; } // Ensure entangled particles maintain proper alpha based on current dimension var entangledTargetAlpha = draggedParticle.entangledWith.dimension === currentDimension ? 1.0 : 0.15; draggedParticle.entangledWith.alpha = entangledTargetAlpha; } } }; game.up = function (x, y, obj) { if (draggedParticle) { draggedParticle.stopDrag(); draggedParticle = null; } }; game.update = function () { // Handle timer countdown if (timerActive) { var timeDecrement = slowMotionActive ? 8.33 : 16.67; // Slow motion halves time consumption timeRemaining -= timeDecrement; if (timeRemaining <= 0) { resetLevel(); return; } var seconds = Math.ceil(timeRemaining / 1000); timerText.setText('Time: ' + seconds + 's'); // Smooth color transitions when time is running out if (seconds <= 5) { tween(timerText, { tint: 0xFF0000 }, { duration: 200, easing: tween.easeOut }); } else if (seconds <= 10) { tween(timerText, { tint: 0xFFFF00 }, { duration: 200, easing: tween.easeOut }); } else { tween(timerText, { tint: 0xFFFFFF }, { duration: 200, easing: tween.easeOut }); } } // Animate quantum core with direct property updates if (quantumCore) { // Direct rotation update quantumCore.rotation += 0.02; // Direct pulsing animation var pulse = Math.sin(LK.ticks * 0.08) * 0.15 + 1.0; quantumCore.scaleX = pulse; quantumCore.scaleY = pulse; // Reduced frequency color cycling if (LK.ticks % 60 === 0) { var colorPhase = LK.ticks * 0.015; var r = Math.sin(colorPhase) * 0.4 + 0.6; var g = Math.sin(colorPhase + 2) * 0.4 + 0.6; var b = Math.sin(colorPhase + 4) * 0.4 + 0.6; var color = Math.floor(r * 255) << 16 | Math.floor(g * 255) << 8 | Math.floor(b * 255); quantumCore.tint = color; } } // Update all particles for (var i = 0; i < particles.length; i++) { if (particles[i].update) { particles[i].update(); } } // Update all portals for (var i = 0; i < portals.length; i++) { if (portals[i].update) { portals[i].update(); } } // Update all interference fields for (var i = 0; i < interferenceFields.length; i++) { if (interferenceFields[i].update) { interferenceFields[i].update(); } } // Handle power-up spawning if (timerActive) { powerUpSpawnTimer += 16.67; // Calculate dynamic spawn interval based on level - more frequent power-ups var dynamicSpawnInterval = powerUpSpawnInterval; if (level >= 5) { dynamicSpawnInterval = Math.max(3000, powerUpSpawnInterval - (level - 4) * 300); // Faster spawning for higher levels, minimum 3 seconds (reduced from 4) } if (powerUpSpawnTimer >= dynamicSpawnInterval) { spawnPowerUp(); powerUpSpawnTimer = 0; } } // Handle shield duration if (shieldActive) { shieldTimeRemaining -= 16.67; if (shieldTimeRemaining <= 0) { shieldActive = false; shieldText.visible = false; } else { shieldText.visible = true; shieldText.setText('SHIELD: ' + Math.ceil(shieldTimeRemaining / 1000) + 's'); } } // Handle slow motion duration if (slowMotionActive) { slowMotionTimeRemaining -= 16.67; if (slowMotionTimeRemaining <= 0) { slowMotionActive = false; slowMotionText.visible = false; } else { slowMotionText.visible = true; slowMotionText.setText('SLOW MOTION: ' + Math.ceil(slowMotionTimeRemaining / 1000) + 's'); } } // Update power-ups for (var i = powerUps.length - 1; i >= 0; i--) { if (powerUps[i].update) { powerUps[i].update(); } // Remove collected power-ups if (powerUps[i].isCollected && !powerUps[i].visible) { powerUps[i].destroy(); powerUps.splice(i, 1); } } // Update background stars for (var i = 0; i < backgroundStars.length; i++) { var star = backgroundStars[i]; if (star.update) { star.update(); } // Handle orbital motion for core particles if (star.orbitalAngle !== undefined && quantumCore) { star.orbitalAngle += star.orbitalSpeed; star.x = quantumCore.x + Math.cos(star.orbitalAngle) * star.orbitalRadius; star.y = quantumCore.y + Math.sin(star.orbitalAngle) * star.orbitalRadius; } } }; function updateTutorialStep() { if (!isTutorial) return; // Ensure tutorial text is visible and properly positioned tutorialText.visible = true; tutorialText.alpha = 1.0; // Position tutorial text in center-upper area for better visibility tutorialText.x = 1024; tutorialText.y = 600; // Ensure text is on top and visible game.removeChild(tutorialText); game.addChild(tutorialText); switch (tutorialStep) { case 0: tutorialText.setText('Welcome to Quantum Dimensions!\nYou control particles across multiple dimensions.'); LK.setTimeout(function () { tutorialStep = 1; updateTutorialStep(); }, 3000); break; case 1: tutorialText.setText('See the glowing particle? Touch and drag it.\nThis is how you move particles in the quantum field.'); // Add visual hint by pulsing the particle if (particles.length > 0 && particles[0].dimension === currentDimension) { LK.effects.flashObject(particles[0], 0x00ff00, 1000); } break; case 2: tutorialText.setText('Excellent! Now drag it to the quantum core (center).\nParticles must reach the core to be collected.'); // Add visual hint by flashing the quantum core if (quantumCore) { LK.effects.flashObject(quantumCore, 0x00ffff, 1500); } break; case 3: tutorialText.setText('Perfect! You collected your first particle!\nNow tap anywhere (empty space) to switch dimensions.'); break; case 4: tutorialText.setText('Great! Notice how the view changed?\nYou just switched to Dimension 1. See the second particle?'); if (particles.length > 1 && particles[1].dimension === currentDimension) { LK.effects.flashObject(particles[1], 0x00ff00, 1000); } LK.setTimeout(function () { tutorialStep = 5; updateTutorialStep(); }, 3000); break; case 5: tutorialText.setText('Now collect this second particle!\nDrag it to the quantum core too.'); if (particles.length > 1 && particles[1].dimension === currentDimension) { LK.effects.flashObject(particles[1], 0x00ff00, 1000); } break; case 6: tutorialText.setText('Excellent! You have learned the basics.\nIn real levels, you have limited dimension switches!'); LK.setTimeout(function () { tutorialStep = 7; updateTutorialStep(); }, 3000); break; case 7: tutorialText.setText('Watch out for red interference fields - they reset the level!\nAvoid them while moving particles.'); LK.setTimeout(function () { tutorialStep = 8; updateTutorialStep(); }, 3000); break; case 8: tutorialText.setText('Blue portals transport particles between dimensions.\nUse them strategically!'); LK.setTimeout(function () { tutorialStep = 9; updateTutorialStep(); }, 3000); break; case 9: tutorialText.setText('Power-ups help you: Time Boost (+15s), Shield (protection),\nand Slow Motion (easier movement).'); LK.setTimeout(function () { tutorialStep = 10; updateTutorialStep(); }, 4000); break; case 10: tutorialText.setText('Tutorial Complete! Ready for the challenge?\nStarting Level 1...'); LK.setTimeout(function () { tutorialComplete = true; checkWinCondition(); // Use existing function to transition properly }, 3000); break; } } function showPowerUpSpec(title, description, color) { // Create power-up specification display var specContainer = new Container(); // Title text var titleText = new Text2(title, { size: 60, fill: color }); titleText.anchor.set(0.5, 0.5); titleText.x = 1024; titleText.y = 1300; specContainer.addChild(titleText); // Description text var descText = new Text2(description, { size: 45, fill: 0xFFFFFF }); descText.anchor.set(0.5, 0.5); descText.x = 1024; descText.y = 1380; specContainer.addChild(descText); // Add to game game.addChild(specContainer); // Initial state specContainer.alpha = 0; specContainer.scaleX = 0.3; specContainer.scaleY = 0.3; // Animation: fade in and scale up tween(specContainer, { alpha: 1.0, scaleX: 1.0, scaleY: 1.0 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { // Hold for a moment then fade out LK.setTimeout(function () { tween(specContainer, { alpha: 0, scaleX: 0.8, scaleY: 0.8 }, { duration: 400, easing: tween.easeIn, onFinish: function onFinish() { specContainer.destroy(); } }); }, 2000); } }); } // Initialize first level initializeLevel();
===================================================================
--- original.js
+++ change.js
@@ -156,13 +156,13 @@
}
// Check collision with quantum core - only trigger on first contact
var currentCoreIntersecting = false;
if (self.dimension === currentDimension && quantumCore) {
- // Use proper bounds checking for accurate collision detection
- var particleHalfWidth = 70; // Half of particle asset width (140/2)
- var particleHalfHeight = 70; // Half of particle asset height (140/2)
- var coreHalfWidth = 125; // Half of quantum core asset width (250/2)
- var coreHalfHeight = 125; // Half of quantum core asset height (250/2)
+ // Use actual asset dimensions for accurate collision detection
+ var particleHalfWidth = particleGraphics.width / 2; // Use actual particle asset width
+ var particleHalfHeight = particleGraphics.height / 2; // Use actual particle asset height
+ var coreHalfWidth = quantumCore.width / 2; // Use actual quantum core asset width
+ var coreHalfHeight = quantumCore.height / 2; // Use actual quantum core asset height
currentCoreIntersecting = Math.abs(self.x - quantumCore.x) < particleHalfWidth + coreHalfWidth && Math.abs(self.y - quantumCore.y) < particleHalfHeight + coreHalfHeight;
}
if (!self.lastCoreIntersecting && currentCoreIntersecting) {
self.collect();
@@ -174,13 +174,13 @@
// Check collision with interference fields
for (var i = 0; i < interferenceFields.length; i++) {
var field = interferenceFields[i];
if (field.dimension === self.dimension) {
- // Use proper bounds checking for accurate collision detection
- var particleHalfWidth = 70; // Half of particle asset width (140/2)
- var particleHalfHeight = 70; // Half of particle asset height (140/2)
- var fieldHalfWidth = 75; // Half of interference field asset width (150/2)
- var fieldHalfHeight = 75; // Half of interference field asset height (150/2)
+ // Use actual asset dimensions for accurate collision detection
+ var particleHalfWidth = particleGraphics.width / 2; // Use actual particle asset width
+ var particleHalfHeight = particleGraphics.height / 2; // Use actual particle asset height
+ var fieldHalfWidth = field.children[0].width / 2; // Use actual interference field asset width
+ var fieldHalfHeight = field.children[0].height / 2; // Use actual interference field asset height
var isColliding = Math.abs(self.x - field.x) < particleHalfWidth + fieldHalfWidth && Math.abs(self.y - field.y) < particleHalfHeight + fieldHalfHeight;
if (isColliding) {
if (isTutorial) {
// In tutorial, just show educational message instead of resetting
@@ -227,13 +227,13 @@
// Check if particles are transported through portal
for (var i = 0; i < particles.length; i++) {
var particle = particles[i];
if (particle.dimension === self.dimension && !particle.isBeingDragged) {
- // Use proper bounds checking for accurate collision detection
- var portalHalfWidth = 100; // Half of portal asset width (200/2)
- var portalHalfHeight = 100; // Half of portal asset height (200/2)
- var particleHalfWidth = 70; // Half of particle asset width (140/2)
- var particleHalfHeight = 70; // Half of particle asset height (140/2)
+ // Use actual asset dimensions for accurate collision detection
+ var portalHalfWidth = portalGraphics.width / 2; // Use actual portal asset width
+ var portalHalfHeight = portalGraphics.height / 2; // Use actual portal asset height
+ var particleHalfWidth = particle.children[0].width / 2; // Use actual particle asset width
+ var particleHalfHeight = particle.children[0].height / 2; // Use actual particle asset height
var isColliding = Math.abs(self.x - particle.x) < portalHalfWidth + particleHalfWidth && Math.abs(self.y - particle.y) < portalHalfHeight + particleHalfHeight;
if (isColliding) {
particle.setDimension(self.targetDimension);
LK.getSound('portalSound').play();
@@ -336,13 +336,13 @@
var currentPlayerIntersecting = false;
for (var p = 0; p < particles.length; p++) {
var particle = particles[p];
if (particle.dimension === self.dimension && particle.dimension === currentDimension && !particle.isCollected) {
- // Use proper bounds checking for more accurate collision detection
- var powerUpHalfWidth = 45; // Half of power-up asset width (90/2 average)
- var powerUpHalfHeight = 45; // Half of power-up asset height (90/2 average)
- var particleHalfWidth = 70; // Half of particle asset width (140/2)
- var particleHalfHeight = 70; // Half of particle asset height (140/2)
+ // Use actual asset dimensions for accurate collision detection
+ var powerUpHalfWidth = self.powerUpGraphics.width / 2; // Use actual power-up asset width
+ var powerUpHalfHeight = self.powerUpGraphics.height / 2; // Use actual power-up asset height
+ var particleHalfWidth = particle.children[0].width / 2; // Use actual particle asset width
+ var particleHalfHeight = particle.children[0].height / 2; // Use actual particle asset height
var isColliding = Math.abs(self.x - particle.x) < powerUpHalfWidth + particleHalfWidth && Math.abs(self.y - particle.y) < powerUpHalfHeight + particleHalfHeight;
if (isColliding) {
currentPlayerIntersecting = true;
break;
@@ -983,11 +983,11 @@
var hitParticle = false;
for (var i = 0; i < particles.length; i++) {
var particle = particles[i];
if (particle.dimension === currentDimension && !particle.isCollected && particle.alpha > 0.5) {
- // Use proper bounds checking based on particle's actual asset dimensions
- var halfWidth = 70; // Half of particle asset width (140/2)
- var halfHeight = 70; // Half of particle asset height (140/2)
+ // Use actual asset dimensions for accurate touch detection
+ var halfWidth = particle.children[0].width / 2; // Use actual particle asset width
+ var halfHeight = particle.children[0].height / 2; // Use actual particle asset height
// Check if touch point is within particle bounds
if (x >= particle.x - halfWidth && x <= particle.x + halfWidth && y >= particle.y - halfHeight && y <= particle.y + halfHeight) {
draggedParticle = particle;
particle.startDrag();