User prompt
show the brush on the pollutedspirits not on spirits that respawn from the top βͺπ‘ Consider importing and using the following plugins: @upit/tween.v1
User prompt
Add brush asset to the game when player clean the spirits show the brush on them with animation left and right by small distance to look like its brushing them. βͺπ‘ Consider importing and using the following plugins: @upit/tween.v1
User prompt
Add gamebackground
User prompt
play intro music when intro music only so when the game is starts play only game music
User prompt
Please fix the bug: 'ReferenceError: spawnToken is not defined' in or related to this line: 'spawnToken();' Line Number: 347
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'length')' in or related to this line: 'for (var i = tokens.length - 1; i >= 0; i--) {' Line Number: 358
User prompt
The startbutton not working!
User prompt
Add introbackground before game starts and startbutton close to the bottom.
User prompt
add bathmusic for the game
User prompt
don't show the game objects till it starts or startbutton is clicked!
User prompt
Add introbackground for the intro before game start and startbutton close to the bottom by 100px
User prompt
Import of asset
User prompt
Change direction for the player when go to the left and right from the middle of the screen.
User prompt
free one spirit took all the tokens! reduce that to 1 token only per spirit before it change to dark spirit.
User prompt
Add the asset for the dark spirt is missing on the list of assets!
User prompt
Lower the game screen from the top by 200px but let the text in its position so the healthbar
User prompt
move health bar to top max close to top by 30px on the same area on the left side not to the middle or right side!
User prompt
move health bar to the max top before 30px
User prompt
change health to a sky blue bar of 100% decreased by random % from 3 to 10.
Code edit (1 edits merged)
Please save this source code
User prompt
Spirit Bath House Adventure
Initial prompt
Create a spirited a way game. story game. from the anime movie "spirited a way".
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var BlueSpirit = Container.expand(function () { var self = Container.call(this); var spiritGraphics = self.attachAsset('blueSpirit', { anchorX: 0.5, anchorY: 0.5 }); self.waitTime = 0; self.maxWaitTime = 600; // 10 seconds at 60fps (default for both levels) self.isDark = false; self.speed = 1; self.update = function () { self.waitTime++; // Set maxWaitTime based on current level if (currentLevel === 'level1') { self.maxWaitTime = 600; // 10 seconds at 60fps } else if (currentLevel === 'level2') { self.maxWaitTime = 600; // 10 seconds at 60fps } if (!self.isDark && self.waitTime >= self.maxWaitTime) { self.turnDark(); } if (self.isDark) { self.y += self.speed; } }; self.turnDark = function () { self.isDark = true; spiritGraphics.tint = 0x2a0845; tween(spiritGraphics, { scaleX: 1.2, scaleY: 1.2 }, { duration: 500 }); }; return self; }); var DarkSpirit = Container.expand(function () { var self = Container.call(this); var darkGraphics = self.attachAsset('darkSpirit', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 1.5; self.targetPlayer = null; self.update = function () { if (self.targetPlayer) { var dx = self.targetPlayer.x - self.x; var dy = self.targetPlayer.y - 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; } // Change direction based on position relative to screen middle var screenMiddle = 1024; if (self.x < screenMiddle) { // Dark spirit is on left side, face right towards middle self.scaleX = 1; } else { // Dark spirit is on right side, face left towards middle self.scaleX = -1; } } }; return self; }); var HealthBar = Container.expand(function () { var self = Container.call(this); // Background bar self.bgBar = self.attachAsset('healthBarBg', { anchorX: 0, anchorY: 0 }); // Health bar self.healthBar = self.attachAsset('healthBarFill', { anchorX: 0, anchorY: 0 }); self.maxWidth = 300; self.updateHealth = function (healthPercent) { self.healthBar.scaleX = healthPercent / 100; }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.tokens = 0; self.health = 100; self.maxHealth = 100; self.collectToken = function () { self.tokens++; }; self.deliverTokens = function () { var delivered = self.tokens; self.tokens = 0; return delivered; }; self.takeDamage = function () { var damage = Math.random() * 7 + 3; // Random between 3-10 self.health -= damage; self.health = Math.max(0, self.health); // Ensure health doesn't go below 0 LK.effects.flashObject(self, 0xff0000, 500); return self.health <= 0; }; return self; }); var PollutedSpirit = Container.expand(function () { var self = Container.call(this); var pollutedGraphics = self.attachAsset('pollutedspirit1', { anchorX: 0.5, anchorY: 0.5 }); self.tokensNeeded = 3; self.isCleansed = false; self.cleanse = function () { self.isCleansed = true; tween(pollutedGraphics, { tint: 0x98fb98 }, { duration: 1000, onFinish: function onFinish() { self.destroy(); } }); }; return self; }); var PollutedSpirit2 = Container.expand(function () { var self = Container.call(this); var pollutedGraphics = self.attachAsset('pollutedspirit2', { anchorX: 0.5, anchorY: 0.5 }); self.tokensNeeded = 3; self.isCleansed = false; self.cleanse = function () { self.isCleansed = true; tween(pollutedGraphics, { tint: 0x98fb98 }, { duration: 1000, onFinish: function onFinish() { self.destroy(); } }); }; return self; }); var PollutedSpirit3 = Container.expand(function () { var self = Container.call(this); var pollutedGraphics = self.attachAsset('pollutedspirit3', { anchorX: 0.5, anchorY: 0.5 }); self.tokensNeeded = 3; self.isCleansed = false; self.cleanse = function () { self.isCleansed = true; tween(pollutedGraphics, { tint: 0x98fb98 }, { duration: 1000, onFinish: function onFinish() { self.destroy(); } }); }; return self; }); var PollutedSpirit4 = Container.expand(function () { var self = Container.call(this); var pollutedGraphics = self.attachAsset('pollutedspirit4', { anchorX: 0.5, anchorY: 0.5 }); self.tokensNeeded = 3; self.isCleansed = false; self.cleanse = function () { self.isCleansed = true; tween(pollutedGraphics, { tint: 0x98fb98 }, { duration: 1000, onFinish: function onFinish() { self.destroy(); } }); }; return self; }); var PollutedSpirit5 = Container.expand(function () { var self = Container.call(this); var pollutedGraphics = self.attachAsset('pollutedspirit5', { anchorX: 0.5, anchorY: 0.5 }); self.tokensNeeded = 3; self.isCleansed = false; self.cleanse = function () { self.isCleansed = true; tween(pollutedGraphics, { tint: 0x98fb98 }, { duration: 1000, onFinish: function onFinish() { self.destroy(); } }); }; return self; }); var PollutedSpirit6 = Container.expand(function () { var self = Container.call(this); var pollutedGraphics = self.attachAsset('pollutedspirit6', { anchorX: 0.5, anchorY: 0.5 }); self.tokensNeeded = 3; self.isCleansed = false; self.cleanse = function () { self.isCleansed = true; tween(pollutedGraphics, { tint: 0x98fb98 }, { duration: 1000, onFinish: function onFinish() { self.destroy(); } }); }; return self; }); var PollutedSpirit7 = Container.expand(function () { var self = Container.call(this); var pollutedGraphics = self.attachAsset('pollutedspirit7', { anchorX: 0.5, anchorY: 0.5 }); self.tokensNeeded = 3; self.isCleansed = false; self.cleanse = function () { self.isCleansed = true; tween(pollutedGraphics, { tint: 0x98fb98 }, { duration: 1000, onFinish: function onFinish() { self.destroy(); } }); }; return self; }); var PollutedSpirit8 = Container.expand(function () { var self = Container.call(this); var pollutedGraphics = self.attachAsset('pollutedspirit8', { anchorX: 0.5, anchorY: 0.5 }); self.tokensNeeded = 3; self.isCleansed = false; self.cleanse = function () { self.isCleansed = true; tween(pollutedGraphics, { tint: 0x98fb98 }, { duration: 1000, onFinish: function onFinish() { self.destroy(); } }); }; return self; }); var RiverSpirit = Container.expand(function () { var self = Container.call(this); var riverGraphics = self.attachAsset('riverSpirit', { anchorX: 0.5, anchorY: 0.5 }); self.bonusValue = 20; self.speed = 0.5; self.update = function () { self.x += self.speed; self.rotation += 0.01; }; return self; }); var ShadowSpirit = Container.expand(function () { var self = Container.call(this); var shadowGraphics = self.attachAsset('shadowSpirit', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 2; self.targetPlayer = null; self.update = function () { if (self.targetPlayer) { var dx = self.targetPlayer.x - self.x; var dy = self.targetPlayer.y - 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; } // Change direction based on position relative to screen middle var screenMiddle = 1024; if (self.x < screenMiddle) { // Shadow is on left side, face right towards middle self.scaleX = 1; } else { // Shadow is on right side, face left towards middle self.scaleX = -1; } } }; return self; }); var Token = Container.expand(function () { var self = Container.call(this); var tokenGraphics = self.attachAsset('token', { anchorX: 0.5, anchorY: 0.5 }); self.collected = false; self.update = function () { if (!self.collected) { self.rotation += 0.02; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1a1a2e }); /**** * Game Code ****/ var gameStarted = false; var introBackground = null; var startButton = null; var currentLevel = 'level1'; var gameBackground = null; // Declare game variables in global scope var player, tokens, blueSpirits, shadowSpirits, pollutedSpirits, riverSpirit, darkSpirits; var spawnTimer, spawnInterval, shadowSpawnTimer, shadowSpawnInterval; var scoreTxt, tokenTxt, healthBar; var brushSprite = null; var showerAreas = [], pollutedSpawnTimer, pollutedSpawnInterval; var maxShadowSpirits = 2; // Level 1: 2, Level 2: 4 var shadowRespawnTimer = 0; var shadowRespawnInterval = 180; // 3 seconds to respawn var lastMovementSoundTime = 0; var movementSoundCooldown = 1000; // Milliseconds between sound plays // Show intro screen function showIntroScreen() { introBackground = game.addChild(LK.getAsset('introbackground', { anchorX: 0, anchorY: 0, x: 0, y: 0 })); startButton = game.addChild(LK.getAsset('startbutton', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 2400 })); // Only play intro music if game hasn't started and we're actually showing intro screen if (!gameStarted && introBackground && startButton) { LK.playMusic('intromusic'); } } // Start the actual game function startGame() { gameStarted = true; if (introBackground) { introBackground.destroy(); introBackground = null; } if (startButton) { startButton.destroy(); startButton = null; } LK.stopMusic(); LK.playMusic('level1music'); initializeGame(); } // Spawn functions in global scope function spawnToken() { var token = new Token(); token.x = Math.random() * 1848 + 100; token.y = Math.random() * 2332 + 300; tokens.push(token); game.addChild(token); } function spawnSpirit() { var spirit = new BlueSpirit(); spirit.x = Math.random() * 1848 + 100; spirit.y = 300; blueSpirits.push(spirit); game.addChild(spirit); } function spawnShadowSpirit() { // Only spawn if under the limit if (shadowSpirits.length < maxShadowSpirits) { var shadow = new ShadowSpirit(); shadow.x = Math.random() * 1848 + 100; shadow.y = Math.random() * 400 + 300; shadow.targetPlayer = player; shadowSpirits.push(shadow); game.addChild(shadow); LK.getSound('Shadowspiritsound').play(); } } function spawnPollutedSpirit() { // Find an empty shower area var emptyAreas = []; for (var i = 0; i < showerAreas.length; i++) { if (!showerAreas[i].occupied) { emptyAreas.push(showerAreas[i]); } } // Only spawn if there's an empty area if (emptyAreas.length > 0) { if (currentLevel === 'level4') { // Level 4: Spawn only PollutedSpirit6, PollutedSpirit7, PollutedSpirit8 if (emptyAreas.length >= 3) { var pollutedTypes = [PollutedSpirit6, PollutedSpirit7, PollutedSpirit8]; for (var t = 0; t < pollutedTypes.length; t++) { var selectedArea = emptyAreas[Math.floor(Math.random() * emptyAreas.length)]; var polluted = new pollutedTypes[t](); polluted.x = selectedArea.x; polluted.y = selectedArea.y; polluted.assignedShowerArea = selectedArea; selectedArea.occupied = true; pollutedSpirits.push(polluted); game.addChild(polluted); // Spawn DarkSpirit behind polluted spirit var dark = new DarkSpirit(); dark.x = polluted.x - 50; dark.y = polluted.y + 30; dark.targetPlayer = player; darkSpirits.push(dark); game.addChild(dark); LK.getSound('darkspiritsound').play(); // Remove the used area from available areas emptyAreas.splice(emptyAreas.indexOf(selectedArea), 1); } } else { // Spawn random types based on available areas var pollutedTypes = [PollutedSpirit6, PollutedSpirit7, PollutedSpirit8]; for (var a = 0; a < Math.min(emptyAreas.length, 3); a++) { var selectedArea = emptyAreas[Math.floor(Math.random() * emptyAreas.length)]; var randomType = pollutedTypes[Math.floor(Math.random() * pollutedTypes.length)]; var polluted = new randomType(); polluted.x = selectedArea.x; polluted.y = selectedArea.y; polluted.assignedShowerArea = selectedArea; selectedArea.occupied = true; pollutedSpirits.push(polluted); game.addChild(polluted); // Spawn DarkSpirit behind polluted spirit var dark = new DarkSpirit(); dark.x = polluted.x - 50; dark.y = polluted.y + 30; dark.targetPlayer = player; darkSpirits.push(dark); game.addChild(dark); LK.getSound('darkspiritsound').play(); // Remove the used area from available areas emptyAreas.splice(emptyAreas.indexOf(selectedArea), 1); } } } else if (currentLevel === 'level3') { // Level 3: Spawn all 5 types if we have at least 5 empty areas if (emptyAreas.length >= 5) { var pollutedTypes = [PollutedSpirit, PollutedSpirit2, PollutedSpirit3, PollutedSpirit4, PollutedSpirit5]; for (var t = 0; t < pollutedTypes.length; t++) { var selectedArea = emptyAreas[Math.floor(Math.random() * emptyAreas.length)]; var polluted = new pollutedTypes[t](); polluted.x = selectedArea.x; polluted.y = selectedArea.y; polluted.assignedShowerArea = selectedArea; selectedArea.occupied = true; pollutedSpirits.push(polluted); game.addChild(polluted); // Spawn DarkSpirit behind polluted spirit var dark = new DarkSpirit(); dark.x = polluted.x - 50; dark.y = polluted.y + 30; dark.targetPlayer = player; darkSpirits.push(dark); game.addChild(dark); LK.getSound('darkspiritsound').play(); // Remove the used area from available areas emptyAreas.splice(emptyAreas.indexOf(selectedArea), 1); } } else { // Spawn random types based on available areas var pollutedTypes = [PollutedSpirit, PollutedSpirit2, PollutedSpirit3, PollutedSpirit4, PollutedSpirit5]; for (var a = 0; a < Math.min(emptyAreas.length, 3); a++) { var selectedArea = emptyAreas[Math.floor(Math.random() * emptyAreas.length)]; var randomType = pollutedTypes[Math.floor(Math.random() * pollutedTypes.length)]; var polluted = new randomType(); polluted.x = selectedArea.x; polluted.y = selectedArea.y; polluted.assignedShowerArea = selectedArea; selectedArea.occupied = true; pollutedSpirits.push(polluted); game.addChild(polluted); // Spawn DarkSpirit behind polluted spirit var dark = new DarkSpirit(); dark.x = polluted.x - 50; dark.y = polluted.y + 30; dark.targetPlayer = player; darkSpirits.push(dark); game.addChild(dark); LK.getSound('darkspiritsound').play(); // Remove the used area from available areas emptyAreas.splice(emptyAreas.indexOf(selectedArea), 1); } } } else if (currentLevel === 'level2') { // Level 2: Spawn both types if we have at least 2 empty areas if (emptyAreas.length >= 2) { // Spawn PollutedSpirit (pollutedspirit1) var selectedArea1 = emptyAreas[Math.floor(Math.random() * emptyAreas.length)]; var polluted1 = new PollutedSpirit(); polluted1.x = selectedArea1.x; polluted1.y = selectedArea1.y; polluted1.assignedShowerArea = selectedArea1; selectedArea1.occupied = true; pollutedSpirits.push(polluted1); game.addChild(polluted1); // Remove the used area from available areas emptyAreas.splice(emptyAreas.indexOf(selectedArea1), 1); // Spawn PollutedSpirit2 (pollutedspirit2) var selectedArea2 = emptyAreas[Math.floor(Math.random() * emptyAreas.length)]; var polluted2 = new PollutedSpirit2(); polluted2.x = selectedArea2.x; polluted2.y = selectedArea2.y; polluted2.assignedShowerArea = selectedArea2; selectedArea2.occupied = true; pollutedSpirits.push(polluted2); game.addChild(polluted2); // Spawn DarkSpirit behind polluted2 var dark2 = new DarkSpirit(); dark2.x = polluted2.x - 50; dark2.y = polluted2.y + 30; dark2.targetPlayer = player; darkSpirits.push(dark2); game.addChild(dark2); LK.getSound('darkspiritsound').play(); } else { // Only one empty area, spawn randomly either type var selectedArea = emptyAreas[0]; var polluted = Math.random() < 0.5 ? new PollutedSpirit() : new PollutedSpirit2(); polluted.x = selectedArea.x; polluted.y = selectedArea.y; polluted.assignedShowerArea = selectedArea; selectedArea.occupied = true; pollutedSpirits.push(polluted); game.addChild(polluted); } } else { // Level 1: Spawn only PollutedSpirit (pollutedspirit1) var selectedArea = emptyAreas[Math.floor(Math.random() * emptyAreas.length)]; var polluted = new PollutedSpirit(); polluted.x = selectedArea.x; polluted.y = selectedArea.y; polluted.assignedShowerArea = selectedArea; selectedArea.occupied = true; pollutedSpirits.push(polluted); game.addChild(polluted); // Spawn DarkSpirit behind polluted spirit in level1 var dark = new DarkSpirit(); dark.x = polluted.x - 50; dark.y = polluted.y + 30; dark.targetPlayer = player; darkSpirits.push(dark); game.addChild(dark); LK.getSound('darkspiritsound').play(); } // Move brush sprite to render on top of polluted spirits if (brushSprite) { game.removeChild(brushSprite); game.addChild(brushSprite); } // Ensure player renders on top of polluted spirits if (player) { game.removeChild(player); game.addChild(player); } } } function spawnRiverSpirit() { if (!riverSpirit) { riverSpirit = new RiverSpirit(); riverSpirit.x = -100; riverSpirit.y = Math.random() * 1000 + 1066; game.addChild(riverSpirit); } } function startLevel(levelName) { currentLevel = levelName; // Remove current background if (gameBackground) { gameBackground.destroy(); gameBackground = null; } // Stop current music and play appropriate level music LK.stopMusic(); if (levelName === 'level2') { LK.playMusic('level2music'); } else if (levelName === 'level3') { LK.playMusic('level3music'); } else if (levelName === 'level4') { LK.playMusic('level4music'); } else if (levelName === 'level1') { LK.playMusic('level1music'); } // Clear all existing enemies from previous level for (var i = blueSpirits.length - 1; i >= 0; i--) { blueSpirits[i].destroy(); } blueSpirits = []; for (var j = shadowSpirits.length - 1; j >= 0; j--) { shadowSpirits[j].destroy(); } shadowSpirits = []; for (var d = darkSpirits.length - 1; d >= 0; d--) { darkSpirits[d].destroy(); } darkSpirits = []; for (var k = pollutedSpirits.length - 1; k >= 0; k--) { if (pollutedSpirits[k].assignedShowerArea) { pollutedSpirits[k].assignedShowerArea.occupied = false; } pollutedSpirits[k].destroy(); } pollutedSpirits = []; if (riverSpirit) { riverSpirit.destroy(); riverSpirit = null; } // Remove existing shower areas for (var i = 0; i < showerAreas.length; i++) { showerAreas[i].destroy(); } showerAreas = []; // Add level background gameBackground = game.addChild(LK.getAsset('background02', { anchorX: 0, anchorY: 0, x: 0, y: 0, visible: true })); // Add shower areas based on level var screenMiddle = 1024; var spacing = 500; // 500px spacing between shower areas var positions = []; if (levelName === 'level2') { // Level 2: 4 shower areas in 2x2 grid positions = [{ x: screenMiddle - spacing / 2, y: 1366 - spacing / 2 }, { x: screenMiddle + spacing / 2, y: 1366 - spacing / 2 }, { x: screenMiddle - spacing / 2, y: 1366 + spacing / 2 }, { x: screenMiddle + spacing / 2, y: 1366 + spacing / 2 }]; } else if (levelName === 'level3') { // Level 3: 6 shower areas in 3x2 grid positions = [ // Top row (3 areas) { x: screenMiddle - spacing, y: 1366 - spacing / 2 }, { x: screenMiddle, y: 1366 - spacing / 2 }, { x: screenMiddle + spacing, y: 1366 - spacing / 2 }, // Bottom row (3 areas) { x: screenMiddle - spacing, y: 1366 + spacing / 2 }, { x: screenMiddle, y: 1366 + spacing / 2 }, { x: screenMiddle + spacing, y: 1366 + spacing / 2 }]; } else if (levelName === 'level4') { // Level 4: 6 shower areas in 2x3 grid positions = [ // Left column (3 areas) { x: screenMiddle - spacing / 2, y: 1366 - spacing }, { x: screenMiddle - spacing / 2, y: 1366 }, { x: screenMiddle - spacing / 2, y: 1366 + spacing }, // Right column (3 areas) { x: screenMiddle + spacing / 2, y: 1366 - spacing }, { x: screenMiddle + spacing / 2, y: 1366 }, { x: screenMiddle + spacing / 2, y: 1366 + spacing }]; } for (var p = 0; p < positions.length; p++) { var showerArea = game.addChild(LK.getAsset('Showerarea', { anchorX: 0.5, anchorY: 0.5, x: positions[p].x, y: positions[p].y })); showerArea.occupied = false; showerAreas.push(showerArea); } // Move player to front to ensure it renders above the new background game.removeChild(player); game.addChild(player); // Reset game state for new level player.health = player.maxHealth; healthBar.updateHealth(player.health); spawnInterval = 1200; // 20 seconds at 60fps shadowSpawnInterval = 240; if (levelName === 'level2') { maxShadowSpirits = 4; // Increase limit for level2 } else if (levelName === 'level3') { maxShadowSpirits = 6; // Increase limit for level3 } else if (levelName === 'level4') { maxShadowSpirits = 8; // Increase limit for level4 } } function initializeGame() { game.setBackgroundColor(0x16213e); currentLevel = 'level1'; // Add level1 game background gameBackground = game.addChild(LK.getAsset('gamebackground', { anchorX: 0, anchorY: 0, x: 0, y: 0 })); player = game.addChild(new Player()); player.x = 1024; player.y = 2200; tokens = []; blueSpirits = []; shadowSpirits = []; pollutedSpirits = []; darkSpirits = []; riverSpirit = null; spawnTimer = 0; spawnInterval = 1200; // 20 seconds at 60fps for level1 shadowSpawnTimer = 0; shadowSpawnInterval = 360; // Level1 difficulty maxShadowSpirits = 2; // Level 1 limit shadowRespawnTimer = 0; scoreTxt = new Text2('Score: 0', { size: 80, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); tokenTxt = new Text2('Tokens: 0', { size: 60, fill: 0xFFD700 }); tokenTxt.anchor.set(1, 0); tokenTxt.x = -20; LK.gui.topRight.addChild(tokenTxt); healthBar = new HealthBar(); healthBar.x = 20; healthBar.y = 30; LK.gui.topLeft.addChild(healthBar); // Initial spawns for (var i = 0; i < 5; i++) { spawnToken(); } spawnSpirit(); spawnPollutedSpirit(); // Initialize brush sprite (initially hidden) brushSprite = LK.getAsset('brush', { anchorX: 0.5, anchorY: 0.5 }); brushSprite.visible = false; game.addChild(brushSprite); // Initialize shower area system showerAreas = []; pollutedSpawnTimer = 0; pollutedSpawnInterval = 600; // 10 seconds at 60fps // Add shower areas based on level var screenMiddle = 1024; var spacing = 200; var showerAreaWidth = 300; // Based on asset width if (currentLevel === 'level1') { // Level 1: 2 shower areas var leftShowerArea = game.addChild(LK.getAsset('Showerarea', { anchorX: 0.5, anchorY: 0.5, x: screenMiddle - spacing / 2 - showerAreaWidth / 2, y: 1366 // Middle of screen height })); leftShowerArea.occupied = false; showerAreas.push(leftShowerArea); var rightShowerArea = game.addChild(LK.getAsset('Showerarea', { anchorX: 0.5, anchorY: 0.5, x: screenMiddle + spacing / 2 + showerAreaWidth / 2, y: 1366 // Middle of screen height })); rightShowerArea.occupied = false; showerAreas.push(rightShowerArea); } else if (currentLevel === 'level2') { // Level 2: 4 shower areas in 2x2 grid var spacing = 500; // 500px spacing between shower areas var positions = [{ x: screenMiddle - spacing / 2, y: 1366 - spacing / 2 }, { x: screenMiddle + spacing / 2, y: 1366 - spacing / 2 }, { x: screenMiddle - spacing / 2, y: 1366 + spacing / 2 }, { x: screenMiddle + spacing / 2, y: 1366 + spacing / 2 }]; for (var p = 0; p < positions.length; p++) { var showerArea = game.addChild(LK.getAsset('Showerarea', { anchorX: 0.5, anchorY: 0.5, x: positions[p].x, y: positions[p].y })); showerArea.occupied = false; showerAreas.push(showerArea); } } else if (currentLevel === 'level3') { // Level 3: 6 shower areas in 3x2 grid var spacing = 500; // 500px spacing between shower areas var positions = [ // Top row (3 areas) { x: screenMiddle - spacing, y: 1366 - spacing / 2 }, { x: screenMiddle, y: 1366 - spacing / 2 }, { x: screenMiddle + spacing, y: 1366 - spacing / 2 }, // Bottom row (3 areas) { x: screenMiddle - spacing, y: 1366 + spacing / 2 }, { x: screenMiddle, y: 1366 + spacing / 2 }, { x: screenMiddle + spacing, y: 1366 + spacing / 2 }]; for (var p = 0; p < positions.length; p++) { var showerArea = game.addChild(LK.getAsset('Showerarea', { anchorX: 0.5, anchorY: 0.5, x: positions[p].x, y: positions[p].y })); showerArea.occupied = false; showerAreas.push(showerArea); } } else if (currentLevel === 'level4') { // Level 4: 6 shower areas in 2x3 grid var spacing = 500; // 500px spacing between shower areas var positions = [ // Left column (3 areas) { x: screenMiddle - spacing / 2, y: 1366 - spacing }, { x: screenMiddle - spacing / 2, y: 1366 }, { x: screenMiddle - spacing / 2, y: 1366 + spacing }, // Right column (3 areas) { x: screenMiddle + spacing / 2, y: 1366 - spacing }, { x: screenMiddle + spacing / 2, y: 1366 }, { x: screenMiddle + spacing / 2, y: 1366 + spacing }]; for (var p = 0; p < positions.length; p++) { var showerArea = game.addChild(LK.getAsset('Showerarea', { anchorX: 0.5, anchorY: 0.5, x: positions[p].x, y: positions[p].y })); showerArea.occupied = false; showerAreas.push(showerArea); } } // Move player to front to ensure it renders above shower areas game.removeChild(player); game.addChild(player); } var dragActive = false; var currentMovementSprite = 'player'; var movementAnimationTimer = 0; var movementAnimationInterval = 15; // Switch every 15 frames (quarter second at 60fps) game.down = function (x, y, obj) { if (!gameStarted && startButton) { // Check if click is within start button bounds var buttonLeft = startButton.x - startButton.width * startButton.anchor.x; var buttonRight = startButton.x + startButton.width * (1 - startButton.anchor.x); var buttonTop = startButton.y - startButton.height * startButton.anchor.y; var buttonBottom = startButton.y + startButton.height * (1 - startButton.anchor.y); if (x >= buttonLeft && x <= buttonRight && y >= buttonTop && y <= buttonBottom) { startGame(); return; } } if (gameStarted) { dragActive = true; } }; game.up = function (x, y, obj) { if (gameStarted) { dragActive = false; } }; game.move = function (x, y, obj) { if (gameStarted && dragActive && player) { player.x = x; player.y = y; // Throttle movement sound to prevent too frequent playback var currentTime = Date.now(); if (currentTime - lastMovementSoundTime >= movementSoundCooldown) { LK.getSound('playermovment').play(); lastMovementSoundTime = currentTime; } } }; game.update = function () { if (!gameStarted) { return; } // Update spawn timers spawnTimer++; shadowSpawnTimer++; if (spawnTimer >= spawnInterval) { spawnSpirit(); spawnTimer = 0; } if (shadowSpawnTimer >= shadowSpawnInterval) { spawnShadowSpirit(); shadowSpawnTimer = 0; } // Shadow spirit respawn timer shadowRespawnTimer++; if (shadowRespawnTimer >= shadowRespawnInterval && shadowSpirits.length < maxShadowSpirits) { spawnShadowSpirit(); shadowRespawnTimer = 0; } // Token spawning if (LK.ticks % 120 === 0) { spawnToken(); } // Polluted spirit spawning every 10 seconds pollutedSpawnTimer++; if (pollutedSpawnTimer >= pollutedSpawnInterval) { spawnPollutedSpirit(); pollutedSpawnTimer = 0; } // River spirit spawning if (LK.getScore() > 0 && LK.getScore() % 50 === 0 && !riverSpirit) { spawnRiverSpirit(); } // Check token collection for (var i = tokens.length - 1; i >= 0; i--) { var token = tokens[i]; if (!token.collected && player.intersects(token)) { token.collected = true; player.collectToken(); tokenTxt.setText('Tokens: ' + player.tokens); LK.getSound('collect').play(); token.destroy(); tokens.splice(i, 1); } } // Check spirit interactions for (var j = blueSpirits.length - 1; j >= 0; j--) { var spirit = blueSpirits[j]; if (!spirit.isDark && player.intersects(spirit) && player.tokens > 0) { player.tokens -= 1; // Only consume 1 token per spirit LK.setScore(LK.getScore() + 5); // Award 5 points per spirit freed scoreTxt.setText('Score: ' + LK.getScore()); tokenTxt.setText('Tokens: ' + player.tokens); LK.getSound('deliver').play(); // Remove one shadow spirit when blue spirit is freed if (shadowSpirits.length > 0) { var shadowToRemove = shadowSpirits[0]; shadowToRemove.destroy(); shadowSpirits.splice(0, 1); } spirit.destroy(); blueSpirits.splice(j, 1); } if (spirit.isDark && spirit.y > 2932) { spirit.destroy(); blueSpirits.splice(j, 1); } } // Check shadow spirit collisions for (var k = shadowSpirits.length - 1; k >= 0; k--) { var shadow = shadowSpirits[k]; if (shadow.lastIntersecting === undefined) { shadow.lastIntersecting = false; } var currentIntersecting = player.intersects(shadow); if (!shadow.lastIntersecting && currentIntersecting) { LK.getSound('damage').play(); var gameOver = player.takeDamage(); healthBar.updateHealth(player.health); if (gameOver) { LK.showGameOver(); } shadow.destroy(); shadowSpirits.splice(k, 1); continue; } shadow.lastIntersecting = currentIntersecting; } // Check dark spirit collisions for (var d = darkSpirits.length - 1; d >= 0; d--) { var darkSpirit = darkSpirits[d]; if (darkSpirit.lastIntersecting === undefined) { darkSpirit.lastIntersecting = false; } var currentDarkIntersecting = player.intersects(darkSpirit); if (!darkSpirit.lastIntersecting && currentDarkIntersecting) { LK.getSound('damage').play(); var gameOver = player.takeDamage(); healthBar.updateHealth(player.health); if (gameOver) { LK.showGameOver(); } darkSpirit.destroy(); darkSpirits.splice(d, 1); continue; } darkSpirit.lastIntersecting = currentDarkIntersecting; } // Check polluted spirit cleansing for (var l = pollutedSpirits.length - 1; l >= 0; l--) { var polluted = pollutedSpirits[l]; if (!polluted.isCleansed && player.intersects(polluted) && player.tokens >= polluted.tokensNeeded) { player.tokens -= polluted.tokensNeeded; tokenTxt.setText('Tokens: ' + player.tokens); LK.setScore(LK.getScore() + 15); scoreTxt.setText('Score: ' + LK.getScore()); LK.getSound('cleanse').play(); // Remove one darkspirit when polluted spirit is cleansed if (darkSpirits.length > 0) { var darkToRemove = darkSpirits[0]; darkToRemove.destroy(); darkSpirits.splice(0, 1); } // Show and animate brush if (brushSprite) { brushSprite.visible = true; brushSprite.x = polluted.x; brushSprite.y = polluted.y; // Stop any existing brush animations tween.stop(brushSprite); // Animate brush left and right to simulate brushing tween(brushSprite, { x: polluted.x - 30 }, { duration: 200, easing: tween.easeInOut, onFinish: function onFinish() { tween(brushSprite, { x: polluted.x + 30 }, { duration: 200, easing: tween.easeInOut, onFinish: function onFinish() { tween(brushSprite, { x: polluted.x - 20 }, { duration: 150, easing: tween.easeInOut, onFinish: function onFinish() { tween(brushSprite, { x: polluted.x + 20 }, { duration: 150, easing: tween.easeInOut, onFinish: function onFinish() { tween(brushSprite, { x: polluted.x }, { duration: 100, easing: tween.easeInOut, onFinish: function onFinish() { brushSprite.visible = false; } }); } }); } }); } }); } }); } // Free up the shower area if (polluted.assignedShowerArea) { polluted.assignedShowerArea.occupied = false; } polluted.cleanse(); pollutedSpirits.splice(l, 1); } } // Check river spirit collection if (riverSpirit) { if (riverSpirit.lastIntersecting === undefined) { riverSpirit.lastIntersecting = false; } var riverIntersecting = player.intersects(riverSpirit); if (!riverSpirit.lastIntersecting && riverIntersecting) { LK.setScore(LK.getScore() + riverSpirit.bonusValue); scoreTxt.setText('Score: ' + LK.getScore()); // Regenerate health by 30% player.health += player.maxHealth * 0.3; player.health = Math.min(player.health, player.maxHealth); // Cap at max health healthBar.updateHealth(player.health); LK.effects.flashObject(player, 0x87ceeb, 1000); // Flash blue to indicate healing riverSpirit.destroy(); riverSpirit = null; } else if (riverSpirit && riverSpirit.x > 2200) { riverSpirit.destroy(); riverSpirit = null; } if (riverSpirit) { riverSpirit.lastIntersecting = riverIntersecting; } } // Handle movement animation when dragging if (dragActive && player) { movementAnimationTimer++; if (movementAnimationTimer >= movementAnimationInterval) { // Switch between movement sprites if (currentMovementSprite === 'player') { currentMovementSprite = 'playermovement1'; } else if (currentMovementSprite === 'playermovement1') { currentMovementSprite = 'playermovement2'; } else { currentMovementSprite = 'playermovement1'; } // Update player sprite player.removeChildren(); var newPlayerGraphics = player.attachAsset(currentMovementSprite, { anchorX: 0.5, anchorY: 0.5 }); movementAnimationTimer = 0; } } else if (!dragActive && currentMovementSprite !== 'player') { // Reset to normal player sprite when not dragging currentMovementSprite = 'player'; player.removeChildren(); var normalPlayerGraphics = player.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); } // Player direction based on position var screenMiddle = 1024; if (player.x < screenMiddle) { // Player is on left side, face left (flip horizontally) player.scaleX = -1; } else { // Player is on right side, face right (normal orientation) player.scaleX = 1; } // Level progression if (currentLevel === 'level1' && LK.getScore() >= 250) { startLevel('level2'); } if (currentLevel === 'level2' && LK.getScore() >= 500) { startLevel('level3'); } if (currentLevel === 'level3' && LK.getScore() >= 750) { startLevel('level4'); } // Win condition if (currentLevel === 'level4' && LK.getScore() >= 1000) { LK.showYouWin(); } }; // Show intro screen initially showIntroScreen();
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var BlueSpirit = Container.expand(function () {
var self = Container.call(this);
var spiritGraphics = self.attachAsset('blueSpirit', {
anchorX: 0.5,
anchorY: 0.5
});
self.waitTime = 0;
self.maxWaitTime = 600; // 10 seconds at 60fps (default for both levels)
self.isDark = false;
self.speed = 1;
self.update = function () {
self.waitTime++;
// Set maxWaitTime based on current level
if (currentLevel === 'level1') {
self.maxWaitTime = 600; // 10 seconds at 60fps
} else if (currentLevel === 'level2') {
self.maxWaitTime = 600; // 10 seconds at 60fps
}
if (!self.isDark && self.waitTime >= self.maxWaitTime) {
self.turnDark();
}
if (self.isDark) {
self.y += self.speed;
}
};
self.turnDark = function () {
self.isDark = true;
spiritGraphics.tint = 0x2a0845;
tween(spiritGraphics, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 500
});
};
return self;
});
var DarkSpirit = Container.expand(function () {
var self = Container.call(this);
var darkGraphics = self.attachAsset('darkSpirit', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 1.5;
self.targetPlayer = null;
self.update = function () {
if (self.targetPlayer) {
var dx = self.targetPlayer.x - self.x;
var dy = self.targetPlayer.y - 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;
}
// Change direction based on position relative to screen middle
var screenMiddle = 1024;
if (self.x < screenMiddle) {
// Dark spirit is on left side, face right towards middle
self.scaleX = 1;
} else {
// Dark spirit is on right side, face left towards middle
self.scaleX = -1;
}
}
};
return self;
});
var HealthBar = Container.expand(function () {
var self = Container.call(this);
// Background bar
self.bgBar = self.attachAsset('healthBarBg', {
anchorX: 0,
anchorY: 0
});
// Health bar
self.healthBar = self.attachAsset('healthBarFill', {
anchorX: 0,
anchorY: 0
});
self.maxWidth = 300;
self.updateHealth = function (healthPercent) {
self.healthBar.scaleX = healthPercent / 100;
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.tokens = 0;
self.health = 100;
self.maxHealth = 100;
self.collectToken = function () {
self.tokens++;
};
self.deliverTokens = function () {
var delivered = self.tokens;
self.tokens = 0;
return delivered;
};
self.takeDamage = function () {
var damage = Math.random() * 7 + 3; // Random between 3-10
self.health -= damage;
self.health = Math.max(0, self.health); // Ensure health doesn't go below 0
LK.effects.flashObject(self, 0xff0000, 500);
return self.health <= 0;
};
return self;
});
var PollutedSpirit = Container.expand(function () {
var self = Container.call(this);
var pollutedGraphics = self.attachAsset('pollutedspirit1', {
anchorX: 0.5,
anchorY: 0.5
});
self.tokensNeeded = 3;
self.isCleansed = false;
self.cleanse = function () {
self.isCleansed = true;
tween(pollutedGraphics, {
tint: 0x98fb98
}, {
duration: 1000,
onFinish: function onFinish() {
self.destroy();
}
});
};
return self;
});
var PollutedSpirit2 = Container.expand(function () {
var self = Container.call(this);
var pollutedGraphics = self.attachAsset('pollutedspirit2', {
anchorX: 0.5,
anchorY: 0.5
});
self.tokensNeeded = 3;
self.isCleansed = false;
self.cleanse = function () {
self.isCleansed = true;
tween(pollutedGraphics, {
tint: 0x98fb98
}, {
duration: 1000,
onFinish: function onFinish() {
self.destroy();
}
});
};
return self;
});
var PollutedSpirit3 = Container.expand(function () {
var self = Container.call(this);
var pollutedGraphics = self.attachAsset('pollutedspirit3', {
anchorX: 0.5,
anchorY: 0.5
});
self.tokensNeeded = 3;
self.isCleansed = false;
self.cleanse = function () {
self.isCleansed = true;
tween(pollutedGraphics, {
tint: 0x98fb98
}, {
duration: 1000,
onFinish: function onFinish() {
self.destroy();
}
});
};
return self;
});
var PollutedSpirit4 = Container.expand(function () {
var self = Container.call(this);
var pollutedGraphics = self.attachAsset('pollutedspirit4', {
anchorX: 0.5,
anchorY: 0.5
});
self.tokensNeeded = 3;
self.isCleansed = false;
self.cleanse = function () {
self.isCleansed = true;
tween(pollutedGraphics, {
tint: 0x98fb98
}, {
duration: 1000,
onFinish: function onFinish() {
self.destroy();
}
});
};
return self;
});
var PollutedSpirit5 = Container.expand(function () {
var self = Container.call(this);
var pollutedGraphics = self.attachAsset('pollutedspirit5', {
anchorX: 0.5,
anchorY: 0.5
});
self.tokensNeeded = 3;
self.isCleansed = false;
self.cleanse = function () {
self.isCleansed = true;
tween(pollutedGraphics, {
tint: 0x98fb98
}, {
duration: 1000,
onFinish: function onFinish() {
self.destroy();
}
});
};
return self;
});
var PollutedSpirit6 = Container.expand(function () {
var self = Container.call(this);
var pollutedGraphics = self.attachAsset('pollutedspirit6', {
anchorX: 0.5,
anchorY: 0.5
});
self.tokensNeeded = 3;
self.isCleansed = false;
self.cleanse = function () {
self.isCleansed = true;
tween(pollutedGraphics, {
tint: 0x98fb98
}, {
duration: 1000,
onFinish: function onFinish() {
self.destroy();
}
});
};
return self;
});
var PollutedSpirit7 = Container.expand(function () {
var self = Container.call(this);
var pollutedGraphics = self.attachAsset('pollutedspirit7', {
anchorX: 0.5,
anchorY: 0.5
});
self.tokensNeeded = 3;
self.isCleansed = false;
self.cleanse = function () {
self.isCleansed = true;
tween(pollutedGraphics, {
tint: 0x98fb98
}, {
duration: 1000,
onFinish: function onFinish() {
self.destroy();
}
});
};
return self;
});
var PollutedSpirit8 = Container.expand(function () {
var self = Container.call(this);
var pollutedGraphics = self.attachAsset('pollutedspirit8', {
anchorX: 0.5,
anchorY: 0.5
});
self.tokensNeeded = 3;
self.isCleansed = false;
self.cleanse = function () {
self.isCleansed = true;
tween(pollutedGraphics, {
tint: 0x98fb98
}, {
duration: 1000,
onFinish: function onFinish() {
self.destroy();
}
});
};
return self;
});
var RiverSpirit = Container.expand(function () {
var self = Container.call(this);
var riverGraphics = self.attachAsset('riverSpirit', {
anchorX: 0.5,
anchorY: 0.5
});
self.bonusValue = 20;
self.speed = 0.5;
self.update = function () {
self.x += self.speed;
self.rotation += 0.01;
};
return self;
});
var ShadowSpirit = Container.expand(function () {
var self = Container.call(this);
var shadowGraphics = self.attachAsset('shadowSpirit', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2;
self.targetPlayer = null;
self.update = function () {
if (self.targetPlayer) {
var dx = self.targetPlayer.x - self.x;
var dy = self.targetPlayer.y - 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;
}
// Change direction based on position relative to screen middle
var screenMiddle = 1024;
if (self.x < screenMiddle) {
// Shadow is on left side, face right towards middle
self.scaleX = 1;
} else {
// Shadow is on right side, face left towards middle
self.scaleX = -1;
}
}
};
return self;
});
var Token = Container.expand(function () {
var self = Container.call(this);
var tokenGraphics = self.attachAsset('token', {
anchorX: 0.5,
anchorY: 0.5
});
self.collected = false;
self.update = function () {
if (!self.collected) {
self.rotation += 0.02;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a2e
});
/****
* Game Code
****/
var gameStarted = false;
var introBackground = null;
var startButton = null;
var currentLevel = 'level1';
var gameBackground = null;
// Declare game variables in global scope
var player, tokens, blueSpirits, shadowSpirits, pollutedSpirits, riverSpirit, darkSpirits;
var spawnTimer, spawnInterval, shadowSpawnTimer, shadowSpawnInterval;
var scoreTxt, tokenTxt, healthBar;
var brushSprite = null;
var showerAreas = [],
pollutedSpawnTimer,
pollutedSpawnInterval;
var maxShadowSpirits = 2; // Level 1: 2, Level 2: 4
var shadowRespawnTimer = 0;
var shadowRespawnInterval = 180; // 3 seconds to respawn
var lastMovementSoundTime = 0;
var movementSoundCooldown = 1000; // Milliseconds between sound plays
// Show intro screen
function showIntroScreen() {
introBackground = game.addChild(LK.getAsset('introbackground', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
}));
startButton = game.addChild(LK.getAsset('startbutton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 2400
}));
// Only play intro music if game hasn't started and we're actually showing intro screen
if (!gameStarted && introBackground && startButton) {
LK.playMusic('intromusic');
}
}
// Start the actual game
function startGame() {
gameStarted = true;
if (introBackground) {
introBackground.destroy();
introBackground = null;
}
if (startButton) {
startButton.destroy();
startButton = null;
}
LK.stopMusic();
LK.playMusic('level1music');
initializeGame();
}
// Spawn functions in global scope
function spawnToken() {
var token = new Token();
token.x = Math.random() * 1848 + 100;
token.y = Math.random() * 2332 + 300;
tokens.push(token);
game.addChild(token);
}
function spawnSpirit() {
var spirit = new BlueSpirit();
spirit.x = Math.random() * 1848 + 100;
spirit.y = 300;
blueSpirits.push(spirit);
game.addChild(spirit);
}
function spawnShadowSpirit() {
// Only spawn if under the limit
if (shadowSpirits.length < maxShadowSpirits) {
var shadow = new ShadowSpirit();
shadow.x = Math.random() * 1848 + 100;
shadow.y = Math.random() * 400 + 300;
shadow.targetPlayer = player;
shadowSpirits.push(shadow);
game.addChild(shadow);
LK.getSound('Shadowspiritsound').play();
}
}
function spawnPollutedSpirit() {
// Find an empty shower area
var emptyAreas = [];
for (var i = 0; i < showerAreas.length; i++) {
if (!showerAreas[i].occupied) {
emptyAreas.push(showerAreas[i]);
}
}
// Only spawn if there's an empty area
if (emptyAreas.length > 0) {
if (currentLevel === 'level4') {
// Level 4: Spawn only PollutedSpirit6, PollutedSpirit7, PollutedSpirit8
if (emptyAreas.length >= 3) {
var pollutedTypes = [PollutedSpirit6, PollutedSpirit7, PollutedSpirit8];
for (var t = 0; t < pollutedTypes.length; t++) {
var selectedArea = emptyAreas[Math.floor(Math.random() * emptyAreas.length)];
var polluted = new pollutedTypes[t]();
polluted.x = selectedArea.x;
polluted.y = selectedArea.y;
polluted.assignedShowerArea = selectedArea;
selectedArea.occupied = true;
pollutedSpirits.push(polluted);
game.addChild(polluted);
// Spawn DarkSpirit behind polluted spirit
var dark = new DarkSpirit();
dark.x = polluted.x - 50;
dark.y = polluted.y + 30;
dark.targetPlayer = player;
darkSpirits.push(dark);
game.addChild(dark);
LK.getSound('darkspiritsound').play();
// Remove the used area from available areas
emptyAreas.splice(emptyAreas.indexOf(selectedArea), 1);
}
} else {
// Spawn random types based on available areas
var pollutedTypes = [PollutedSpirit6, PollutedSpirit7, PollutedSpirit8];
for (var a = 0; a < Math.min(emptyAreas.length, 3); a++) {
var selectedArea = emptyAreas[Math.floor(Math.random() * emptyAreas.length)];
var randomType = pollutedTypes[Math.floor(Math.random() * pollutedTypes.length)];
var polluted = new randomType();
polluted.x = selectedArea.x;
polluted.y = selectedArea.y;
polluted.assignedShowerArea = selectedArea;
selectedArea.occupied = true;
pollutedSpirits.push(polluted);
game.addChild(polluted);
// Spawn DarkSpirit behind polluted spirit
var dark = new DarkSpirit();
dark.x = polluted.x - 50;
dark.y = polluted.y + 30;
dark.targetPlayer = player;
darkSpirits.push(dark);
game.addChild(dark);
LK.getSound('darkspiritsound').play();
// Remove the used area from available areas
emptyAreas.splice(emptyAreas.indexOf(selectedArea), 1);
}
}
} else if (currentLevel === 'level3') {
// Level 3: Spawn all 5 types if we have at least 5 empty areas
if (emptyAreas.length >= 5) {
var pollutedTypes = [PollutedSpirit, PollutedSpirit2, PollutedSpirit3, PollutedSpirit4, PollutedSpirit5];
for (var t = 0; t < pollutedTypes.length; t++) {
var selectedArea = emptyAreas[Math.floor(Math.random() * emptyAreas.length)];
var polluted = new pollutedTypes[t]();
polluted.x = selectedArea.x;
polluted.y = selectedArea.y;
polluted.assignedShowerArea = selectedArea;
selectedArea.occupied = true;
pollutedSpirits.push(polluted);
game.addChild(polluted);
// Spawn DarkSpirit behind polluted spirit
var dark = new DarkSpirit();
dark.x = polluted.x - 50;
dark.y = polluted.y + 30;
dark.targetPlayer = player;
darkSpirits.push(dark);
game.addChild(dark);
LK.getSound('darkspiritsound').play();
// Remove the used area from available areas
emptyAreas.splice(emptyAreas.indexOf(selectedArea), 1);
}
} else {
// Spawn random types based on available areas
var pollutedTypes = [PollutedSpirit, PollutedSpirit2, PollutedSpirit3, PollutedSpirit4, PollutedSpirit5];
for (var a = 0; a < Math.min(emptyAreas.length, 3); a++) {
var selectedArea = emptyAreas[Math.floor(Math.random() * emptyAreas.length)];
var randomType = pollutedTypes[Math.floor(Math.random() * pollutedTypes.length)];
var polluted = new randomType();
polluted.x = selectedArea.x;
polluted.y = selectedArea.y;
polluted.assignedShowerArea = selectedArea;
selectedArea.occupied = true;
pollutedSpirits.push(polluted);
game.addChild(polluted);
// Spawn DarkSpirit behind polluted spirit
var dark = new DarkSpirit();
dark.x = polluted.x - 50;
dark.y = polluted.y + 30;
dark.targetPlayer = player;
darkSpirits.push(dark);
game.addChild(dark);
LK.getSound('darkspiritsound').play();
// Remove the used area from available areas
emptyAreas.splice(emptyAreas.indexOf(selectedArea), 1);
}
}
} else if (currentLevel === 'level2') {
// Level 2: Spawn both types if we have at least 2 empty areas
if (emptyAreas.length >= 2) {
// Spawn PollutedSpirit (pollutedspirit1)
var selectedArea1 = emptyAreas[Math.floor(Math.random() * emptyAreas.length)];
var polluted1 = new PollutedSpirit();
polluted1.x = selectedArea1.x;
polluted1.y = selectedArea1.y;
polluted1.assignedShowerArea = selectedArea1;
selectedArea1.occupied = true;
pollutedSpirits.push(polluted1);
game.addChild(polluted1);
// Remove the used area from available areas
emptyAreas.splice(emptyAreas.indexOf(selectedArea1), 1);
// Spawn PollutedSpirit2 (pollutedspirit2)
var selectedArea2 = emptyAreas[Math.floor(Math.random() * emptyAreas.length)];
var polluted2 = new PollutedSpirit2();
polluted2.x = selectedArea2.x;
polluted2.y = selectedArea2.y;
polluted2.assignedShowerArea = selectedArea2;
selectedArea2.occupied = true;
pollutedSpirits.push(polluted2);
game.addChild(polluted2);
// Spawn DarkSpirit behind polluted2
var dark2 = new DarkSpirit();
dark2.x = polluted2.x - 50;
dark2.y = polluted2.y + 30;
dark2.targetPlayer = player;
darkSpirits.push(dark2);
game.addChild(dark2);
LK.getSound('darkspiritsound').play();
} else {
// Only one empty area, spawn randomly either type
var selectedArea = emptyAreas[0];
var polluted = Math.random() < 0.5 ? new PollutedSpirit() : new PollutedSpirit2();
polluted.x = selectedArea.x;
polluted.y = selectedArea.y;
polluted.assignedShowerArea = selectedArea;
selectedArea.occupied = true;
pollutedSpirits.push(polluted);
game.addChild(polluted);
}
} else {
// Level 1: Spawn only PollutedSpirit (pollutedspirit1)
var selectedArea = emptyAreas[Math.floor(Math.random() * emptyAreas.length)];
var polluted = new PollutedSpirit();
polluted.x = selectedArea.x;
polluted.y = selectedArea.y;
polluted.assignedShowerArea = selectedArea;
selectedArea.occupied = true;
pollutedSpirits.push(polluted);
game.addChild(polluted);
// Spawn DarkSpirit behind polluted spirit in level1
var dark = new DarkSpirit();
dark.x = polluted.x - 50;
dark.y = polluted.y + 30;
dark.targetPlayer = player;
darkSpirits.push(dark);
game.addChild(dark);
LK.getSound('darkspiritsound').play();
}
// Move brush sprite to render on top of polluted spirits
if (brushSprite) {
game.removeChild(brushSprite);
game.addChild(brushSprite);
}
// Ensure player renders on top of polluted spirits
if (player) {
game.removeChild(player);
game.addChild(player);
}
}
}
function spawnRiverSpirit() {
if (!riverSpirit) {
riverSpirit = new RiverSpirit();
riverSpirit.x = -100;
riverSpirit.y = Math.random() * 1000 + 1066;
game.addChild(riverSpirit);
}
}
function startLevel(levelName) {
currentLevel = levelName;
// Remove current background
if (gameBackground) {
gameBackground.destroy();
gameBackground = null;
}
// Stop current music and play appropriate level music
LK.stopMusic();
if (levelName === 'level2') {
LK.playMusic('level2music');
} else if (levelName === 'level3') {
LK.playMusic('level3music');
} else if (levelName === 'level4') {
LK.playMusic('level4music');
} else if (levelName === 'level1') {
LK.playMusic('level1music');
}
// Clear all existing enemies from previous level
for (var i = blueSpirits.length - 1; i >= 0; i--) {
blueSpirits[i].destroy();
}
blueSpirits = [];
for (var j = shadowSpirits.length - 1; j >= 0; j--) {
shadowSpirits[j].destroy();
}
shadowSpirits = [];
for (var d = darkSpirits.length - 1; d >= 0; d--) {
darkSpirits[d].destroy();
}
darkSpirits = [];
for (var k = pollutedSpirits.length - 1; k >= 0; k--) {
if (pollutedSpirits[k].assignedShowerArea) {
pollutedSpirits[k].assignedShowerArea.occupied = false;
}
pollutedSpirits[k].destroy();
}
pollutedSpirits = [];
if (riverSpirit) {
riverSpirit.destroy();
riverSpirit = null;
}
// Remove existing shower areas
for (var i = 0; i < showerAreas.length; i++) {
showerAreas[i].destroy();
}
showerAreas = [];
// Add level background
gameBackground = game.addChild(LK.getAsset('background02', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
visible: true
}));
// Add shower areas based on level
var screenMiddle = 1024;
var spacing = 500; // 500px spacing between shower areas
var positions = [];
if (levelName === 'level2') {
// Level 2: 4 shower areas in 2x2 grid
positions = [{
x: screenMiddle - spacing / 2,
y: 1366 - spacing / 2
}, {
x: screenMiddle + spacing / 2,
y: 1366 - spacing / 2
}, {
x: screenMiddle - spacing / 2,
y: 1366 + spacing / 2
}, {
x: screenMiddle + spacing / 2,
y: 1366 + spacing / 2
}];
} else if (levelName === 'level3') {
// Level 3: 6 shower areas in 3x2 grid
positions = [
// Top row (3 areas)
{
x: screenMiddle - spacing,
y: 1366 - spacing / 2
}, {
x: screenMiddle,
y: 1366 - spacing / 2
}, {
x: screenMiddle + spacing,
y: 1366 - spacing / 2
},
// Bottom row (3 areas)
{
x: screenMiddle - spacing,
y: 1366 + spacing / 2
}, {
x: screenMiddle,
y: 1366 + spacing / 2
}, {
x: screenMiddle + spacing,
y: 1366 + spacing / 2
}];
} else if (levelName === 'level4') {
// Level 4: 6 shower areas in 2x3 grid
positions = [
// Left column (3 areas)
{
x: screenMiddle - spacing / 2,
y: 1366 - spacing
}, {
x: screenMiddle - spacing / 2,
y: 1366
}, {
x: screenMiddle - spacing / 2,
y: 1366 + spacing
},
// Right column (3 areas)
{
x: screenMiddle + spacing / 2,
y: 1366 - spacing
}, {
x: screenMiddle + spacing / 2,
y: 1366
}, {
x: screenMiddle + spacing / 2,
y: 1366 + spacing
}];
}
for (var p = 0; p < positions.length; p++) {
var showerArea = game.addChild(LK.getAsset('Showerarea', {
anchorX: 0.5,
anchorY: 0.5,
x: positions[p].x,
y: positions[p].y
}));
showerArea.occupied = false;
showerAreas.push(showerArea);
}
// Move player to front to ensure it renders above the new background
game.removeChild(player);
game.addChild(player);
// Reset game state for new level
player.health = player.maxHealth;
healthBar.updateHealth(player.health);
spawnInterval = 1200; // 20 seconds at 60fps
shadowSpawnInterval = 240;
if (levelName === 'level2') {
maxShadowSpirits = 4; // Increase limit for level2
} else if (levelName === 'level3') {
maxShadowSpirits = 6; // Increase limit for level3
} else if (levelName === 'level4') {
maxShadowSpirits = 8; // Increase limit for level4
}
}
function initializeGame() {
game.setBackgroundColor(0x16213e);
currentLevel = 'level1';
// Add level1 game background
gameBackground = game.addChild(LK.getAsset('gamebackground', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
}));
player = game.addChild(new Player());
player.x = 1024;
player.y = 2200;
tokens = [];
blueSpirits = [];
shadowSpirits = [];
pollutedSpirits = [];
darkSpirits = [];
riverSpirit = null;
spawnTimer = 0;
spawnInterval = 1200; // 20 seconds at 60fps for level1
shadowSpawnTimer = 0;
shadowSpawnInterval = 360; // Level1 difficulty
maxShadowSpirits = 2; // Level 1 limit
shadowRespawnTimer = 0;
scoreTxt = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
tokenTxt = new Text2('Tokens: 0', {
size: 60,
fill: 0xFFD700
});
tokenTxt.anchor.set(1, 0);
tokenTxt.x = -20;
LK.gui.topRight.addChild(tokenTxt);
healthBar = new HealthBar();
healthBar.x = 20;
healthBar.y = 30;
LK.gui.topLeft.addChild(healthBar);
// Initial spawns
for (var i = 0; i < 5; i++) {
spawnToken();
}
spawnSpirit();
spawnPollutedSpirit();
// Initialize brush sprite (initially hidden)
brushSprite = LK.getAsset('brush', {
anchorX: 0.5,
anchorY: 0.5
});
brushSprite.visible = false;
game.addChild(brushSprite);
// Initialize shower area system
showerAreas = [];
pollutedSpawnTimer = 0;
pollutedSpawnInterval = 600; // 10 seconds at 60fps
// Add shower areas based on level
var screenMiddle = 1024;
var spacing = 200;
var showerAreaWidth = 300; // Based on asset width
if (currentLevel === 'level1') {
// Level 1: 2 shower areas
var leftShowerArea = game.addChild(LK.getAsset('Showerarea', {
anchorX: 0.5,
anchorY: 0.5,
x: screenMiddle - spacing / 2 - showerAreaWidth / 2,
y: 1366 // Middle of screen height
}));
leftShowerArea.occupied = false;
showerAreas.push(leftShowerArea);
var rightShowerArea = game.addChild(LK.getAsset('Showerarea', {
anchorX: 0.5,
anchorY: 0.5,
x: screenMiddle + spacing / 2 + showerAreaWidth / 2,
y: 1366 // Middle of screen height
}));
rightShowerArea.occupied = false;
showerAreas.push(rightShowerArea);
} else if (currentLevel === 'level2') {
// Level 2: 4 shower areas in 2x2 grid
var spacing = 500; // 500px spacing between shower areas
var positions = [{
x: screenMiddle - spacing / 2,
y: 1366 - spacing / 2
}, {
x: screenMiddle + spacing / 2,
y: 1366 - spacing / 2
}, {
x: screenMiddle - spacing / 2,
y: 1366 + spacing / 2
}, {
x: screenMiddle + spacing / 2,
y: 1366 + spacing / 2
}];
for (var p = 0; p < positions.length; p++) {
var showerArea = game.addChild(LK.getAsset('Showerarea', {
anchorX: 0.5,
anchorY: 0.5,
x: positions[p].x,
y: positions[p].y
}));
showerArea.occupied = false;
showerAreas.push(showerArea);
}
} else if (currentLevel === 'level3') {
// Level 3: 6 shower areas in 3x2 grid
var spacing = 500; // 500px spacing between shower areas
var positions = [
// Top row (3 areas)
{
x: screenMiddle - spacing,
y: 1366 - spacing / 2
}, {
x: screenMiddle,
y: 1366 - spacing / 2
}, {
x: screenMiddle + spacing,
y: 1366 - spacing / 2
},
// Bottom row (3 areas)
{
x: screenMiddle - spacing,
y: 1366 + spacing / 2
}, {
x: screenMiddle,
y: 1366 + spacing / 2
}, {
x: screenMiddle + spacing,
y: 1366 + spacing / 2
}];
for (var p = 0; p < positions.length; p++) {
var showerArea = game.addChild(LK.getAsset('Showerarea', {
anchorX: 0.5,
anchorY: 0.5,
x: positions[p].x,
y: positions[p].y
}));
showerArea.occupied = false;
showerAreas.push(showerArea);
}
} else if (currentLevel === 'level4') {
// Level 4: 6 shower areas in 2x3 grid
var spacing = 500; // 500px spacing between shower areas
var positions = [
// Left column (3 areas)
{
x: screenMiddle - spacing / 2,
y: 1366 - spacing
}, {
x: screenMiddle - spacing / 2,
y: 1366
}, {
x: screenMiddle - spacing / 2,
y: 1366 + spacing
},
// Right column (3 areas)
{
x: screenMiddle + spacing / 2,
y: 1366 - spacing
}, {
x: screenMiddle + spacing / 2,
y: 1366
}, {
x: screenMiddle + spacing / 2,
y: 1366 + spacing
}];
for (var p = 0; p < positions.length; p++) {
var showerArea = game.addChild(LK.getAsset('Showerarea', {
anchorX: 0.5,
anchorY: 0.5,
x: positions[p].x,
y: positions[p].y
}));
showerArea.occupied = false;
showerAreas.push(showerArea);
}
}
// Move player to front to ensure it renders above shower areas
game.removeChild(player);
game.addChild(player);
}
var dragActive = false;
var currentMovementSprite = 'player';
var movementAnimationTimer = 0;
var movementAnimationInterval = 15; // Switch every 15 frames (quarter second at 60fps)
game.down = function (x, y, obj) {
if (!gameStarted && startButton) {
// Check if click is within start button bounds
var buttonLeft = startButton.x - startButton.width * startButton.anchor.x;
var buttonRight = startButton.x + startButton.width * (1 - startButton.anchor.x);
var buttonTop = startButton.y - startButton.height * startButton.anchor.y;
var buttonBottom = startButton.y + startButton.height * (1 - startButton.anchor.y);
if (x >= buttonLeft && x <= buttonRight && y >= buttonTop && y <= buttonBottom) {
startGame();
return;
}
}
if (gameStarted) {
dragActive = true;
}
};
game.up = function (x, y, obj) {
if (gameStarted) {
dragActive = false;
}
};
game.move = function (x, y, obj) {
if (gameStarted && dragActive && player) {
player.x = x;
player.y = y;
// Throttle movement sound to prevent too frequent playback
var currentTime = Date.now();
if (currentTime - lastMovementSoundTime >= movementSoundCooldown) {
LK.getSound('playermovment').play();
lastMovementSoundTime = currentTime;
}
}
};
game.update = function () {
if (!gameStarted) {
return;
}
// Update spawn timers
spawnTimer++;
shadowSpawnTimer++;
if (spawnTimer >= spawnInterval) {
spawnSpirit();
spawnTimer = 0;
}
if (shadowSpawnTimer >= shadowSpawnInterval) {
spawnShadowSpirit();
shadowSpawnTimer = 0;
}
// Shadow spirit respawn timer
shadowRespawnTimer++;
if (shadowRespawnTimer >= shadowRespawnInterval && shadowSpirits.length < maxShadowSpirits) {
spawnShadowSpirit();
shadowRespawnTimer = 0;
}
// Token spawning
if (LK.ticks % 120 === 0) {
spawnToken();
}
// Polluted spirit spawning every 10 seconds
pollutedSpawnTimer++;
if (pollutedSpawnTimer >= pollutedSpawnInterval) {
spawnPollutedSpirit();
pollutedSpawnTimer = 0;
}
// River spirit spawning
if (LK.getScore() > 0 && LK.getScore() % 50 === 0 && !riverSpirit) {
spawnRiverSpirit();
}
// Check token collection
for (var i = tokens.length - 1; i >= 0; i--) {
var token = tokens[i];
if (!token.collected && player.intersects(token)) {
token.collected = true;
player.collectToken();
tokenTxt.setText('Tokens: ' + player.tokens);
LK.getSound('collect').play();
token.destroy();
tokens.splice(i, 1);
}
}
// Check spirit interactions
for (var j = blueSpirits.length - 1; j >= 0; j--) {
var spirit = blueSpirits[j];
if (!spirit.isDark && player.intersects(spirit) && player.tokens > 0) {
player.tokens -= 1; // Only consume 1 token per spirit
LK.setScore(LK.getScore() + 5); // Award 5 points per spirit freed
scoreTxt.setText('Score: ' + LK.getScore());
tokenTxt.setText('Tokens: ' + player.tokens);
LK.getSound('deliver').play();
// Remove one shadow spirit when blue spirit is freed
if (shadowSpirits.length > 0) {
var shadowToRemove = shadowSpirits[0];
shadowToRemove.destroy();
shadowSpirits.splice(0, 1);
}
spirit.destroy();
blueSpirits.splice(j, 1);
}
if (spirit.isDark && spirit.y > 2932) {
spirit.destroy();
blueSpirits.splice(j, 1);
}
}
// Check shadow spirit collisions
for (var k = shadowSpirits.length - 1; k >= 0; k--) {
var shadow = shadowSpirits[k];
if (shadow.lastIntersecting === undefined) {
shadow.lastIntersecting = false;
}
var currentIntersecting = player.intersects(shadow);
if (!shadow.lastIntersecting && currentIntersecting) {
LK.getSound('damage').play();
var gameOver = player.takeDamage();
healthBar.updateHealth(player.health);
if (gameOver) {
LK.showGameOver();
}
shadow.destroy();
shadowSpirits.splice(k, 1);
continue;
}
shadow.lastIntersecting = currentIntersecting;
}
// Check dark spirit collisions
for (var d = darkSpirits.length - 1; d >= 0; d--) {
var darkSpirit = darkSpirits[d];
if (darkSpirit.lastIntersecting === undefined) {
darkSpirit.lastIntersecting = false;
}
var currentDarkIntersecting = player.intersects(darkSpirit);
if (!darkSpirit.lastIntersecting && currentDarkIntersecting) {
LK.getSound('damage').play();
var gameOver = player.takeDamage();
healthBar.updateHealth(player.health);
if (gameOver) {
LK.showGameOver();
}
darkSpirit.destroy();
darkSpirits.splice(d, 1);
continue;
}
darkSpirit.lastIntersecting = currentDarkIntersecting;
}
// Check polluted spirit cleansing
for (var l = pollutedSpirits.length - 1; l >= 0; l--) {
var polluted = pollutedSpirits[l];
if (!polluted.isCleansed && player.intersects(polluted) && player.tokens >= polluted.tokensNeeded) {
player.tokens -= polluted.tokensNeeded;
tokenTxt.setText('Tokens: ' + player.tokens);
LK.setScore(LK.getScore() + 15);
scoreTxt.setText('Score: ' + LK.getScore());
LK.getSound('cleanse').play();
// Remove one darkspirit when polluted spirit is cleansed
if (darkSpirits.length > 0) {
var darkToRemove = darkSpirits[0];
darkToRemove.destroy();
darkSpirits.splice(0, 1);
}
// Show and animate brush
if (brushSprite) {
brushSprite.visible = true;
brushSprite.x = polluted.x;
brushSprite.y = polluted.y;
// Stop any existing brush animations
tween.stop(brushSprite);
// Animate brush left and right to simulate brushing
tween(brushSprite, {
x: polluted.x - 30
}, {
duration: 200,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(brushSprite, {
x: polluted.x + 30
}, {
duration: 200,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(brushSprite, {
x: polluted.x - 20
}, {
duration: 150,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(brushSprite, {
x: polluted.x + 20
}, {
duration: 150,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(brushSprite, {
x: polluted.x
}, {
duration: 100,
easing: tween.easeInOut,
onFinish: function onFinish() {
brushSprite.visible = false;
}
});
}
});
}
});
}
});
}
});
}
// Free up the shower area
if (polluted.assignedShowerArea) {
polluted.assignedShowerArea.occupied = false;
}
polluted.cleanse();
pollutedSpirits.splice(l, 1);
}
}
// Check river spirit collection
if (riverSpirit) {
if (riverSpirit.lastIntersecting === undefined) {
riverSpirit.lastIntersecting = false;
}
var riverIntersecting = player.intersects(riverSpirit);
if (!riverSpirit.lastIntersecting && riverIntersecting) {
LK.setScore(LK.getScore() + riverSpirit.bonusValue);
scoreTxt.setText('Score: ' + LK.getScore());
// Regenerate health by 30%
player.health += player.maxHealth * 0.3;
player.health = Math.min(player.health, player.maxHealth); // Cap at max health
healthBar.updateHealth(player.health);
LK.effects.flashObject(player, 0x87ceeb, 1000); // Flash blue to indicate healing
riverSpirit.destroy();
riverSpirit = null;
} else if (riverSpirit && riverSpirit.x > 2200) {
riverSpirit.destroy();
riverSpirit = null;
}
if (riverSpirit) {
riverSpirit.lastIntersecting = riverIntersecting;
}
}
// Handle movement animation when dragging
if (dragActive && player) {
movementAnimationTimer++;
if (movementAnimationTimer >= movementAnimationInterval) {
// Switch between movement sprites
if (currentMovementSprite === 'player') {
currentMovementSprite = 'playermovement1';
} else if (currentMovementSprite === 'playermovement1') {
currentMovementSprite = 'playermovement2';
} else {
currentMovementSprite = 'playermovement1';
}
// Update player sprite
player.removeChildren();
var newPlayerGraphics = player.attachAsset(currentMovementSprite, {
anchorX: 0.5,
anchorY: 0.5
});
movementAnimationTimer = 0;
}
} else if (!dragActive && currentMovementSprite !== 'player') {
// Reset to normal player sprite when not dragging
currentMovementSprite = 'player';
player.removeChildren();
var normalPlayerGraphics = player.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
}
// Player direction based on position
var screenMiddle = 1024;
if (player.x < screenMiddle) {
// Player is on left side, face left (flip horizontally)
player.scaleX = -1;
} else {
// Player is on right side, face right (normal orientation)
player.scaleX = 1;
}
// Level progression
if (currentLevel === 'level1' && LK.getScore() >= 250) {
startLevel('level2');
}
if (currentLevel === 'level2' && LK.getScore() >= 500) {
startLevel('level3');
}
if (currentLevel === 'level3' && LK.getScore() >= 750) {
startLevel('level4');
}
// Win condition
if (currentLevel === 'level4' && LK.getScore() >= 1000) {
LK.showYouWin();
}
};
// Show intro screen initially
showIntroScreen();