/**** 
* Plugins
****/ 
var facekit = LK.import("@upit/facekit.v1");
var tween = LK.import("@upit/tween.v1");
/**** 
* Classes
****/ 
// Chicken class
var Chicken = Container.expand(function () {
	var self = Container.call(this);
	// Chicken body
	var chickenBody = self.attachAsset('chicken', {
		anchorX: 0.5,
		anchorY: 1
	});
	// Chicken shadow
	var shadow = self.attachAsset('shadow', {
		anchorX: 0.5,
		anchorY: 0.5,
		y: 20
	});
	// Physics
	self.groundY = 0; // Set after adding to game
	self.velY = 0;
	self.isJumping = false;
	self.jumpPower = -82; // Even higher jump for easier play
	self.gravity = 5.2;
	self.jumpCooldown = 0; // Prevents double jumps
	// Jump method
	self.jump = function () {
		if (!self.isJumping && self.jumpCooldown <= 0) {
			self.velY = self.jumpPower;
			self.isJumping = true;
			self.jumpCooldown = 12; // ~0.2s lockout
			LK.getSound('jump').play();
			// Animate chicken up
			tween(self, {
				scaleX: 1.08,
				scaleY: 0.92
			}, {
				duration: 120,
				easing: tween.easeOut
			});
			tween(shadow, {
				scaleX: 0.7,
				scaleY: 0.7
			}, {
				duration: 120,
				easing: tween.easeOut
			});
		}
	};
	// Update method
	self.update = function () {
		// Cooldown
		if (self.jumpCooldown > 0) self.jumpCooldown--;
		// Gravity
		if (self.isJumping) {
			self.y += self.velY;
			self.velY += self.gravity;
			// Land
			if (self.y >= self.groundY) {
				self.y = self.groundY;
				self.velY = 0;
				self.isJumping = false;
				// Animate squash
				tween(self, {
					scaleX: 1,
					scaleY: 1
				}, {
					duration: 120,
					easing: tween.easeOut
				});
				tween(shadow, {
					scaleX: 1,
					scaleY: 1
				}, {
					duration: 120,
					easing: tween.easeOut
				});
			}
		}
	};
	return self;
});
// Obstacle class
var Obstacle = Container.expand(function () {
	var self = Container.call(this);
	var obs = self.attachAsset('obstacle', {
		anchorX: 0.5,
		anchorY: 1
	});
	self.speed = 0; // Set by game
	self.passed = false; // For scoring
	self.update = function () {
		self.x -= self.speed;
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0xb3e0ff // Light blue sky
});
/**** 
* Game Code
****/ 
// Tween plugin
// Facekit plugin
// Hit sound
// Jump sound
// Shadow
// Ground
// Obstacle (box)
// Chicken (player)
// Game constants
var GROUND_Y = 2300;
var CHICKEN_X = 500;
var OBSTACLE_MIN_GAP = 950; // Wider minimum gap
var OBSTACLE_MAX_GAP = 1450; // Wider maximum gap
var OBSTACLE_MIN_HEIGHT = 140; // Lower minimum height
var OBSTACLE_MAX_HEIGHT = 220; // Lower maximum height
var OBSTACLE_WIDTH = 120;
var OBSTACLE_SPEED_START = 16; // Slower start speed for easier play
var OBSTACLE_SPEED_INC = 0.006; // Slower speed increase
var OBSTACLE_MAX_SPEED = 28; // Lower max speed
// Game state
var chicken;
var ground;
var obstacles = [];
var score = 0;
var distance = 0;
var gameSpeed = OBSTACLE_SPEED_START;
var lastObstacleX = 0;
var isGameOver = false;
var jumpTriggered = false;
var scoreTxt;
var distTxt;
var dragNode = null;
var lives = 6; // Number of lives (increased for easier gameplay)
var livesTxt; // Text2 for lives
// Add ground
ground = LK.getAsset('ground', {
	anchorX: 0,
	anchorY: 0,
	x: 0,
	y: GROUND_Y + 60
});
game.addChild(ground);
// Add chicken
chicken = new Chicken();
chicken.x = CHICKEN_X;
chicken.groundY = GROUND_Y;
chicken.y = GROUND_Y;
game.addChild(chicken);
// Score text
scoreTxt = new Text2('0', {
	size: 120,
	fill: 0xFFF700
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Lives text (top right)
livesTxt = new Text2('❤ x' + lives, {
	size: 90,
	fill: 0xFF4444
});
livesTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(livesTxt);
// Distance text (bottom center)
distTxt = new Text2('0m', {
	size: 70,
	fill: 0xFFFFFF
});
distTxt.anchor.set(0.5, 1);
LK.gui.bottom.addChild(distTxt);
// Helper: spawn obstacle
function spawnObstacle() {
	var obs = new Obstacle();
	obs.speed = gameSpeed;
	obs.x = 2048 + OBSTACLE_WIDTH;
	obs.y = GROUND_Y;
	// Randomize height
	var h = OBSTACLE_MIN_HEIGHT + Math.floor(Math.random() * (OBSTACLE_MAX_HEIGHT - OBSTACLE_MIN_HEIGHT));
	obs.children[0].height = h;
	obs.children[0].y = 0; // AnchorY=1, so bottom at y=0
	obstacles.push(obs);
	game.addChild(obs);
	lastObstacleX = obs.x;
}
// Helper: reset game state
function resetGame() {
	// Remove obstacles
	for (var i = 0; i < obstacles.length; ++i) {
		obstacles[i].destroy();
	}
	obstacles = [];
	score = 0;
	distance = 0;
	gameSpeed = OBSTACLE_SPEED_START;
	lastObstacleX = 0;
	isGameOver = false;
	lives = 3;
	if (livesTxt) livesTxt.setText('❤ x' + lives);
	chicken.x = CHICKEN_X;
	chicken.y = GROUND_Y;
	chicken.velY = 0;
	chicken.isJumping = false;
	chicken.jumpCooldown = 0;
	scoreTxt.setText('0');
	distTxt.setText('0m');
}
// Face control: triggers jump if mouth opens or head moves up
function shouldJump() {
	// If mouth open
	if (facekit.mouthOpen) return true;
	// If head moves up (nose tip y decreases quickly)
	// We'll use a simple delta check
	if (typeof shouldJump.lastNoseY === 'undefined') {
		shouldJump.lastNoseY = facekit.noseTip ? facekit.noseTip.y : 0;
		return false;
	}
	var currY = facekit.noseTip ? facekit.noseTip.y : 0;
	var delta = shouldJump.lastNoseY - currY;
	shouldJump.lastNoseY = currY;
	if (delta > 22) return true; // Quick upward nod
	return false;
}
// Main update loop
game.update = function () {
	if (isGameOver) return;
	// Chicken update
	chicken.update();
	// Facekit: check for jump
	if (shouldJump() && !jumpTriggered) {
		chicken.jump();
		jumpTriggered = true;
	}
	if (!facekit.mouthOpen && !shouldJump()) {
		jumpTriggered = false;
	}
	// Obstacles update
	for (var i = obstacles.length - 1; i >= 0; --i) {
		var obs = obstacles[i];
		obs.speed = gameSpeed;
		obs.update();
		// Remove if off screen
		if (obs.x < -OBSTACLE_WIDTH) {
			obs.destroy();
			obstacles.splice(i, 1);
			continue;
		}
		// Collision
		if (!isGameOver && chicken.y + 10 > obs.y - obs.children[0].height + 30) {
			// Chicken feet near ground
			// Simple AABB
			var cLeft = chicken.x - chicken.children[0].width / 2 + 30;
			var cRight = chicken.x + chicken.children[0].width / 2 - 30;
			var oLeft = obs.x - OBSTACLE_WIDTH / 2;
			var oRight = obs.x + OBSTACLE_WIDTH / 2;
			if (cRight > oLeft && cLeft < oRight) {
				// Hit!
				lives--;
				livesTxt.setText('❤ x' + lives);
				LK.getSound('hit').play();
				LK.effects.flashScreen(0xff0000, 800);
				tween(chicken, {
					rotation: 0.7
				}, {
					duration: 300,
					easing: tween.easeOut
				});
				if (lives <= 0) {
					isGameOver = true;
					LK.setTimeout(function () {
						LK.showGameOver();
					}, 900);
					return;
				} else {
					// Remove the obstacle and reset chicken position for next life
					obs.destroy();
					obstacles.splice(i, 1);
					chicken.x = CHICKEN_X;
					chicken.y = GROUND_Y;
					chicken.velY = 0;
					chicken.isJumping = false;
					chicken.jumpCooldown = 0;
					tween(chicken, {
						rotation: 0
					}, {
						duration: 200,
						easing: tween.easeOut
					});
					// Brief invulnerability (skip further collision this frame)
					break;
				}
			}
		}
		// Score: passed obstacle
		if (!obs.passed && obs.x + OBSTACLE_WIDTH / 2 < chicken.x - chicken.children[0].width / 2) {
			obs.passed = true;
			score++;
			scoreTxt.setText(score);
		}
	}
	// Distance
	distance += gameSpeed / 8;
	distTxt.setText(Math.floor(distance) + "m");
	// Spawn new obstacle
	if (obstacles.length === 0 || 2048 - lastObstacleX > OBSTACLE_MIN_GAP + Math.random() * (OBSTACLE_MAX_GAP - OBSTACLE_MIN_GAP)) {
		spawnObstacle();
	}
	// Increase speed
	if (gameSpeed < OBSTACLE_MAX_SPEED) {
		gameSpeed += OBSTACLE_SPEED_INC;
	}
};
// Touch control: tap anywhere to jump (always enabled)
game.down = function (x, y, obj) {
	if (!isGameOver && !chicken.isJumping && chicken.jumpCooldown <= 0) {
		chicken.jump();
	}
	// Drag chicken for debug/touch (optional, for mobile fallback)
	if (!facekit.mouthOpen && !facekit.noseTip) {
		if (x > chicken.x - 120 && x < chicken.x + 120 && y > chicken.y - 180 && y < chicken.y) {
			dragNode = chicken;
		}
	}
};
game.move = function (x, y, obj) {
	if (dragNode) {
		dragNode.y = Math.max(Math.min(y, GROUND_Y), GROUND_Y - 400);
	}
};
game.up = function (x, y, obj) {
	dragNode = null;
};
// Reset game on showGameOver
LK.on('gameover', function () {
	resetGame();
});
// Reset game on showYouWin (not used, but for completeness)
LK.on('youwin', function () {
	resetGame();
}); /**** 
* Plugins
****/ 
var facekit = LK.import("@upit/facekit.v1");
var tween = LK.import("@upit/tween.v1");
/**** 
* Classes
****/ 
// Chicken class
var Chicken = Container.expand(function () {
	var self = Container.call(this);
	// Chicken body
	var chickenBody = self.attachAsset('chicken', {
		anchorX: 0.5,
		anchorY: 1
	});
	// Chicken shadow
	var shadow = self.attachAsset('shadow', {
		anchorX: 0.5,
		anchorY: 0.5,
		y: 20
	});
	// Physics
	self.groundY = 0; // Set after adding to game
	self.velY = 0;
	self.isJumping = false;
	self.jumpPower = -82; // Even higher jump for easier play
	self.gravity = 5.2;
	self.jumpCooldown = 0; // Prevents double jumps
	// Jump method
	self.jump = function () {
		if (!self.isJumping && self.jumpCooldown <= 0) {
			self.velY = self.jumpPower;
			self.isJumping = true;
			self.jumpCooldown = 12; // ~0.2s lockout
			LK.getSound('jump').play();
			// Animate chicken up
			tween(self, {
				scaleX: 1.08,
				scaleY: 0.92
			}, {
				duration: 120,
				easing: tween.easeOut
			});
			tween(shadow, {
				scaleX: 0.7,
				scaleY: 0.7
			}, {
				duration: 120,
				easing: tween.easeOut
			});
		}
	};
	// Update method
	self.update = function () {
		// Cooldown
		if (self.jumpCooldown > 0) self.jumpCooldown--;
		// Gravity
		if (self.isJumping) {
			self.y += self.velY;
			self.velY += self.gravity;
			// Land
			if (self.y >= self.groundY) {
				self.y = self.groundY;
				self.velY = 0;
				self.isJumping = false;
				// Animate squash
				tween(self, {
					scaleX: 1,
					scaleY: 1
				}, {
					duration: 120,
					easing: tween.easeOut
				});
				tween(shadow, {
					scaleX: 1,
					scaleY: 1
				}, {
					duration: 120,
					easing: tween.easeOut
				});
			}
		}
	};
	return self;
});
// Obstacle class
var Obstacle = Container.expand(function () {
	var self = Container.call(this);
	var obs = self.attachAsset('obstacle', {
		anchorX: 0.5,
		anchorY: 1
	});
	self.speed = 0; // Set by game
	self.passed = false; // For scoring
	self.update = function () {
		self.x -= self.speed;
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0xb3e0ff // Light blue sky
});
/**** 
* Game Code
****/ 
// Tween plugin
// Facekit plugin
// Hit sound
// Jump sound
// Shadow
// Ground
// Obstacle (box)
// Chicken (player)
// Game constants
var GROUND_Y = 2300;
var CHICKEN_X = 500;
var OBSTACLE_MIN_GAP = 950; // Wider minimum gap
var OBSTACLE_MAX_GAP = 1450; // Wider maximum gap
var OBSTACLE_MIN_HEIGHT = 140; // Lower minimum height
var OBSTACLE_MAX_HEIGHT = 220; // Lower maximum height
var OBSTACLE_WIDTH = 120;
var OBSTACLE_SPEED_START = 16; // Slower start speed for easier play
var OBSTACLE_SPEED_INC = 0.006; // Slower speed increase
var OBSTACLE_MAX_SPEED = 28; // Lower max speed
// Game state
var chicken;
var ground;
var obstacles = [];
var score = 0;
var distance = 0;
var gameSpeed = OBSTACLE_SPEED_START;
var lastObstacleX = 0;
var isGameOver = false;
var jumpTriggered = false;
var scoreTxt;
var distTxt;
var dragNode = null;
var lives = 6; // Number of lives (increased for easier gameplay)
var livesTxt; // Text2 for lives
// Add ground
ground = LK.getAsset('ground', {
	anchorX: 0,
	anchorY: 0,
	x: 0,
	y: GROUND_Y + 60
});
game.addChild(ground);
// Add chicken
chicken = new Chicken();
chicken.x = CHICKEN_X;
chicken.groundY = GROUND_Y;
chicken.y = GROUND_Y;
game.addChild(chicken);
// Score text
scoreTxt = new Text2('0', {
	size: 120,
	fill: 0xFFF700
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Lives text (top right)
livesTxt = new Text2('❤ x' + lives, {
	size: 90,
	fill: 0xFF4444
});
livesTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(livesTxt);
// Distance text (bottom center)
distTxt = new Text2('0m', {
	size: 70,
	fill: 0xFFFFFF
});
distTxt.anchor.set(0.5, 1);
LK.gui.bottom.addChild(distTxt);
// Helper: spawn obstacle
function spawnObstacle() {
	var obs = new Obstacle();
	obs.speed = gameSpeed;
	obs.x = 2048 + OBSTACLE_WIDTH;
	obs.y = GROUND_Y;
	// Randomize height
	var h = OBSTACLE_MIN_HEIGHT + Math.floor(Math.random() * (OBSTACLE_MAX_HEIGHT - OBSTACLE_MIN_HEIGHT));
	obs.children[0].height = h;
	obs.children[0].y = 0; // AnchorY=1, so bottom at y=0
	obstacles.push(obs);
	game.addChild(obs);
	lastObstacleX = obs.x;
}
// Helper: reset game state
function resetGame() {
	// Remove obstacles
	for (var i = 0; i < obstacles.length; ++i) {
		obstacles[i].destroy();
	}
	obstacles = [];
	score = 0;
	distance = 0;
	gameSpeed = OBSTACLE_SPEED_START;
	lastObstacleX = 0;
	isGameOver = false;
	lives = 3;
	if (livesTxt) livesTxt.setText('❤ x' + lives);
	chicken.x = CHICKEN_X;
	chicken.y = GROUND_Y;
	chicken.velY = 0;
	chicken.isJumping = false;
	chicken.jumpCooldown = 0;
	scoreTxt.setText('0');
	distTxt.setText('0m');
}
// Face control: triggers jump if mouth opens or head moves up
function shouldJump() {
	// If mouth open
	if (facekit.mouthOpen) return true;
	// If head moves up (nose tip y decreases quickly)
	// We'll use a simple delta check
	if (typeof shouldJump.lastNoseY === 'undefined') {
		shouldJump.lastNoseY = facekit.noseTip ? facekit.noseTip.y : 0;
		return false;
	}
	var currY = facekit.noseTip ? facekit.noseTip.y : 0;
	var delta = shouldJump.lastNoseY - currY;
	shouldJump.lastNoseY = currY;
	if (delta > 22) return true; // Quick upward nod
	return false;
}
// Main update loop
game.update = function () {
	if (isGameOver) return;
	// Chicken update
	chicken.update();
	// Facekit: check for jump
	if (shouldJump() && !jumpTriggered) {
		chicken.jump();
		jumpTriggered = true;
	}
	if (!facekit.mouthOpen && !shouldJump()) {
		jumpTriggered = false;
	}
	// Obstacles update
	for (var i = obstacles.length - 1; i >= 0; --i) {
		var obs = obstacles[i];
		obs.speed = gameSpeed;
		obs.update();
		// Remove if off screen
		if (obs.x < -OBSTACLE_WIDTH) {
			obs.destroy();
			obstacles.splice(i, 1);
			continue;
		}
		// Collision
		if (!isGameOver && chicken.y + 10 > obs.y - obs.children[0].height + 30) {
			// Chicken feet near ground
			// Simple AABB
			var cLeft = chicken.x - chicken.children[0].width / 2 + 30;
			var cRight = chicken.x + chicken.children[0].width / 2 - 30;
			var oLeft = obs.x - OBSTACLE_WIDTH / 2;
			var oRight = obs.x + OBSTACLE_WIDTH / 2;
			if (cRight > oLeft && cLeft < oRight) {
				// Hit!
				lives--;
				livesTxt.setText('❤ x' + lives);
				LK.getSound('hit').play();
				LK.effects.flashScreen(0xff0000, 800);
				tween(chicken, {
					rotation: 0.7
				}, {
					duration: 300,
					easing: tween.easeOut
				});
				if (lives <= 0) {
					isGameOver = true;
					LK.setTimeout(function () {
						LK.showGameOver();
					}, 900);
					return;
				} else {
					// Remove the obstacle and reset chicken position for next life
					obs.destroy();
					obstacles.splice(i, 1);
					chicken.x = CHICKEN_X;
					chicken.y = GROUND_Y;
					chicken.velY = 0;
					chicken.isJumping = false;
					chicken.jumpCooldown = 0;
					tween(chicken, {
						rotation: 0
					}, {
						duration: 200,
						easing: tween.easeOut
					});
					// Brief invulnerability (skip further collision this frame)
					break;
				}
			}
		}
		// Score: passed obstacle
		if (!obs.passed && obs.x + OBSTACLE_WIDTH / 2 < chicken.x - chicken.children[0].width / 2) {
			obs.passed = true;
			score++;
			scoreTxt.setText(score);
		}
	}
	// Distance
	distance += gameSpeed / 8;
	distTxt.setText(Math.floor(distance) + "m");
	// Spawn new obstacle
	if (obstacles.length === 0 || 2048 - lastObstacleX > OBSTACLE_MIN_GAP + Math.random() * (OBSTACLE_MAX_GAP - OBSTACLE_MIN_GAP)) {
		spawnObstacle();
	}
	// Increase speed
	if (gameSpeed < OBSTACLE_MAX_SPEED) {
		gameSpeed += OBSTACLE_SPEED_INC;
	}
};
// Touch control: tap anywhere to jump (always enabled)
game.down = function (x, y, obj) {
	if (!isGameOver && !chicken.isJumping && chicken.jumpCooldown <= 0) {
		chicken.jump();
	}
	// Drag chicken for debug/touch (optional, for mobile fallback)
	if (!facekit.mouthOpen && !facekit.noseTip) {
		if (x > chicken.x - 120 && x < chicken.x + 120 && y > chicken.y - 180 && y < chicken.y) {
			dragNode = chicken;
		}
	}
};
game.move = function (x, y, obj) {
	if (dragNode) {
		dragNode.y = Math.max(Math.min(y, GROUND_Y), GROUND_Y - 400);
	}
};
game.up = function (x, y, obj) {
	dragNode = null;
};
// Reset game on showGameOver
LK.on('gameover', function () {
	resetGame();
});
// Reset game on showYouWin (not used, but for completeness)
LK.on('youwin', function () {
	resetGame();
});