/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/**** 
* Classes
****/ 
var Hand = Container.expand(function () {
	var self = Container.call(this);
	var handGraphics = self.attachAsset('hand', {
		anchorX: 0.5,
		anchorY: 0
	});
	self.state = 'rising'; // rising, grabbing, retreating
	self.speed = 0;
	self.targetY = 0;
	self.originalY = 0;
	self.riseSpeed = 2 + Math.random() * 3;
	self.grabSpeed = 8 + Math.random() * 4;
	self.retreatSpeed = 5 + Math.random() * 3;
	self.waitCounter = 0;
	self.waitTime = 30 + Math.floor(Math.random() * 60);
	// Randomly adjust hand appearance for variety
	handGraphics.rotation = -0.2 + Math.random() * 0.4;
	handGraphics.scaleX = 0.7 + Math.random() * 0.6;
	handGraphics.alpha = 0.7 + Math.random() * 0.3;
	self.update = function () {
		switch (self.state) {
			case 'rising':
				self.y -= self.riseSpeed;
				if (self.y <= self.targetY) {
					self.y = self.targetY;
					self.state = 'waiting';
				}
				break;
			case 'waiting':
				self.waitCounter++;
				if (self.waitCounter >= self.waitTime) {
					self.waitCounter = 0;
					self.state = 'grabbing';
				}
				break;
			case 'grabbing':
				self.y -= self.grabSpeed;
				if (self.y <= -handGraphics.height) {
					self.state = 'retreating';
					self.targetY = self.originalY;
				}
				break;
			case 'retreating':
				self.y += self.retreatSpeed;
				if (self.y >= self.originalY) {
					self.y = self.originalY;
					self.state = 'rising';
					self.targetY = getRandomTargetY();
				}
				break;
		}
	};
	self.grab = function () {
		if (self.state !== 'retreating') {
			self.state = 'grabbing';
			LK.getSound('handGrab').play();
		}
	};
	function getRandomTargetY() {
		return 1800 + Math.random() * 500;
	}
	return self;
});
var Orb = Container.expand(function () {
	var self = Container.call(this);
	var orbGraphics = self.attachAsset('orb', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.glow = 0;
	self.glowDirection = 0.05;
	self.update = function () {
		// Glow effect
		self.glow += self.glowDirection;
		if (self.glow >= 1) {
			self.glow = 1;
			self.glowDirection = -0.05;
		} else if (self.glow <= 0.2) {
			self.glow = 0.2;
			self.glowDirection = 0.05;
		}
		// Apply glow as both scale and brightness
		orbGraphics.scale.set(0.8 + self.glow * 0.4);
		orbGraphics.alpha = 0.6 + self.glow * 0.4;
	};
	self.collect = function () {
		// Expand and fade out effect
		tween(orbGraphics, {
			alpha: 0,
			scaleX: 2,
			scaleY: 2
		}, {
			duration: 300,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				self.destroy();
			}
		});
	};
	return self;
});
var Player = Container.expand(function () {
	var self = Container.call(this);
	var playerGraphics = self.attachAsset('player', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	var pulseScale = 1.0;
	var pulseDirection = 0.01;
	self.isAlive = true;
	self.orbsCollected = 0;
	self.update = function () {
		if (!self.isAlive) {
			return;
		}
		// Subtle pulsing effect
		pulseScale += pulseDirection;
		if (pulseScale >= 1.1) {
			pulseScale = 1.1;
			pulseDirection = -0.01;
		} else if (pulseScale <= 0.9) {
			pulseScale = 0.9;
			pulseDirection = 0.01;
		}
		playerGraphics.scale.x = pulseScale;
		playerGraphics.scale.y = pulseScale;
	};
	self.die = function () {
		if (!self.isAlive) {
			return;
		}
		self.isAlive = false;
		LK.getSound('playerDeath').play();
		// Collapse and fade out effect
		tween(playerGraphics, {
			alpha: 0,
			scaleX: 0.1,
			scaleY: 0.1
		}, {
			duration: 1000,
			easing: tween.easeIn,
			onFinish: function onFinish() {
				LK.showGameOver();
			}
		});
	};
	self.collectOrb = function () {
		self.orbsCollected++;
		LK.setScore(self.orbsCollected);
		// Flash effect
		LK.effects.flashObject(self, 0x00FFFF, 300);
		// Play sound
		LK.getSound('orbCollect').play();
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x000000
});
/**** 
* Game Code
****/ 
// Game state variables
var player;
var orbs = [];
var hands = [];
var lastOrbSpawnTime = 0;
var orbSpawnDelay = 120; // in frames (60 fps = 2 seconds)
var difficulty = 1;
var shadow;
var gameStarted = false;
var scoreTxt;
// Initialize game elements
function initGame() {
	// Create shadow overlay with low opacity
	shadow = LK.getAsset('shadow', {
		anchorX: 0,
		anchorY: 0,
		alpha: 0.9
	});
	game.addChild(shadow);
	// Create player
	player = new Player();
	player.x = 2048 / 2;
	player.y = 2732 / 2;
	game.addChild(player);
	// Initialize score display
	scoreTxt = new Text2('0', {
		size: 120,
		fill: 0x00FFFF
	});
	scoreTxt.anchor.set(0.5, 0);
	scoreTxt.setText(LK.getScore());
	LK.gui.top.addChild(scoreTxt);
	// Initialize tutorial text (disappears after a few seconds)
	var tutorialText = new Text2("Collect the glowing orbs.\nAvoid the hands.", {
		size: 80,
		fill: 0xFFFFFF
	});
	tutorialText.anchor.set(0.5, 0.5);
	LK.gui.center.addChild(tutorialText);
	// Fade out tutorial text after 4 seconds
	LK.setTimeout(function () {
		tween(tutorialText, {
			alpha: 0
		}, {
			duration: 1000,
			onFinish: function onFinish() {
				tutorialText.destroy();
			}
		});
	}, 4000);
	// Start ambient music
	LK.playMusic('creepyAmbience', {
		fade: {
			start: 0,
			end: 0.4,
			duration: 3000
		}
	});
	gameStarted = true;
}
// Create a new orb at a random position
function spawnOrb() {
	var newOrb = new Orb();
	// Place orb in a random position, but keep it away from edges
	newOrb.x = 200 + Math.random() * (2048 - 400);
	newOrb.y = 200 + Math.random() * (2732 - 400);
	// Keep orbs away from player's initial position
	var dx = newOrb.x - player.x;
	var dy = newOrb.y - player.y;
	var dist = Math.sqrt(dx * dx + dy * dy);
	if (dist < 200) {
		// Too close to player, adjust position
		newOrb.x = newOrb.x + (dx > 0 ? 200 : -200);
		newOrb.y = newOrb.y + (dy > 0 ? 200 : -200);
	}
	game.addChild(newOrb);
	orbs.push(newOrb);
	lastOrbSpawnTime = LK.ticks;
}
// Create a new hand at a random position
function spawnHand() {
	var newHand = new Hand();
	// Place hand at a random horizontal position at the bottom of the screen
	newHand.x = 100 + Math.random() * (2048 - 200);
	newHand.y = 2732 + 100; // Start below the screen
	newHand.originalY = newHand.y;
	newHand.targetY = 1800 + Math.random() * 500; // Target y to rise to
	game.addChild(newHand);
	hands.push(newHand);
	return newHand;
}
// Handle player movement
var isDragging = false;
game.down = function (x, y, obj) {
	if (!gameStarted) {
		initGame();
	}
	if (!player.isAlive) {
		return;
	}
	isDragging = true;
	player.x = x;
	player.y = y;
};
game.move = function (x, y, obj) {
	if (!player.isAlive || !isDragging) {
		return;
	}
	player.x = x;
	player.y = y;
};
game.up = function (x, y, obj) {
	isDragging = false;
};
// Main game update loop
game.update = function () {
	if (!gameStarted) {
		initGame();
		return;
	}
	// Spawn orbs on a timer
	if (LK.ticks - lastOrbSpawnTime > orbSpawnDelay && orbs.length < 10) {
		spawnOrb();
		// Make orbs spawn faster as the game progresses
		orbSpawnDelay = Math.max(60, 120 - player.orbsCollected * 2);
	}
	// Spawn hands based on difficulty
	if (LK.ticks % Math.max(60, 180 - difficulty * 15) === 0 && hands.length < 10 + difficulty) {
		spawnHand();
	}
	// Update difficulty based on orbs collected
	difficulty = Math.floor(player.orbsCollected / 5) + 1;
	// Process orb collection
	for (var i = orbs.length - 1; i >= 0; i--) {
		var orb = orbs[i];
		if (player.isAlive && player.intersects(orb)) {
			player.collectOrb();
			orb.collect();
			orbs.splice(i, 1);
			// Increase difficulty
			if (player.orbsCollected % 5 === 0) {
				// Spawn extra hands when difficulty increases
				for (var j = 0; j < 2; j++) {
					var hand = spawnHand();
					hand.grab(); // Make it immediately try to grab
				}
				// Flash screen to indicate difficulty increase
				LK.effects.flashScreen(0x880000, 300);
			}
			// Update score display
			scoreTxt.setText(LK.getScore());
			// Check for win condition (collect 30 orbs)
			if (player.orbsCollected >= 30) {
				LK.showYouWin();
			}
		}
	}
	// Process hand movement and grabbing
	for (var i = hands.length - 1; i >= 0; i--) {
		var hand = hands[i];
		// Check for collision with player
		if (player.isAlive && player.intersects(hand) && (hand.state === 'rising' || hand.state === 'waiting' || hand.state === 'grabbing')) {
			player.die();
		}
		// Remove hands that have been off-screen for too long
		if (hand.state === 'retreating' && hand.y > hand.originalY + 300) {
			hand.destroy();
			hands.splice(i, 1);
		}
	}
}; /**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/**** 
* Classes
****/ 
var Hand = Container.expand(function () {
	var self = Container.call(this);
	var handGraphics = self.attachAsset('hand', {
		anchorX: 0.5,
		anchorY: 0
	});
	self.state = 'rising'; // rising, grabbing, retreating
	self.speed = 0;
	self.targetY = 0;
	self.originalY = 0;
	self.riseSpeed = 2 + Math.random() * 3;
	self.grabSpeed = 8 + Math.random() * 4;
	self.retreatSpeed = 5 + Math.random() * 3;
	self.waitCounter = 0;
	self.waitTime = 30 + Math.floor(Math.random() * 60);
	// Randomly adjust hand appearance for variety
	handGraphics.rotation = -0.2 + Math.random() * 0.4;
	handGraphics.scaleX = 0.7 + Math.random() * 0.6;
	handGraphics.alpha = 0.7 + Math.random() * 0.3;
	self.update = function () {
		switch (self.state) {
			case 'rising':
				self.y -= self.riseSpeed;
				if (self.y <= self.targetY) {
					self.y = self.targetY;
					self.state = 'waiting';
				}
				break;
			case 'waiting':
				self.waitCounter++;
				if (self.waitCounter >= self.waitTime) {
					self.waitCounter = 0;
					self.state = 'grabbing';
				}
				break;
			case 'grabbing':
				self.y -= self.grabSpeed;
				if (self.y <= -handGraphics.height) {
					self.state = 'retreating';
					self.targetY = self.originalY;
				}
				break;
			case 'retreating':
				self.y += self.retreatSpeed;
				if (self.y >= self.originalY) {
					self.y = self.originalY;
					self.state = 'rising';
					self.targetY = getRandomTargetY();
				}
				break;
		}
	};
	self.grab = function () {
		if (self.state !== 'retreating') {
			self.state = 'grabbing';
			LK.getSound('handGrab').play();
		}
	};
	function getRandomTargetY() {
		return 1800 + Math.random() * 500;
	}
	return self;
});
var Orb = Container.expand(function () {
	var self = Container.call(this);
	var orbGraphics = self.attachAsset('orb', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.glow = 0;
	self.glowDirection = 0.05;
	self.update = function () {
		// Glow effect
		self.glow += self.glowDirection;
		if (self.glow >= 1) {
			self.glow = 1;
			self.glowDirection = -0.05;
		} else if (self.glow <= 0.2) {
			self.glow = 0.2;
			self.glowDirection = 0.05;
		}
		// Apply glow as both scale and brightness
		orbGraphics.scale.set(0.8 + self.glow * 0.4);
		orbGraphics.alpha = 0.6 + self.glow * 0.4;
	};
	self.collect = function () {
		// Expand and fade out effect
		tween(orbGraphics, {
			alpha: 0,
			scaleX: 2,
			scaleY: 2
		}, {
			duration: 300,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				self.destroy();
			}
		});
	};
	return self;
});
var Player = Container.expand(function () {
	var self = Container.call(this);
	var playerGraphics = self.attachAsset('player', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	var pulseScale = 1.0;
	var pulseDirection = 0.01;
	self.isAlive = true;
	self.orbsCollected = 0;
	self.update = function () {
		if (!self.isAlive) {
			return;
		}
		// Subtle pulsing effect
		pulseScale += pulseDirection;
		if (pulseScale >= 1.1) {
			pulseScale = 1.1;
			pulseDirection = -0.01;
		} else if (pulseScale <= 0.9) {
			pulseScale = 0.9;
			pulseDirection = 0.01;
		}
		playerGraphics.scale.x = pulseScale;
		playerGraphics.scale.y = pulseScale;
	};
	self.die = function () {
		if (!self.isAlive) {
			return;
		}
		self.isAlive = false;
		LK.getSound('playerDeath').play();
		// Collapse and fade out effect
		tween(playerGraphics, {
			alpha: 0,
			scaleX: 0.1,
			scaleY: 0.1
		}, {
			duration: 1000,
			easing: tween.easeIn,
			onFinish: function onFinish() {
				LK.showGameOver();
			}
		});
	};
	self.collectOrb = function () {
		self.orbsCollected++;
		LK.setScore(self.orbsCollected);
		// Flash effect
		LK.effects.flashObject(self, 0x00FFFF, 300);
		// Play sound
		LK.getSound('orbCollect').play();
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x000000
});
/**** 
* Game Code
****/ 
// Game state variables
var player;
var orbs = [];
var hands = [];
var lastOrbSpawnTime = 0;
var orbSpawnDelay = 120; // in frames (60 fps = 2 seconds)
var difficulty = 1;
var shadow;
var gameStarted = false;
var scoreTxt;
// Initialize game elements
function initGame() {
	// Create shadow overlay with low opacity
	shadow = LK.getAsset('shadow', {
		anchorX: 0,
		anchorY: 0,
		alpha: 0.9
	});
	game.addChild(shadow);
	// Create player
	player = new Player();
	player.x = 2048 / 2;
	player.y = 2732 / 2;
	game.addChild(player);
	// Initialize score display
	scoreTxt = new Text2('0', {
		size: 120,
		fill: 0x00FFFF
	});
	scoreTxt.anchor.set(0.5, 0);
	scoreTxt.setText(LK.getScore());
	LK.gui.top.addChild(scoreTxt);
	// Initialize tutorial text (disappears after a few seconds)
	var tutorialText = new Text2("Collect the glowing orbs.\nAvoid the hands.", {
		size: 80,
		fill: 0xFFFFFF
	});
	tutorialText.anchor.set(0.5, 0.5);
	LK.gui.center.addChild(tutorialText);
	// Fade out tutorial text after 4 seconds
	LK.setTimeout(function () {
		tween(tutorialText, {
			alpha: 0
		}, {
			duration: 1000,
			onFinish: function onFinish() {
				tutorialText.destroy();
			}
		});
	}, 4000);
	// Start ambient music
	LK.playMusic('creepyAmbience', {
		fade: {
			start: 0,
			end: 0.4,
			duration: 3000
		}
	});
	gameStarted = true;
}
// Create a new orb at a random position
function spawnOrb() {
	var newOrb = new Orb();
	// Place orb in a random position, but keep it away from edges
	newOrb.x = 200 + Math.random() * (2048 - 400);
	newOrb.y = 200 + Math.random() * (2732 - 400);
	// Keep orbs away from player's initial position
	var dx = newOrb.x - player.x;
	var dy = newOrb.y - player.y;
	var dist = Math.sqrt(dx * dx + dy * dy);
	if (dist < 200) {
		// Too close to player, adjust position
		newOrb.x = newOrb.x + (dx > 0 ? 200 : -200);
		newOrb.y = newOrb.y + (dy > 0 ? 200 : -200);
	}
	game.addChild(newOrb);
	orbs.push(newOrb);
	lastOrbSpawnTime = LK.ticks;
}
// Create a new hand at a random position
function spawnHand() {
	var newHand = new Hand();
	// Place hand at a random horizontal position at the bottom of the screen
	newHand.x = 100 + Math.random() * (2048 - 200);
	newHand.y = 2732 + 100; // Start below the screen
	newHand.originalY = newHand.y;
	newHand.targetY = 1800 + Math.random() * 500; // Target y to rise to
	game.addChild(newHand);
	hands.push(newHand);
	return newHand;
}
// Handle player movement
var isDragging = false;
game.down = function (x, y, obj) {
	if (!gameStarted) {
		initGame();
	}
	if (!player.isAlive) {
		return;
	}
	isDragging = true;
	player.x = x;
	player.y = y;
};
game.move = function (x, y, obj) {
	if (!player.isAlive || !isDragging) {
		return;
	}
	player.x = x;
	player.y = y;
};
game.up = function (x, y, obj) {
	isDragging = false;
};
// Main game update loop
game.update = function () {
	if (!gameStarted) {
		initGame();
		return;
	}
	// Spawn orbs on a timer
	if (LK.ticks - lastOrbSpawnTime > orbSpawnDelay && orbs.length < 10) {
		spawnOrb();
		// Make orbs spawn faster as the game progresses
		orbSpawnDelay = Math.max(60, 120 - player.orbsCollected * 2);
	}
	// Spawn hands based on difficulty
	if (LK.ticks % Math.max(60, 180 - difficulty * 15) === 0 && hands.length < 10 + difficulty) {
		spawnHand();
	}
	// Update difficulty based on orbs collected
	difficulty = Math.floor(player.orbsCollected / 5) + 1;
	// Process orb collection
	for (var i = orbs.length - 1; i >= 0; i--) {
		var orb = orbs[i];
		if (player.isAlive && player.intersects(orb)) {
			player.collectOrb();
			orb.collect();
			orbs.splice(i, 1);
			// Increase difficulty
			if (player.orbsCollected % 5 === 0) {
				// Spawn extra hands when difficulty increases
				for (var j = 0; j < 2; j++) {
					var hand = spawnHand();
					hand.grab(); // Make it immediately try to grab
				}
				// Flash screen to indicate difficulty increase
				LK.effects.flashScreen(0x880000, 300);
			}
			// Update score display
			scoreTxt.setText(LK.getScore());
			// Check for win condition (collect 30 orbs)
			if (player.orbsCollected >= 30) {
				LK.showYouWin();
			}
		}
	}
	// Process hand movement and grabbing
	for (var i = hands.length - 1; i >= 0; i--) {
		var hand = hands[i];
		// Check for collision with player
		if (player.isAlive && player.intersects(hand) && (hand.state === 'rising' || hand.state === 'waiting' || hand.state === 'grabbing')) {
			player.die();
		}
		// Remove hands that have been off-screen for too long
		if (hand.state === 'retreating' && hand.y > hand.originalY + 300) {
			hand.destroy();
			hands.splice(i, 1);
		}
	}
};
 hand. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
 player. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
 orb. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
 shadow. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows