/****
* 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;
// Flip sprite based on horizontal movement direction
if (dx > 0) {
// Moving right, face right
self.scaleX = 1;
} else if (dx < 0) {
// Moving left, face left (flip horizontally)
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;
// Flip sprite based on movement direction
if (self.speed > 0) {
// Moving right, face right
self.scaleX = 1;
} else if (self.speed < 0) {
// Moving left, face left (flip horizontally)
self.scaleX = -1;
}
};
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;
// Flip sprite based on horizontal movement direction
if (dx > 0) {
// Moving right, face right
self.scaleX = 1;
} else if (dx < 0) {
// Moving left, face left (flip horizontally)
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
});
}
// Track player's last position for direction flipping
if (player.lastX === undefined) player.lastX = player.x;
// Flip player based on movement direction
var dx = player.x - player.lastX;
if (dx > 0) {
// Moving right, face right
player.scaleX = 1;
} else if (dx < 0) {
// Moving left, face left (flip horizontally)
player.scaleX = -1;
}
// Update last position
player.lastX = player.x;
// 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;
// Flip sprite based on horizontal movement direction
if (dx > 0) {
// Moving right, face right
self.scaleX = 1;
} else if (dx < 0) {
// Moving left, face left (flip horizontally)
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;
// Flip sprite based on movement direction
if (self.speed > 0) {
// Moving right, face right
self.scaleX = 1;
} else if (self.speed < 0) {
// Moving left, face left (flip horizontally)
self.scaleX = -1;
}
};
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;
// Flip sprite based on horizontal movement direction
if (dx > 0) {
// Moving right, face right
self.scaleX = 1;
} else if (dx < 0) {
// Moving left, face left (flip horizontally)
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
});
}
// Track player's last position for direction flipping
if (player.lastX === undefined) player.lastX = player.x;
// Flip player based on movement direction
var dx = player.x - player.lastX;
if (dx > 0) {
// Moving right, face right
player.scaleX = 1;
} else if (dx < 0) {
// Moving left, face left (flip horizontally)
player.scaleX = -1;
}
// Update last position
player.lastX = player.x;
// 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();