/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/**** 
* Classes
****/ 
// Boss class (for 2nd area end boss)
var Boss = Container.expand(function () {
	var self = Container.call(this);
	// Use the new unique boss image asset for the boss look
	var bossAsset = self.attachAsset('bossUnique', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.width = bossAsset.width;
	self.height = bossAsset.height;
	self.vx = -2; // Slow horizontal movement (optional)
	self.vy = 0;
	self.lastX = 0;
	self.lastY = 0;
	self.lastWasIntersecting = false;
	self.hp = 15; // Boss hit points (increased by 50%)
	self.isBoss = true;
	// Boss fight state
	self.phase = 1; // 1: normal, 2: jump, 3: fast
	self.attackTimer = 0;
	self.attackCooldown = 60; // frames between attacks (1.0 seconds at 60fps)
	// Boss only starts firing after player reaches boss platform
	self.bossStartFiring = false;
	self.jumpTimer = 0;
	self.isJumping = false;
	self.jumpVy = 0;
	self.groundY = self.y; // y position where boss stands
	self.shieldActive = false;
	self.shieldTimer = 0;
	self.shieldDuration = 60; // frames
	self.weakSpotOpen = false;
	self.weakSpotTimer = 0;
	self.weakSpotDuration = 40; // frames
	self.lastPhase = 1;
	self.update = function () {
		self.lastX = self.x;
		self.lastY = self.y;
		// --- Boss Phase Logic ---
		// Phase changes based on HP
		if (self.hp <= 7.5 && self.phase === 1) {
			self.phase = 2; // Start jumping attacks
			self.attackCooldown = 60; // 1.0 seconds at 60fps
		}
		if (self.hp <= 3 && self.phase === 2) {
			self.phase = 3; // Faster, more aggressive
			self.attackCooldown = 60; // 1.0 seconds at 60fps
		}
		// --- Boss Shield (defense) ---
		if (!self.shieldActive && Math.random() < 0.008 && self.phase > 1) {
			self.shieldActive = true;
			self.shieldTimer = self.shieldDuration;
			// Optional: visual effect for shield (tint blue)
			if (self.displayObject) {
				self.displayObject.tint = 0x44aaff;
			}
		}
		if (self.shieldActive) {
			self.shieldTimer--;
			if (self.shieldTimer <= 0) {
				self.shieldActive = false;
				if (self.displayObject) {
					self.displayObject.tint = 0xffffff;
				}
			}
		}
		// --- Weak Spot (vulnerable) ---
		if (!self.weakSpotOpen && Math.random() < 0.01 && self.phase > 1 && !self.shieldActive) {
			self.weakSpotOpen = true;
			self.weakSpotTimer = self.weakSpotDuration;
			// Optional: visual effect for weak spot (tint yellow)
			if (self.displayObject) {
				self.displayObject.tint = 0xffee44;
			}
		}
		if (self.weakSpotOpen) {
			self.weakSpotTimer--;
			if (self.weakSpotTimer <= 0) {
				self.weakSpotOpen = false;
				if (self.displayObject) {
					self.displayObject.tint = 0xffffff;
				}
			}
		}
		// --- Boss Attacks ---
		if (self.bossStartFiring) {
			self.attackTimer++;
			if (self.attackTimer >= self.attackCooldown && !self.shieldActive && !self.isJumping && !self.isLeaping) {
				self.attackTimer = 0;
				// Choose attack: 50% chance to leap, 50% to fire
				var doLeap = false;
				if (self.phase >= 2 && Math.random() < 0.5) {
					doLeap = true;
				}
				if (doLeap) {
					// Start leap attack: jump toward player, then return
					self.isLeaping = true;
					self.leapPhase = 0; // 0: going to player, 1: returning
					self.leapStartX = self.x;
					self.leapStartY = self.y;
					// Target player position at leap start
					self.leapTargetX = typeof player !== "undefined" ? player.x : self.x;
					self.leapTargetY = self.groundY;
					// Calculate leap velocity to reach player in N frames
					var leapFrames = 24;
					self.leapTimer = 0;
					self.leapTotalFrames = leapFrames;
					self.leapVX = (self.leapTargetX - self.x) / leapFrames;
					self.leapVY = -44; // Upward velocity
					self.leapGravity = (self.groundY - self.y - self.leapVY * leapFrames) * 2 / (leapFrames * leapFrames);
				} else {
					// Boss always fires projectile at player every attack, regardless of phase
					if (typeof bossFireProjectile === "function") {
						bossFireProjectile(self, self.phase === 3);
					}
				}
			}
		}
		// --- Boss Leap Attack ---
		if (self.isLeaping) {
			// Leap phase 0: jump toward player
			if (self.leapPhase === 0) {
				self.x += self.leapVX;
				self.y += self.leapVY;
				self.leapVY += self.leapGravity;
				self.leapTimer++;
				// If reached or passed groundY, land and start return
				if (self.y >= self.groundY) {
					self.y = self.groundY;
					self.leapPhase = 1;
					// On landing, create shockwave (damage if player is close)
					if (typeof bossShockwave === "function") {
						bossShockwave(self);
					}
					// Prepare return leap
					var returnFrames = 24;
					self.leapTimer = 0;
					self.leapTotalFrames = returnFrames;
					self.leapVX = (self.leapStartX - self.x) / returnFrames;
					self.leapVY = -38; // Upward velocity for return
					self.leapGravity = (self.groundY - self.y - self.leapVY * returnFrames) * 2 / (returnFrames * returnFrames);
				}
			} else if (self.leapPhase === 1) {
				// Return leap to original position
				self.x += self.leapVX;
				self.y += self.leapVY;
				self.leapVY += self.leapGravity;
				self.leapTimer++;
				if (self.y >= self.groundY || self.leapTimer >= self.leapTotalFrames) {
					self.y = self.groundY;
					self.x = self.leapStartX;
					self.isLeaping = false;
					self.leapPhase = 0;
					// On landing, create shockwave (damage if player is close)
					if (typeof bossShockwave === "function") {
						bossShockwave(self);
					}
				}
			}
		}
		// --- Boss Jumping (old jump attack, only used if not leaping) ---
		if (self.isJumping) {
			self.y += self.jumpVy;
			self.jumpVy += 4.5; // gravity
			if (self.y >= self.groundY) {
				self.y = self.groundY;
				self.isJumping = false;
				// On landing, create shockwave (damage if player is close)
				if (typeof bossShockwave === "function") {
					bossShockwave(self);
				}
			}
		}
		// --- Boss Movement (side to side in phase 3) ---
		if (self.phase === 3 && !self.isJumping && !self.isLeaping) {
			// Move left and right slowly
			if (!self.moveDir) {
				self.moveDir = -1;
			}
			self.x += self.moveDir * 7;
			// Clamp to wide platform area (assume platform at y = self.groundY + boss.height/2 + 200)
			var minX = self.x0 || self.x - 600;
			var maxX = self.x1 || self.x + 600;
			if (!self.x0) {
				self.x0 = self.x - 600;
			}
			if (!self.x1) {
				self.x1 = self.x + 600;
			}
			if (self.x < minX) {
				self.x = minX;
				self.moveDir = 1;
			}
			if (self.x > maxX) {
				self.x = maxX;
				self.moveDir = -1;
			}
		}
	};
	return self;
});
// BossBullet class: used for boss projectiles, uses bossBullet asset
var BossBullet = Container.expand(function () {
	var self = Container.call(this);
	var bossBulletAsset = self.attachAsset('bossBullet', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.width = bossBulletAsset.width;
	self.height = bossBulletAsset.height;
	self.vx = 0;
	self.vy = 0;
	self.lastX = 0;
	self.lastY = 0;
	self.isBossProjectile = true;
	self.update = function () {
		self.lastX = self.x;
		self.lastY = self.y;
		self.x += self.vx;
		self.y += self.vy;
		// Clamp boss projectiles within boss platform bounds
		if (typeof platforms !== "undefined" && platforms.length > 0) {
			// Find the boss platform (the widest one, used for boss)
			var bossPlat = null;
			for (var i = 0; i < platforms.length; i++) {
				if (platforms[i].width >= 1800) {
					bossPlat = platforms[i];
					break;
				}
			}
			if (bossPlat) {
				var minX = bossPlat.x;
				var maxX = bossPlat.x + bossPlat.width;
				// Clamp self.x to platform bounds
				if (self.x < minX) {
					self.x = minX;
				}
				if (self.x > maxX) {
					self.x = maxX;
				}
			}
		}
	};
	return self;
});
// Bullet class
var Bullet = Container.expand(function () {
	var self = Container.call(this);
	// Use the new bullet figure asset
	var bulletAsset = self.attachAsset('bulletFigure', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.width = bulletAsset.width;
	self.height = bulletAsset.height;
	self.vx = 40; // Bullet speed (right)
	self.vy = 0; // Add vy for vertical movement
	self.active = true;
	self.lastX = 0;
	self.lastY = 0;
	self.isControlled = false; // If true, player can control direction
	self.update = function () {
		self.lastX = self.x;
		self.lastY = self.y;
		// If controlled, vx/vy may be set by player, else keep moving
		self.x += self.vx;
		self.y += self.vy;
	};
	return self;
});
// Coin class
var Coin = Container.expand(function () {
	var self = Container.call(this);
	var coinAsset = self.attachAsset('coinCircle', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.width = coinAsset.width;
	self.height = coinAsset.height;
	return self;
});
// Enemy class: simple flying enemy that moves left across the screen
var Enemy = Container.expand(function () {
	var self = Container.call(this);
	// Use a unique asset for the enemy (use '682f46a9c0116d543bc37477' as image)
	var enemyAsset = self.attachAsset('682f46a9c0116d543bc37477', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.width = enemyAsset.width;
	self.height = enemyAsset.height;
	self.vx = -14 - Math.random() * 6; // Move left at random speed
	self.vy = 0;
	self.lastX = 0;
	self.lastY = 0;
	self.lastWasIntersecting = false;
	self.isBossProjectile = false; // Not a boss projectile
	self.update = function () {
		self.lastX = self.x;
		self.lastY = self.y;
		self.x += self.vx;
		self.y += self.vy;
		// Optionally, add up/down movement for variety
		if (Math.random() < 0.02) {
			self.vy = (Math.random() - 0.5) * 8;
		}
		// Clamp Y to play area
		if (self.y < 200) {
			self.y = 200;
		}
		if (self.y > 2300) {
			self.y = 2300;
		}
	};
	return self;
});
// FreezingEnemy class: special enemy that appears only once per level
var FreezingEnemy = Container.expand(function () {
	var self = Container.call(this);
	// Use the freezing enemy asset
	var freezingAsset = self.attachAsset('freezingEnemy', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.width = freezingAsset.width;
	self.height = freezingAsset.height;
	// Initial speed toward left, but will accelerate
	self.vx = -10 - Math.random() * 4;
	self.vy = 0;
	self.acceleration = 0.7 + Math.random() * 0.3; // How quickly it turns toward player
	self.maxSpeed = 22 + Math.random() * 4; // Max speed increases for more threat
	self.lastX = 0;
	self.lastY = 0;
	self.lastWasIntersecting = false;
	self.isBossProjectile = false;
	self.update = function () {
		self.lastX = self.x;
		self.lastY = self.y;
		// Home in on player if player exists
		if (typeof player !== "undefined" && player) {
			var dx = player.x - self.x;
			var dy = player.y - player.height / 2 - self.y;
			var len = Math.sqrt(dx * dx + dy * dy);
			if (len > 0) {
				// Normalize direction
				var targetVx = dx / len * self.maxSpeed;
				var targetVy = dy / len * self.maxSpeed;
				// Accelerate vx/vy toward targetVx/targetVy
				self.vx += (targetVx - self.vx) * self.acceleration * 0.08;
				self.vy += (targetVy - self.vy) * self.acceleration * 0.08;
				// Clamp speed to maxSpeed
				var speed = Math.sqrt(self.vx * self.vx + self.vy * self.vy);
				if (speed > self.maxSpeed) {
					self.vx = self.vx / speed * self.maxSpeed;
					self.vy = self.vy / speed * self.maxSpeed;
				}
			}
		}
		self.x += self.vx;
		self.y += self.vy;
		// Clamp Y to play area
		if (self.y < 200) {
			self.y = 200;
		}
		if (self.y > 2300) {
			self.y = 2300;
		}
	};
	return self;
});
// Platform class
var Platform = Container.expand(function () {
	var self = Container.call(this);
	var platAsset = self.attachAsset('platformBox', {
		anchorX: 0,
		anchorY: 0
	});
	self.width = platAsset.width;
	self.height = platAsset.height;
	return self;
});
// Player character class
var Player = Container.expand(function () {
	var self = Container.call(this);
	// Attach player asset (always use playerBox)
	self.skinId = 'playerBox';
	var playerAsset = self.attachAsset(self.skinId, {
		anchorX: 0.5,
		anchorY: 1
	});
	// Method to change skin
	self.setSkin = function (skinId) {
		if (self.displayObject && self.displayObject.parent) {
			self.displayObject.parent.removeChild(self.displayObject);
		}
		var newAsset = self.attachAsset(skinId, {
			anchorX: 0.5,
			anchorY: 1
		});
		self.width = newAsset.width;
		self.height = newAsset.height;
		self.displayObject = newAsset;
		self.skinId = skinId;
	};
	// Physics properties
	self.vx = 0;
	self.vy = 0;
	self.isOnGround = false;
	self.width = playerAsset.width;
	self.height = playerAsset.height;
	// For jump control
	self.jumpRequested = false;
	// Animation properties
	self.isRunning = false;
	self.runningTween = null;
	self.jumpingTween = null;
	self.originalScaleX = 1;
	self.originalScaleY = 1;
	// Animation methods
	self.startRunningAnimation = function () {
		if (!self.isRunning && !self.runningTween) {
			self.isRunning = true;
			// Create bobbing animation while running
			self.runningTween = tween(playerAsset, {
				scaleY: 0.9,
				scaleX: 1.1
			}, {
				duration: 150,
				easing: tween.easeInOut,
				onFinish: function onFinish() {
					if (self.isRunning) {
						// Bounce back
						tween(playerAsset, {
							scaleY: 1.1,
							scaleX: 0.9
						}, {
							duration: 150,
							easing: tween.easeInOut,
							onFinish: function onFinish() {
								if (self.isRunning) {
									self.runningTween = null;
									self.startRunningAnimation(); // Loop animation
								}
							}
						});
					}
				}
			});
		}
	};
	self.stopRunningAnimation = function () {
		if (self.isRunning) {
			self.isRunning = false;
			if (self.runningTween) {
				tween.stop(playerAsset, {
					scaleX: true,
					scaleY: true
				});
				self.runningTween = null;
			}
			// Return to original scale smoothly
			tween(playerAsset, {
				scaleX: self.originalScaleX,
				scaleY: self.originalScaleY
			}, {
				duration: 100,
				easing: tween.easeOut
			});
		}
	};
	self.startJumpAnimation = function () {
		if (!self.jumpingTween) {
			// Squash before jump
			self.jumpingTween = tween(playerAsset, {
				scaleY: 0.7,
				scaleX: 1.3
			}, {
				duration: 80,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					// Stretch during jump
					tween(playerAsset, {
						scaleY: 1.2,
						scaleX: 0.8
					}, {
						duration: 120,
						easing: tween.easeInOut,
						onFinish: function onFinish() {
							// Return to normal on landing
							tween(playerAsset, {
								scaleX: self.originalScaleX,
								scaleY: self.originalScaleY
							}, {
								duration: 100,
								easing: tween.easeOut,
								onFinish: function onFinish() {
									self.jumpingTween = null;
								}
							});
						}
					});
				}
			});
		}
	};
	// Touch down on player (for jump)
	self.down = function (x, y, obj) {
		// Only allow jump if on ground and not frozen
		if (self.isOnGround && !self.isFrozen) {
			self.jumpRequested = true;
		}
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x87ceeb // Sky blue
});
/**** 
* Game Code
****/ 
// Ava: Freezing enemy asset
// --- Shop System Removed ---
var shopCoins = 0; // Ava: Track shop coins collected by player
// Ava: Track if freezing enemy has spawned this level
var freezingEnemySpawned = false;
// new kebabBox asset (fullscreen, kebab color)
// Boss attack: fire projectile at player
// Unique boss asset
// New bullet figure asset (example: blue ellipse, unique id)
// Sun and cloud assets (example IDs, replace with real asset IDs as needed)
// --- Asset Initialization (shapes) ---
// Karakterin terliği için örnek asset (id: '6832a1b2terlikicon')
// Boss health bar assets
// --- Game Variables ---
// --- Shop System Removed ---
function _typeof(o) {
	"@babel/helpers - typeof";
	return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
		return typeof o;
	} : function (o) {
		return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
	}, _typeof(o);
}
function bossFireProjectile(boss, fast) {
	// Fire 1 or 2 projectiles toward player
	var num = fast ? 2 : 1;
	for (var i = 0; i < num; i++) {
		var proj = new BossBullet();
		proj.x = boss.x;
		proj.y = boss.y + boss.height / 2 - 80 + i * 60;
		// Aim at player
		var dx = player.x - boss.x;
		var dy = player.y - player.height / 2 - proj.y;
		var len = Math.sqrt(dx * dx + dy * dy);
		var speed = fast ? 28 : 18;
		if (len > 0) {
			proj.vx = dx / len * speed;
			proj.vy = dy / len * speed;
		} else {
			proj.vx = speed;
			proj.vy = 0;
		}
		// Mark as boss projectile (for collision logic)
		proj.isBossProjectile = true;
		enemies.push(proj);
		game.addChild(proj);
	}
}
// Boss shockwave: damage player if close to boss when landing
function bossShockwave(boss) {
	// If player is within 220px horizontally and below boss, take damage
	var px = player.x;
	var py = player.y;
	var bx = boss.x;
	var by = boss.y + boss.height / 2;
	if (Math.abs(px - bx) < 220 && py > by) {
		LK.effects.flashScreen(0xff0000, 800);
		playerLives--;
		updateHearts();
		if (playerLives <= 0) {
			gameOver = true;
			LK.showGameOver();
			return;
		}
	}
	// Optional: visual effect for shockwave (flash boss yellow)
	if (boss.displayObject) {
		boss.displayObject.tint = 0xffff00;
		LK.setTimeout(function () {
			if (boss.displayObject) {
				boss.displayObject.tint = 0xffffff;
			}
		}, 200);
	}
}
var GRAVITY = 2.2;
var JUMP_VELOCITY = -54;
var PLAYER_SPEED = 16;
var SCROLL_SPEED = 10;
var LEVEL_LENGTH = 950 * 9 + 600 + 500; // 10 platforms, spacing 950, start at 600, plus last platform width
var player;
var platforms = [];
var coins = [];
var bullets = []; // Bullets array for shooting
var enemies = []; // Array for flying enemies
var coffeeHouse = null;
var boss = null; // Boss instance for 2nd area
var cameraX = 0;
var score = 0;
var distance = 0;
var gameOver = false;
var hazards = [];
var checkpoints = [];
var currentLevel = 1;
var autoMoveRightActive = false;
var lastCheckpointIndex = 0;
// --- Ava: Cephane refill timer ---
var playerAmmo = 0;
var maxPlayerAmmo = 10;
var ammoRefillTimer = LK.setInterval(function () {
	if (typeof playerAmmo === "undefined") {
		playerAmmo = 0;
	}
	if (typeof maxPlayerAmmo === "undefined") {
		maxPlayerAmmo = 10;
	}
	if (playerAmmo < maxPlayerAmmo) {
		playerAmmo++;
	}
}, 250);
// --- GUI ---
// Hearts (5 total, left-aligned, with spacing)
var heartAssets = [];
var heartSpacing = 120;
var playerLives = 3; // Total lives/can
// --- Melody Button (Sound/Music Toggle) ---
// Use a simple ellipse as the button background, and a Text2 for the icon
// Melody button (Sound/Music Toggle) - use btnFireBg for a unique look, no centerCircle above it
var melodyBtn = LK.getAsset('btnFireBg', {
	anchorX: 0.5,
	anchorY: 0.5,
	scaleX: 0.7,
	scaleY: 0.7
});
melodyBtn.x = 100 + 60 - 700 - 90; // 790px more to the left from previous position
melodyBtn.y = 100 + 60 + 100; // 100px margin from top, 60px for radius, 100px further down
melodyBtn.width = 120;
melodyBtn.height = 120;
melodyBtn.interactive = true;
melodyBtn.alpha = 0.92;
// Melody icon (♪)
var melodyIcon = new Text2('♪', {
	size: 80,
	fill: 0x222222
});
melodyIcon.anchor.set(0.5, 0.5);
melodyIcon.x = melodyBtn.x;
melodyIcon.y = melodyBtn.y;
// Track mute state
var isMuted = false;
function updateMelodyIcon() {
	if (isMuted) {
		melodyIcon.setText('🔇');
		melodyBtn.alpha = 0.5;
	} else {
		melodyIcon.setText('♪');
		melodyBtn.alpha = 0.92;
	}
}
// Add to GUI (top left, but offset to avoid platform menu)
LK.gui.top.addChild(melodyBtn);
LK.gui.top.addChild(melodyIcon);
updateMelodyIcon();
// Melody button touch handler
melodyBtn.down = function (x, y, obj) {
	isMuted = !isMuted;
	updateMelodyIcon();
	// Mute/unmute all sounds and music
	if (isMuted) {
		if (typeof LK.setMuted === "function") {
			LK.setMuted(true);
		}
	} else {
		if (typeof LK.setMuted === "function") {
			LK.setMuted(false);
		}
	}
};
// Also allow toggling by tapping the icon itself
melodyIcon.down = function (x, y, obj) {
	melodyBtn.down(x, y, obj);
};
function updateHearts() {
	for (var i = 0; i < heartAssets.length; i++) {
		if (i < playerLives) {
			heartAssets[i].visible = true;
		} else {
			heartAssets[i].visible = false;
		}
	}
}
for (var i = 0; i < 5; i++) {
	var heart = LK.getAsset('centerCircle', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	heart.x = 180 + i * heartSpacing; // Shifted 150px left from previous position
	heart.y = 100; // Moved hearts higher up
	LK.gui.top.addChild(heart);
	heartAssets.push(heart);
}
updateHearts();
var scoreTxt = new Text2('0', {
	size: 100,
	fill: 0xFFF700
});
scoreTxt.anchor.set(0.5, 0);
scoreTxt.y = 20; // Moved score text to very top
LK.gui.top.addChild(scoreTxt);
var distTxt = new Text2('0m', {
	size: 60,
	fill: 0xFFFFFF
});
distTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(distTxt);
distTxt.y = 120; // Moved distance text higher
// --- Level Generation ---
function createLevel() {
	// Clear old
	for (var i = 0; i < platforms.length; i++) {
		platforms[i].destroy();
	}
	for (var i = 0; i < coins.length; i++) {
		coins[i].destroy();
	}
	if (typeof coffeeHouse !== "undefined" && coffeeHouse) {
		coffeeHouse.destroy();
	}
	platforms = [];
	coins = [];
	coffeeHouse = null;
	// Add sun to the sky
	var sun = LK.getAsset('sun', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	sun.x = 300;
	sun.y = 300;
	game.addChild(sun);
	// Add a few clouds at different positions
	var cloud1 = LK.getAsset('cloud', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	cloud1.x = 700;
	cloud1.y = 400;
	game.addChild(cloud1);
	var cloud2 = LK.getAsset('cloud', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	cloud2.x = 1400;
	cloud2.y = 600;
	game.addChild(cloud2);
	var cloud3 = LK.getAsset('cloud', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	cloud3.x = 2000;
	cloud3.y = 350;
	game.addChild(cloud3);
	// (bottomCloud removed)
	// Clear and initialize hazards array properly
	if (typeof hazards !== "undefined" && hazards && hazards.length) {
		for (var i = 0; i < hazards.length; i++) {
			if (hazards[i] && typeof hazards[i].destroy === "function") {
				hazards[i].destroy();
			}
		}
	}
	hazards = [];
	// --- Restore old hazard spawning logic: spawn falling hazards on random platforms except boss level ---
	if (!isBossLevel) {
		var hazardCount = Math.max(2, Math.floor(numPlatforms / 3));
		for (var h = 0; h < hazardCount; h++) {
			// Pick a random platform (not the first or last)
			var platIdx = 1 + Math.floor(Math.random() * (numPlatforms - 2));
			var plat = platforms[platIdx];
			if (!plat) {
				continue;
			}
			var hazard = LK.getAsset('hazard', {
				anchorX: 0.5,
				anchorY: 0.5
			});
			// Place hazard above the platform, random X within platform width
			hazard.x = plat.x + plat.width * (0.2 + 0.6 * Math.random());
			hazard.y = plat.y - 400 - Math.random() * 300;
			hazard.width = 120;
			hazard.height = 120;
			hazard.vy = 12 + Math.random() * 6;
			hazards.push(hazard);
			game.addChild(hazard);
		}
	}
	// Platform layout: up/down, not fixed order, player can jump between them
	// 5 levels: 1-4 classic, 5 is boss fight
	var isBossLevel = typeof currentLevel !== "undefined" && currentLevel === 5;
	// Set platform count per level
	var numPlatforms = 10;
	if (typeof currentLevel !== "undefined") {
		if (currentLevel === 1) {
			numPlatforms = 15;
		} else if (currentLevel === 2) {
			numPlatforms = 15;
		} else if (currentLevel === 3) {
			numPlatforms = 20;
		} else if (currentLevel === 4) {
			numPlatforms = 20;
		} else if (currentLevel === 5) {
			numPlatforms = 15;
		}
	}
	var platSpacingX = 950; // Further increased horizontal spacing for much more space
	var platMinY = 400; // Moved higher up to use more of top area
	var platMaxY = 2400; // Extended lower to use more bottom area
	// Calculate max jump height based on physics
	// vy = JUMP_VELOCITY, gravity = GRAVITY
	// maxJumpHeight = - (vy^2) / (2 * gravity)
	var maxJumpHeight = -(JUMP_VELOCITY * JUMP_VELOCITY) / (2 * GRAVITY);
	// Use 90% of maxJumpHeight for margin of error
	var platformGapY = Math.floor(maxJumpHeight * 0.9);
	var lastY = 1800;
	// (Removed initial spawn platform and its coin)
	for (var i = 0; i < numPlatforms; i++) {
		// If this is the last platform of the boss level, add a wide area instead of a platform
		if (isBossLevel && i === numPlatforms - 1) {
			// Create a wide area using a platform asset, but much wider
			var wideArea = new Platform();
			wideArea.x = 600 + i * platSpacingX;
			wideArea.y = lastY;
			wideArea.width = 2048; // Full screen width
			wideArea.height = 300; // Taller for effect
			// Set the display object size as well
			if (wideArea.displayObject) {
				wideArea.displayObject.width = wideArea.width;
				wideArea.displayObject.height = wideArea.height;
			}
			platforms.push(wideArea);
			game.addChild(wideArea);
			// Optionally, add a coin or heart in the middle of the wide area
			var coin = new Coin();
			coin.x = wideArea.x + wideArea.width / 2;
			coin.y = wideArea.y - 80;
			coins.push(coin);
			game.addChild(coin);
			// Add boss at the right end of the wide area
			if (typeof boss !== "undefined" && boss) {
				boss.destroy();
			}
			// Remove all hazards before boss fight
			if (typeof hazards !== "undefined" && hazards.length) {
				for (var h = 0; h < hazards.length; h++) {
					if (hazards[h] && typeof hazards[h].destroy === "function") {
						hazards[h].destroy();
					}
				}
			}
			hazards = [];
			boss = new Boss();
			// Place boss so its feet are 200px above the platform
			boss.x = wideArea.x + wideArea.width - boss.width / 2 - 60; // Near right edge
			// Boss anchorY is 0.5, so y is at center. To put feet 200px above platform: y = platform.y + platform.height - boss.height/2 - 200
			boss.y = wideArea.y + wideArea.height - boss.height / 2 - 200;
			// Set boss.groundY to correct y so boss doesn't jump to top
			boss.groundY = boss.y;
			game.addChild(boss);
			// No checkpoint on the wide area
			continue;
		}
		var plat = new Platform();
		plat.x = 600 + i * platSpacingX;
		// Alternate up/down, but keep within jumpable range
		if (i === 0) {
			plat.y = lastY;
		} else {
			// Randomly go up or down, but clamp to min/max
			var deltaY = (Math.random() > 0.5 ? -1 : 1) * (platformGapY + Math.floor(Math.random() * 40) - 20); // Small random offset
			plat.y = lastY + deltaY;
			if (plat.y < platMinY) {
				plat.y = platMinY;
			}
			if (plat.y > platMaxY) {
				plat.y = platMaxY;
			}
			lastY = plat.y;
		}
		platforms.push(plat);
		game.addChild(plat);
		// Place a coin above every platform, but rarely replace with a heart (extra life)
		if (Math.random() < 0.07) {
			// ~7% chance, very rare
			var heart = LK.getAsset('centerCircle', {
				anchorX: 0.5,
				anchorY: 0.5
			});
			heart.x = plat.x + plat.width / 2;
			heart.y = plat.y - 80;
			heart.isHeart = true;
			coins.push(heart);
			game.addChild(heart);
		} else {
			var coin = new Coin();
			coin.x = plat.x + plat.width / 2;
			coin.y = plat.y - 80;
			coins.push(coin);
			game.addChild(coin);
		}
		// Add a checkpoint marker every 10th platform (not the first platform)
		if (i > 0 && i % 10 === 0) {
			var checkpoint = LK.getAsset('centerCircle', {
				anchorX: 0.5,
				anchorY: 0.5
			});
			checkpoint.x = plat.x + plat.width / 2;
			checkpoint.y = plat.y - 120;
			checkpoint.width = 120;
			checkpoint.height = 120;
			checkpoint.isCheckpoint = true;
			checkpoint.platformIndex = i;
			game.addChild(checkpoint);
			// Initialize checkpoints array if not defined
			var checkpoints = [];
			// Store checkpoint objects in an array for respawn logic
			if (typeof checkpoints === "undefined") {
				checkpoints = [];
			}
			checkpoints.push(checkpoint);
		}
	}
	// Add coffee house on the last platform for levels 1, 2, 3, 4 (not boss level)
	if (platforms.length > 0 && (typeof currentLevel === "undefined" || currentLevel === 1 || currentLevel === 2 || currentLevel === 3 || currentLevel === 4)) {
		var lastPlat = platforms[platforms.length - 1];
		coffeeHouse = LK.getAsset('coffeeHouse', {
			anchorX: 0.5,
			anchorY: 1
		});
		coffeeHouse.x = lastPlat.x + lastPlat.width / 2;
		coffeeHouse.y = lastPlat.y;
		game.addChild(coffeeHouse);
	}
}
// --- Player Initialization ---
// Track the last safe platform index for respawn
var lastSafePlatformIndex = 0;
// Track the platform the player fell from for respawn
var lastFallenPlatformIndex = 0;
function resetPlayer(respawnToLastSafe) {
	if (player) {
		player.destroy();
	}
	player = new Player();
	// No shop skin logic
	// Place player on the start platform or the platform where they fell if requested
	if (platforms.length > 0) {
		var platIdx = 0;
		if (respawnToLastSafe && typeof lastFallenPlatformIndex === "number" && lastFallenPlatformIndex >= 0 && lastFallenPlatformIndex < platforms.length) {
			platIdx = lastFallenPlatformIndex;
		} else if (respawnToLastSafe && typeof lastSafePlatformIndex === "number" && lastSafePlatformIndex >= 0 && lastSafePlatformIndex < platforms.length) {
			platIdx = lastSafePlatformIndex;
		}
		player.x = platforms[platIdx].x + platforms[platIdx].width / 2;
		player.y = platforms[platIdx].y;
	} else {
		player.x = 200;
		player.y = 2000; // Moved default spawn position higher for better screen usage
	}
	player.vx = 0;
	player.vy = 0;
	player.isOnGround = false;
	// No upgrades to apply
	game.addChild(player);
	// --- Ava: Stop auto-move and movement if spawning on first platform ---
	if (typeof autoMoveRightActive === "undefined") {
		autoMoveRightActive = false;
	}
	if (typeof moveDir === "undefined") {
		moveDir = 0;
	}
	if (platIdx === 0) {
		autoMoveRightActive = false;
		moveDir = 0;
		// Set a flag to require left button press to resume movement
		player.waitingForLeftBtn = true;
	} else {
		player.waitingForLeftBtn = false;
	}
}
// --- Camera ---
function updateCamera() {
	// Camera always follows player, no clamping
	cameraX = player.x - 600;
	// Move all game objects (except GUI) by -cameraX
	for (var i = 0; i < platforms.length; i++) {
		platforms[i].xScreen = platforms[i].x - cameraX;
	}
	for (var i = 0; i < coins.length; i++) {
		coins[i].xScreen = coins[i].x - cameraX;
	}
	player.xScreen = player.x - cameraX;
	// Move coffeeHouse relative to camera
	if (coffeeHouse && platforms.length > 0) {
		var lastPlat = platforms[platforms.length - 1];
		coffeeHouse.xScreen = coffeeHouse.x - cameraX;
		coffeeHouse.yScreen = coffeeHouse.y;
	}
	// --- Ava: Keep bottomCloud at fixed screen position if it exists ---
	if (typeof bottomCloud !== "undefined" && bottomCloud) {
		bottomCloud.x = 2048 / 2 - 200;
		bottomCloud.y = 2732 - 120;
	}
	// (hazard removed)
}
// --- Utility: AABB collision ---
function intersectsAABB(a, b) {
	return a.x < b.x + b.width && a.x + a.width > b.x && a.y < b.y + b.height && a.y + a.height > b.y;
}
// --- Touch Controls ---
// On-screen left, right, and jump buttons (bottom left corner)
// Only these buttons control movement/jump; fire is still tap/double-tap on right side
var moveDir = 0; // -1 = left, 1 = right, 0 = none
var leftBtn, rightBtn, jumpBtn;
var leftBtnPressed = false,
	rightBtnPressed = false,
	jumpBtnPressed = false;
// Create left button
leftBtn = LK.getAsset('btnLeftBg', {
	anchorX: 0.5,
	anchorY: 0.5
});
leftBtn.x = 180;
// Move control buttons visually in front of platforms by increasing their y position (platforms are at y ~400-2400, so buttons should be in front)
leftBtn.y = 2400 + 120; // Place left button just in front of lowest platform
leftBtn.width = 260;
leftBtn.height = 260;
var leftIcon = LK.getAsset('btnLeftIcon', {
	anchorX: 0.5,
	anchorY: 0.5
});
leftIcon.x = leftBtn.x;
leftIcon.y = leftBtn.y;
leftIcon.width = 140;
leftIcon.height = 140;
// Create right button
rightBtn = LK.getAsset('btnRightBg', {
	anchorX: 0.5,
	anchorY: 0.5
});
rightBtn.x = 470 + 150 - 125;
rightBtn.y = 2400 + 120; // Place right button just in front of lowest platform
rightBtn.width = 260;
rightBtn.height = 260;
var rightIcon = LK.getAsset('btnRightIcon', {
	anchorX: 0.5,
	anchorY: 0.5
});
rightIcon.x = rightBtn.x;
rightIcon.y = rightBtn.y;
rightIcon.width = 140;
rightIcon.height = 140;
// Create jump button
jumpBtn = LK.getAsset('btnJumpBg', {
	anchorX: 0.5,
	anchorY: 0.5
});
jumpBtn.x = 220 + 200 - 90;
jumpBtn.y = 2400 - 120; // Place jump button just above the other buttons, still in front of platforms
jumpBtn.width = 260;
jumpBtn.height = 260;
var jumpIcon = LK.getAsset('btnJumpIcon', {
	anchorX: 0.5,
	anchorY: 0.5
});
jumpIcon.x = jumpBtn.x;
jumpIcon.y = jumpBtn.y;
jumpIcon.width = 140;
jumpIcon.height = 140;
// Create fire button (bottom right, red circle)
var fireBtn = LK.getAsset('btnFireBg', {
	anchorX: 0.5,
	anchorY: 0.5
});
fireBtn.x = 2048 - 180;
fireBtn.y = 2400 + 120; // Place fire button just in front of lowest platform
fireBtn.width = 260;
fireBtn.height = 260;
// Terlik ikonunu fire butonun ortasına ekle
var terlikIcon = LK.getAsset('terlikIcon', {
	anchorX: 0.5,
	anchorY: 0.5
});
terlikIcon.x = fireBtn.x;
terlikIcon.y = fireBtn.y;
terlikIcon.width = 160;
terlikIcon.height = 160;
// Add all buttons and icons to the display list at the very end so they are always in front
game.addChild(leftBtn);
game.addChild(leftIcon);
game.addChild(rightBtn);
game.addChild(rightIcon);
game.addChild(jumpBtn);
game.addChild(jumpIcon);
game.addChild(fireBtn);
game.addChild(terlikIcon);
// --- Ava: Move all control and UI buttons to the absolute front of the display list every frame to guarantee they are always in front of everything, including the player and platforms ---
game.bringButtonsToFront = function () {
	if (leftBtn && leftBtn.parent) {
		leftBtn.parent.setChildIndex(leftBtn, leftBtn.parent.children.length - 1);
	}
	if (leftIcon && leftIcon.parent) {
		leftIcon.parent.setChildIndex(leftIcon, leftIcon.parent.children.length - 1);
	}
	if (rightBtn && rightBtn.parent) {
		rightBtn.parent.setChildIndex(rightBtn, rightBtn.parent.children.length - 1);
	}
	if (rightIcon && rightIcon.parent) {
		rightIcon.parent.setChildIndex(rightIcon, rightIcon.parent.children.length - 1);
	}
	if (jumpBtn && jumpBtn.parent) {
		jumpBtn.parent.setChildIndex(jumpBtn, jumpBtn.parent.children.length - 1);
	}
	if (jumpIcon && jumpIcon.parent) {
		jumpIcon.parent.setChildIndex(jumpIcon, jumpIcon.parent.children.length - 1);
	}
	if (fireBtn && fireBtn.parent) {
		fireBtn.parent.setChildIndex(fireBtn, fireBtn.parent.children.length - 1);
	}
	if (terlikIcon && terlikIcon.parent) {
		terlikIcon.parent.setChildIndex(terlikIcon, terlikIcon.parent.children.length - 1);
	}
};
// Call this in every game.update to ensure buttons are always in front
var _origUpdate = game.update;
game.update = function () {
	game.bringButtonsToFront && game.bringButtonsToFront();
	if (_origUpdate) {
		return _origUpdate.apply(this, arguments);
	}
};
// Helper to check if a point is inside a button
function isInsideBtn(btn, x, y) {
	var bx = btn.x,
		by = btn.y,
		bw = btn.width,
		bh = btn.height;
	// LK.gui is scaled, so use screen coordinates directly
	return x >= bx - bw / 2 && x <= bx + bw / 2 && y >= by - bh / 2 && y <= by + bh / 2;
}
// Overwrite game.down for button controls
game.down = function (x, y, obj) {
	// Handle title screen play button
	if (!gameStarted && playButton && isInsidePlayButton(x, y)) {
		startGameFromTitle();
		return;
	}
	// Shop logic removed
	// Don't process game controls if game hasn't started yet
	if (!gameStarted) {
		return;
	}
	if (gameOver) {
		return;
	}
	// Check if pressed on left, right, or jump button
	if (player && player.isFrozen) {
		return; // Block all movement/jump button actions while frozen
	}
	if (isInsideBtn(leftBtn, x, y)) {
		leftBtnPressed = true;
		// --- Ava: If waitingForLeftBtn, allow movement to resume only on left button press ---
		if (player && player.waitingForLeftBtn) {
			player.waitingForLeftBtn = false;
			moveDir = -1;
		} else if (!player.waitingForLeftBtn) {
			moveDir = -1;
		}
		// Stop auto-move right if active
		if (typeof autoMoveRightActive !== "undefined" && autoMoveRightActive) {
			autoMoveRightActive = false;
		}
		// Play 'y' sound on left button press
		var ySound = LK.getSound && LK.getSound('y');
		if (ySound && typeof ySound.play === "function") {
			ySound.play();
		}
	}
	if (isInsideBtn(rightBtn, x, y)) {
		rightBtnPressed = true;
		// --- Ava: If waitingForLeftBtn, allow movement to resume on right button as well ---
		if (player && player.waitingForLeftBtn) {
			player.waitingForLeftBtn = false;
			moveDir = 1;
		} else if (!player.waitingForLeftBtn) {
			moveDir = 1;
		}
		// --- Double-tap detection for right button ---
		if (typeof rightBtnLastTapTime === "undefined") {
			rightBtnLastTapTime = 0;
			rightBtnTapCount = 0;
		}
		var now = Date.now();
		if (now - rightBtnLastTapTime < 400) {
			rightBtnTapCount++;
		} else {
			rightBtnTapCount = 1;
		}
		rightBtnLastTapTime = now;
		if (rightBtnTapCount === 2) {
			// Toggle auto-move right: if already active, turn off; if not, turn on
			if (typeof autoMoveRightActive === "undefined") {
				autoMoveRightActive = false;
			}
			if (autoMoveRightActive) {
				autoMoveRightActive = false;
				moveDir = 0;
			} else {
				autoMoveRightActive = true;
				moveDir = 1;
			}
			rightBtnTapCount = 0;
		}
		// Play 'y' sound on right button press
		var ySound = LK.getSound && LK.getSound('y');
		if (ySound && typeof ySound.play === "function") {
			ySound.play();
		}
	}
	if (isInsideBtn(jumpBtn, x, y)) {
		jumpBtnPressed = true;
		if (player.isOnGround) {
			player.jumpRequested = true;
		}
	}
	// Fire button: shoot bullet
	if (typeof fireBtn !== "undefined" && isInsideBtn(fireBtn, x, y)) {
		if (typeof playerAmmo === "undefined" || playerAmmo > 0) {
			var bullet = new Bullet();
			bullet.x = player.x;
			bullet.y = player.y - player.height / 2;
			bullet.lastX = bullet.x;
			bullet.vx = 40;
			bullet.vy = 0;
			bullet.isControlled = false;
			bullets.push(bullet);
			game.addChild(bullet);
			if (typeof playerAmmo !== "undefined") {
				playerAmmo--;
			}
		}
		return;
	}
	// If not on any button, allow fire mechanic as before (right half of screen)
	if (!isInsideBtn(leftBtn, x, y) && !isInsideBtn(rightBtn, x, y) && !isInsideBtn(jumpBtn, x, y)) {
		// Fire a bullet only if this is a double-tap (within 350ms) on the right side
		if (x > 2048 / 2) {
			if (typeof lastFireTapTime === "undefined") {
				lastFireTapTime = 0;
			}
			var now = Date.now();
			if (now - lastFireTapTime < 350) {
				// Double-tap detected: fire bullet
				if (typeof playerAmmo === "undefined" || playerAmmo > 0) {
					var bullet = new Bullet();
					bullet.x = player.x;
					bullet.y = player.y - player.height / 2;
					bullet.lastX = bullet.x;
					// Set initial direction to right, but allow control
					bullet.vx = 0;
					bullet.vy = 0;
					bullet.isControlled = true; // Mark as controlled
					bullets.push(bullet);
					game.addChild(bullet);
					// Store the controlled bullet reference for move/up
					game.controlledBullet = bullet;
					if (typeof playerAmmo !== "undefined") {
						playerAmmo--;
					}
				}
				lastFireTapTime = 0; // Reset
			} else {
				// First tap: just record time
				lastFireTapTime = now;
			}
		}
	}
};
// Overwrite game.up for button controls
game.up = function (x, y, obj) {
	// Don't process game controls if game hasn't started yet
	if (!gameStarted) {
		return;
	}
	// Release movement/jump on button up
	if (isInsideBtn(leftBtn, x, y)) {
		leftBtnPressed = false;
		if (!rightBtnPressed) {
			moveDir = 0;
		} else {
			moveDir = 1;
		}
	}
	if (isInsideBtn(rightBtn, x, y)) {
		rightBtnPressed = false;
		if (!leftBtnPressed) {
			moveDir = 0;
		} else {
			moveDir = -1;
		}
	}
	if (isInsideBtn(jumpBtn, x, y)) {
		jumpBtnPressed = false;
	}
	// Release bullet control on touch up
	if (game.controlledBullet && game.controlledBullet.isControlled) {
		game.controlledBullet.isControlled = false;
		game.controlledBullet = null;
	}
};
// Overwrite game.move for button controls and bullet direction
game.move = function (x, y, obj) {
	// Don't process game controls if game hasn't started yet
	if (!gameStarted) {
		return;
	}
	// Block movement and jump while frozen
	if (player && player.isFrozen) {
		return;
	}
	// If dragging on left/right button, update moveDir
	if (leftBtnPressed && isInsideBtn(leftBtn, x, y)) {
		moveDir = -1;
	} else if (rightBtnPressed && isInsideBtn(rightBtn, x, y)) {
		moveDir = 1;
	} else if (!leftBtnPressed && !rightBtnPressed) {
		moveDir = 0;
	}
	// If a controlled bullet exists, update its velocity based on drag direction
	if (game.controlledBullet && game.controlledBullet.isControlled) {
		var bx = game.controlledBullet.x;
		var by = game.controlledBullet.y;
		var gx = x + cameraX;
		var gy = y;
		var dx = gx - bx;
		var dy = gy - by;
		var len = Math.sqrt(dx * dx + dy * dy);
		if (len > 0) {
			// Set bullet speed (fixed magnitude, e.g. 40 px/frame)
			var speed = 40;
			game.controlledBullet.vx = dx / len * speed;
			game.controlledBullet.vy = dy / len * speed;
		}
	}
};
// --- Game Update Loop ---
game.update = function () {
	// Don't run game logic if game hasn't started yet
	if (!gameStarted) {
		return;
	}
	if (gameOver) {
		return;
	}
	// --- Player Movement ---
	// Auto-move right logic
	if (typeof autoMoveRightActive === "undefined") {
		autoMoveRightActive = false;
	}
	if (autoMoveRightActive) {
		// Play 'y' sound every time auto-move right is active and player is on ground and moving
		if (typeof player.lastAutoMoveYSound === "undefined") {
			player.lastAutoMoveYSound = 0;
		}
		// Only play every 12 frames to avoid spamming
		if (player.isOnGround && Math.abs(player.vx) > 0 && LK.ticks - player.lastAutoMoveYSound > 12) {
			var ySound = LK.getSound && LK.getSound('y');
			if (ySound && typeof ySound.play === "function") {
				ySound.play();
			}
			player.lastAutoMoveYSound = LK.ticks;
		}
		moveDir = 1;
	}
	// --- Ava: Prevent all movement if waitingForLeftBtn is true or player is frozen ---
	if (player && (player.waitingForLeftBtn || player.isFrozen)) {
		player.vx = 0;
		player.vy = player.isFrozen ? 0 : player.vy; // If frozen, also stop vertical movement
		// Prevent jump while frozen
		if (player.isFrozen) {
			player.jumpRequested = false;
		}
	} else {
		var speedMultiplier = 1 + (player.speedBoost || 0) * 0.2;
		player.vx = moveDir * PLAYER_SPEED * speedMultiplier;
	}
	// --- Character Animations ---
	// Running animation
	if (Math.abs(player.vx) > 0 && player.isOnGround) {
		// Start running animation if not already running
		if (typeof player.startRunningAnimation === "function") {
			player.startRunningAnimation();
		}
	} else {
		// Stop running animation if not moving or not on ground
		if (typeof player.stopRunningAnimation === "function") {
			player.stopRunningAnimation();
		}
	}
	// Apply gravity
	player.vy += GRAVITY;
	// Jump
	if (player.jumpRequested) {
		var jumpMultiplier = 1 + (player.jumpBoost || 0) * 0.15;
		player.vy = JUMP_VELOCITY * jumpMultiplier;
		player.jumpRequested = false;
		player.isOnGround = false;
		// Start jump animation
		if (typeof player.startJumpAnimation === "function") {
			player.startJumpAnimation();
		}
		// Play jump sound only if not muted
		if (!isMuted) {
			var zSound = LK.getSound && LK.getSound('z');
			if (zSound && typeof zSound.play === "function") {
				zSound.play();
			}
		}
	}
	// --- Play 'r' and 'y' sound on each step (horizontal movement, only once per step) ---
	if (typeof player.lastStepX === "undefined") {
		player.lastStepX = player.x;
	}
	if (typeof player.hasPlayedStepSound === "undefined") {
		player.hasPlayedStepSound = false;
	}
	if (player.isOnGround && Math.abs(player.vx) > 0 && Math.abs(player.x - player.lastStepX) >= player.width * 0.7 // step size: 0.7x width
	) {
		if (!player.hasPlayedStepSound) {
			if (!isMuted) {
				var rSound = LK.getSound && LK.getSound('r');
				if (rSound && typeof rSound.play === "function") {
					rSound.play();
				}
				var ySound = LK.getSound && LK.getSound('y');
				if (ySound && typeof ySound.play === "function") {
					ySound.play();
				}
			}
			player.hasPlayedStepSound = true;
		}
		// Update lastStepX to current position
		player.lastStepX = player.x;
	} else if (player.isOnGround && Math.abs(player.vx) === 0) {
		// Reset flag when player stops moving
		player.hasPlayedStepSound = false;
	}
	// Move horizontally, check collisions
	player.x += player.vx;
	var collidedX = false;
	for (var i = 0; i < platforms.length; i++) {
		var plat = platforms[i];
		if (intersectsAABB({
			x: player.x - player.width / 2,
			y: player.y - player.height,
			width: player.width,
			height: player.height
		}, {
			x: plat.x,
			y: plat.y,
			width: plat.width,
			height: plat.height
		})) {
			// Collided horizontally, push player out
			if (player.vx > 0) {
				player.x = plat.x - player.width / 2;
			} else if (player.vx < 0) {
				player.x = plat.x + plat.width + player.width / 2;
			}
			collidedX = true;
		}
	}
	// Move vertically, check collisions
	player.y += player.vy;
	var collidedY = false;
	player.isOnGround = false;
	for (var i = 0; i < platforms.length; i++) {
		var plat = platforms[i];
		if (intersectsAABB({
			x: player.x - player.width / 2,
			y: player.y - player.height,
			width: player.width,
			height: player.height
		}, {
			x: plat.x,
			y: plat.y,
			width: plat.width,
			height: plat.height
		})) {
			// Collided vertically
			if (player.vy > 0) {
				// Falling, land on platform
				player.y = plat.y;
				player.vy = 0;
				player.isOnGround = true;
				// Update last safe platform index to this platform
				lastSafePlatformIndex = i;
				// If this is the boss platform and boss exists, start boss firing
				if (boss && plat.width >= 1800 &&
				// Boss platform is the wide one
				typeof boss.bossStartFiring !== "undefined") {
					boss.bossStartFiring = true;
				}
			} else if (player.vy < 0) {
				// Hitting head
				player.y = plat.y + plat.height + player.height;
				player.vy = 0;
			}
			collidedY = true;
		}
	}
	// (bottomCloud platform collision removed)
	// (bottomCloud instant death logic removed)
	// --- Coin/Heart Collection ---
	for (var i = coins.length - 1; i >= 0; i--) {
		var coin = coins[i];
		if (intersectsAABB({
			x: player.x - player.width / 2,
			y: player.y - player.height,
			width: player.width,
			height: player.height
		}, {
			x: coin.x - coin.width / 2,
			y: coin.y - coin.height / 2,
			width: coin.width,
			height: coin.height
		})) {
			// If this is a heart (centerCircle), increase playerLives, up to max 5
			if (coin.isHeart) {
				if (playerLives < 5) {
					playerLives++;
					updateHearts();
				} else {
					// If already at max health, give 20 points instead
					score += 20;
					scoreTxt.setText(score);
					// Every 20 points, convert to 1 life (up to max 5)
					if (score >= 20) {
						var extraLives = Math.floor(score / 20);
						var livesToAdd = Math.min(extraLives, 5 - playerLives);
						if (livesToAdd > 0) {
							playerLives += livesToAdd;
							updateHearts();
							score -= livesToAdd * 20;
							scoreTxt.setText(score);
						}
					}
				}
			} else {
				// Otherwise, it's a coin, increase score and shop coins
				score += 1;
				shopCoins += 1;
				storage.shopCoins = shopCoins;
				scoreTxt.setText(score);
				// Every 20 points, convert to 1 life (up to max 5)
				if (score >= 20) {
					var extraLives = Math.floor(score / 20);
					var livesToAdd = Math.min(extraLives, 5 - playerLives);
					if (livesToAdd > 0) {
						playerLives += livesToAdd;
						updateHearts();
						score -= livesToAdd * 20;
						scoreTxt.setText(score);
					}
				}
			}
			coin.destroy();
			coins.splice(i, 1);
		}
	}
	// --- Checkpoint Collection ---
	// Only mark checkpoint as collected when falling, not on touch
	// (handled in fall logic below)
	// --- Bullets Update ---
	var bossFightActive = boss && boss.bossStartFiring === true;
	// Only update bullets if not in boss fight, or if they are boss/player bullets
	for (var i = bullets.length - 1; i >= 0; i--) {
		var bullet = bullets[i];
		// During boss fight, only allow boss/player bullets to move (skip all others)
		if (bossFightActive && !bullet.isBossProjectile) {
			// Pause non-boss bullets (do not update position)
			// Optionally, you could hide or destroy them here if desired
			continue;
		}
		bullet.update();
		// Remove bullet if off screen (right side)
		if (bullet.lastX <= LEVEL_LENGTH && bullet.x > LEVEL_LENGTH) {
			bullet.destroy();
			bullets.splice(i, 1);
			continue;
		}
		// Remove bullet if off left or out of vertical bounds, respawn at top if falls below
		if (bullet.x < 0 || bullet.y < 0) {
			bullet.destroy();
			bullets.splice(i, 1);
			continue;
		} else if (bullet.y > 2732) {
			// Respawn bullet at the top of the screen, keep its x and vx/vy
			bullet.y = 0;
			// Optionally, you can randomize x or keep as is
			// bullet.x = Math.random() * 2048;
			// Keep lastY in sync to avoid false triggers
			bullet.lastY = bullet.y;
		}
		// --- Bullet stuck detection: remove if not moving for 12 frames ---
		if (typeof bullet.stuckFrames === "undefined") {
			bullet.stuckFrames = 0;
		}
		if (Math.abs(bullet.x - bullet.lastX) < 1 && Math.abs(bullet.y - bullet.lastY) < 1) {
			bullet.stuckFrames++;
			if (bullet.stuckFrames > 12) {
				bullet.destroy();
				bullets.splice(i, 1);
				continue;
			}
		} else {
			bullet.stuckFrames = 0;
		}
		// Render bullet at camera-relative position
		bullet.displayObject = bullet.displayObject || bullet;
		bullet.displayObject.x = bullet.x - cameraX;
		bullet.displayObject.y = bullet.y;
	}
	// --- Auto-fire at boss when visible ---
	if (!bossFightActive) {
		if (boss && _typeof(boss) === "object" && typeof boss.x === "number" && typeof boss.y === "number") {
			// Check if boss is visible on screen (simple check: boss.x - cameraX in [0, 2048])
			var bossScreenX = boss.x - cameraX;
			if (bossScreenX > 0 && bossScreenX < 2048) {
				// Only fire if enough time has passed since last auto-fire
				if (typeof bossAutoFireTimer === "undefined") {
					bossAutoFireTimer = 0;
				}
				bossAutoFireTimer++;
				// Fire every 18 frames (~3 shots per second)
				if (bossAutoFireTimer > 18) {
					bossAutoFireTimer = 0;
					// Create a bullet aimed at boss
					var autoBullet = new Bullet();
					autoBullet.x = player.x;
					autoBullet.y = player.y - player.height / 2;
					autoBullet.lastX = autoBullet.x;
					// Aim at boss center
					var dx = boss.x - autoBullet.x;
					var dy = boss.y - boss.height / 2 - autoBullet.y;
					var len = Math.sqrt(dx * dx + dy * dy);
					var speed = 40;
					if (len > 0) {
						autoBullet.vx = dx / len * speed;
						autoBullet.vy = dy / len * speed;
					} else {
						autoBullet.vx = speed;
						autoBullet.vy = 0;
					}
					autoBullet.isControlled = false;
					bullets.push(autoBullet);
					game.addChild(autoBullet);
				}
			} else {
				// Reset timer if boss is not visible
				bossAutoFireTimer = 18;
			}
		}
	}
	// --- Enemy Update & Collision ---
	if (!bossFightActive) {
		// Delay enemy movement for 3 seconds after game start
		if (typeof enemyStartDelay === "undefined") {
			enemyStartDelay = 180;
		} // 3 seconds at 60fps
		if (enemyStartDelay > 0) {
			enemyStartDelay--;
		} else {
			if (typeof enemySpawnTimer === "undefined") {
				enemySpawnTimer = 0;
			}
			enemySpawnTimer++;
			// Spawn a new enemy every 120-200 frames (randomized)
			if (enemySpawnTimer > 120 + Math.floor(Math.random() * 80)) {
				// Ava: Only spawn freezing enemy if not spawned this level, and with low probability
				if (!freezingEnemySpawned && Math.random() < 0.18) {
					// ~18% chance per spawn window, so rare
					var freezingEnemy = new FreezingEnemy();
					freezingEnemy.x = cameraX + 2048 + freezingEnemy.width / 2;
					freezingEnemy.y = 400 + Math.random() * (2100 - 400);
					freezingEnemy.lastX = freezingEnemy.x;
					freezingEnemy.lastWasIntersecting = false;
					enemies.push(freezingEnemy);
					game.addChild(freezingEnemy);
					freezingEnemySpawned = true;
				} else {
					var enemy = new Enemy();
					// Spawn at right edge, random Y within play area
					enemy.x = cameraX + 2048 + enemy.width / 2;
					// Avoid top 200px and bottom 400px
					enemy.y = 400 + Math.random() * (2100 - 400);
					enemy.lastX = enemy.x;
					enemy.lastWasIntersecting = false;
					enemies.push(enemy);
					game.addChild(enemy);
				}
				enemySpawnTimer = 0;
			}
			// Update and render enemies
			for (var i = enemies.length - 1; i >= 0; i--) {
				var enemy = enemies[i];
				enemy.update();
				// Remove if off left side
				if (enemy.lastX >= -enemy.width && enemy.x < -enemy.width) {
					enemy.destroy();
					enemies.splice(i, 1);
					continue;
				}
				// Render at camera-relative position
				enemy.displayObject = enemy.displayObject || enemy;
				enemy.displayObject.x = enemy.x - cameraX;
				enemy.displayObject.y = enemy.y;
				// --- Bullet-Enemy Collision ---
				var enemyDestroyed = false;
				for (var j = bullets.length - 1; j >= 0; j--) {
					var bullet = bullets[j];
					// Boss projectiles do not collide with other enemies
					if (enemy.isBossProjectile) {
						continue;
					}
					// Use AABB for bullet-enemy collision
					if (intersectsAABB({
						x: bullet.x - bullet.width / 2,
						y: bullet.y - bullet.height / 2,
						width: bullet.width,
						height: bullet.height
					}, {
						x: enemy.x - enemy.width / 2,
						y: enemy.y - enemy.height / 2,
						width: enemy.width,
						height: enemy.height
					})) {
						// Destroy both bullet and enemy
						bullet.destroy();
						bullets.splice(j, 1);
						enemy.destroy();
						enemies.splice(i, 1);
						// Optionally, add score or effect here
						score += 5;
						scoreTxt.setText(score);
						// Every 20 points, convert to 1 life (up to max 5)
						if (score >= 20) {
							var extraLives = Math.floor(score / 20);
							var livesToAdd = Math.min(extraLives, 5 - playerLives);
							if (livesToAdd > 0) {
								playerLives += livesToAdd;
								updateHearts();
								score -= livesToAdd * 20;
								scoreTxt.setText(score);
							}
						}
						enemyDestroyed = true;
						break;
					}
				}
				if (enemyDestroyed) {
					continue;
				}
				// Check collision with player (only on the frame it starts)
				var isIntersecting = intersectsAABB({
					x: player.x - player.width / 2,
					y: player.y - player.height,
					width: player.width,
					height: player.height
				}, {
					x: enemy.x - enemy.width / 2,
					y: enemy.y - enemy.height / 2,
					width: enemy.width,
					height: enemy.height
				});
				if (!enemy.lastWasIntersecting && isIntersecting) {
					// If this is a boss projectile, damage player and destroy projectile
					if (enemy.isBossProjectile) {
						LK.effects.flashScreen(0xff0000, 1000);
						playerLives--;
						updateHearts();
						if (playerLives <= 0) {
							gameOver = true;
							LK.showGameOver();
							return;
						}
						enemy.destroy();
						enemies.splice(i, 1);
						continue;
					}
					// --- FreezingEnemy collision logic ---
					if (enemy instanceof FreezingEnemy) {
						// Destroy freezing enemy
						enemy.destroy();
						enemies.splice(i, 1);
						// Freeze player for 2 seconds (120 frames)
						if (!player.isFrozen) {
							player.isFrozen = true;
							var prevVx = player.vx;
							var prevVy = player.vy;
							var prevMoveDir = moveDir;
							moveDir = 0;
							player.vx = 0;
							player.vy = 0;
							// Optional: visual effect (tint player blue)
							if (player.displayObject) {
								player.displayObject.tint = 0x66ccff;
							}
							// Set a timer to unfreeze after 2 seconds
							LK.setTimeout(function () {
								player.isFrozen = false;
								// Restore player tint
								if (player.displayObject) {
									player.displayObject.tint = 0xffffff;
								}
							}, 2000);
						}
						// Show freeze effect
						LK.effects.flashScreen(0x66ccff, 600);
						// Do not damage player or reduce lives
						enemy.lastWasIntersecting = isIntersecting;
						continue;
					}
					// Player hit by enemy!
					LK.effects.flashScreen(0xff0000, 1000);
					playerLives--;
					updateHearts();
					if (playerLives <= 0) {
						gameOver = true;
						LK.showGameOver();
						return;
					}
					// Do not respawn or move player, just continue playing
				}
				enemy.lastWasIntersecting = isIntersecting;
			}
		} // end else for enemyStartDelay
	}
	// --- Boss Fight: Boss projectiles damage player ---
	if (bossFightActive) {
		for (var i = enemies.length - 1; i >= 0; i--) {
			var enemy = enemies[i];
			enemy.update();
			// Remove if off left side or out of bounds
			if (enemy.lastX >= -enemy.width && enemy.x < -enemy.width) {
				enemy.destroy();
				enemies.splice(i, 1);
				continue;
			}
			// Render at camera-relative position
			enemy.displayObject = enemy.displayObject || enemy;
			enemy.displayObject.x = enemy.x - cameraX;
			enemy.displayObject.y = enemy.y;
			// Only check boss projectiles for player collision
			if (enemy.isBossProjectile) {
				var isIntersecting = intersectsAABB({
					x: player.x - player.width / 2,
					y: player.y - player.height,
					width: player.width,
					height: player.height
				}, {
					x: enemy.x - enemy.width / 2,
					y: enemy.y - enemy.height / 2,
					width: enemy.width,
					height: enemy.height
				});
				if (!enemy.lastWasIntersecting && isIntersecting) {
					LK.effects.flashScreen(0xff0000, 1000);
					playerLives--;
					updateHearts();
					if (playerLives <= 0) {
						gameOver = true;
						LK.showGameOver();
						return;
					}
					enemy.destroy();
					enemies.splice(i, 1);
					continue;
				}
				enemy.lastWasIntersecting = isIntersecting;
			}
		}
	}
	// --- Boss Update & Collision ---
	// Boss health bar setup (global, so only one at a time)
	if (typeof bossHealthBarBg === "undefined") {
		bossHealthBarBg = null;
	}
	if (typeof bossHealthBarFill === "undefined") {
		bossHealthBarFill = null;
	}
	if (boss && typeof boss.update === "function") {
		boss.update();
		// Render boss at camera-relative position
		boss.displayObject = boss.displayObject || boss;
		boss.displayObject.x = boss.x - cameraX;
		boss.displayObject.y = boss.y;
		// --- Boss Health Bar ---
		// Create health bar if not exists
		if (!bossHealthBarBg) {
			// Background bar (custom asset)
			bossHealthBarBg = LK.getAsset('bossHealthBarBg', {
				anchorX: 0.5,
				anchorY: 0.5
			});
			bossHealthBarBg.alpha = 0.7;
			game.addChild(bossHealthBarBg);
			// Fill bar (custom asset)
			bossHealthBarFill = LK.getAsset('bossHealthBarFill', {
				anchorX: 0,
				anchorY: 0.5
			});
			bossHealthBarFill.alpha = 0.95;
			game.addChild(bossHealthBarFill);
		}
		// Update health bar position above boss
		if (bossHealthBarBg && bossHealthBarFill) {
			// Bar width and percent
			var barW = boss.width * 0.8;
			var barH = 44;
			var fillW = boss.width * 0.78;
			var fillH = 32;
			var percent = Math.max(0, boss.hp / 15);
			// Position above boss head (50px above top)
			var barX = boss.x - cameraX;
			var barY = boss.y - boss.height / 2 - 50;
			bossHealthBarBg.x = barX;
			bossHealthBarBg.y = barY;
			bossHealthBarBg.width = barW;
			bossHealthBarBg.height = barH;
			bossHealthBarBg.visible = true;
			bossHealthBarFill.x = barX - fillW / 2;
			bossHealthBarFill.y = barY;
			bossHealthBarFill.width = fillW * percent;
			bossHealthBarFill.height = fillH;
			bossHealthBarFill.visible = true;
		}
		// Bullet-boss collision
		for (var j = bullets.length - 1; j >= 0; j--) {
			var bullet = bullets[j];
			if (intersectsAABB({
				x: bullet.x - bullet.width / 2,
				y: bullet.y - bullet.height / 2,
				width: bullet.width,
				height: bullet.height
			}, {
				x: boss.x - boss.width / 2,
				y: boss.y - boss.height / 2,
				width: boss.width,
				height: boss.height
			})) {
				// Boss can only be damaged if not shielded, or if weak spot is open
				if (!boss.shieldActive && (boss.phase === 1 || boss.weakSpotOpen || boss.phase === 1)) {
					boss.hp--;
					bullet.destroy();
					bullets.splice(j, 1);
					// Flash boss on hit
					LK.effects.flashObject(boss, 0xff0000, 200);
					// If boss defeated
					if (boss.hp <= 0) {
						LK.effects.flashScreen(0x00ff00, 1000);
						boss.destroy();
						boss = null;
						score += 50;
						scoreTxt.setText(score);
						// Remove boss health bar
						if (bossHealthBarBg) {
							bossHealthBarBg.visible = false;
							bossHealthBarBg.destroy();
							bossHealthBarBg = null;
						}
						if (bossHealthBarFill) {
							bossHealthBarFill.visible = false;
							bossHealthBarFill.destroy();
							bossHealthBarFill = null;
						}
						// End the game with a win when boss is defeated
						LK.setScore(score);
						LK.showYouWin();
						return;
					}
					break;
				} else {
					// Boss is shielded or not vulnerable, bullet bounces off (destroy bullet)
					bullet.destroy();
					bullets.splice(j, 1);
					// Optional: flash boss blue for shield
					if (boss.shieldActive && boss.displayObject) {
						LK.effects.flashObject(boss, 0x44aaff, 120);
					}
					break;
				}
			}
		}
		// Boss-player collision (only on the frame it starts)
		if (boss) {
			// Defensive: boss may have been destroyed above
			var bossIntersect = intersectsAABB({
				x: player.x - player.width / 2,
				y: player.y - player.height,
				width: player.width,
				height: player.height
			}, {
				x: boss.x - boss.width / 2,
				y: boss.y - boss.height / 2,
				width: boss.width,
				height: boss.height
			});
			if (!boss.lastWasIntersecting && bossIntersect) {
				LK.effects.flashScreen(0xff0000, 1000);
				playerLives--;
				updateHearts();
				if (playerLives <= 0) {
					gameOver = true;
					LK.showGameOver();
					// Remove boss health bar
					if (bossHealthBarBg) {
						bossHealthBarBg.visible = false;
						bossHealthBarBg.destroy();
						bossHealthBarBg = null;
					}
					if (bossHealthBarFill) {
						bossHealthBarFill.visible = false;
						bossHealthBarFill.destroy();
						bossHealthBarFill = null;
					}
					return;
				}
			}
			boss.lastWasIntersecting = bossIntersect;
		}
	} else {
		// No boss: remove health bar if exists
		if (bossHealthBarBg) {
			bossHealthBarBg.visible = false;
			bossHealthBarBg.destroy();
			bossHealthBarBg = null;
		}
		if (bossHealthBarFill) {
			bossHealthBarFill.visible = false;
			bossHealthBarFill.destroy();
			bossHealthBarFill = null;
		}
	}
	// --- Hazard Update & Collision ---
	// Remove hazards during boss fight (currentLevel === 2 and boss exists)
	if (typeof hazards !== "undefined" && hazards.length && (typeof currentLevel === "undefined" || currentLevel === 1 || typeof currentLevel !== "undefined" && currentLevel === 2 && !boss)) {
		for (var i = hazards.length - 1; i >= 0; i--) {
			var hazard = hazards[i];
			// Ensure hazard has valid properties
			if (!hazard || typeof hazard.x !== "number" || typeof hazard.y !== "number") {
				hazards.splice(i, 1);
				continue;
			}
			// Initialize velocity if not set
			if (typeof hazard.vy !== "number") {
				hazard.vy = 12 + Math.random() * 6;
			}
			// Move hazard down
			hazard.y += hazard.vy;
			// Render at camera-relative position
			hazard.displayObject = hazard.displayObject || hazard;
			if (hazard.displayObject) {
				hazard.displayObject.x = hazard.x - cameraX;
				hazard.displayObject.y = hazard.y;
			}
			// Remove if off screen
			if (hazard.y > 2732 + 200) {
				hazard.destroy();
				hazards.splice(i, 1);
				continue;
			}
			// Check collision with player (AABB)
			if (player.x - player.width / 2 < hazard.x + hazard.width / 2 && player.x + player.width / 2 > hazard.x - hazard.width / 2 && player.y - player.height < hazard.y + hazard.height / 2 && player.y > hazard.y - hazard.height / 2) {
				LK.effects.flashScreen(0xff0000, 800);
				playerLives--;
				updateHearts();
				hazard.destroy();
				hazards.splice(i, 1);
				if (playerLives <= 0) {
					gameOver = true;
					LK.showGameOver();
					return;
				}
			}
		}
	} else if (typeof hazards !== "undefined" && hazards.length && typeof currentLevel !== "undefined" && currentLevel === 2 && boss) {
		// If boss fight is active, despawn all hazards immediately
		for (var i = hazards.length - 1; i >= 0; i--) {
			if (hazards[i] && typeof hazards[i].destroy === "function") {
				hazards[i].destroy();
			}
		}
		hazards = [];
	}
	// --- Camera & Distance ---
	updateCamera();
	// Move all objects to screen position (for rendering only, do not overwrite world position)
	for (var i = 0; i < platforms.length; i++) {
		platforms[i].displayObject = platforms[i].displayObject || platforms[i];
		platforms[i].displayObject.x = platforms[i].xScreen;
		platforms[i].displayObject.y = platforms[i].y;
	}
	for (var i = 0; i < coins.length; i++) {
		coins[i].displayObject = coins[i].displayObject || coins[i];
		coins[i].displayObject.x = coins[i].xScreen;
		coins[i].displayObject.y = coins[i].y;
	}
	player.displayObject = player.displayObject || player;
	player.displayObject.x = player.xScreen;
	player.displayObject.y = player.y;
	// Move coffeeHouse to screen position if exists
	if (coffeeHouse && typeof coffeeHouse.xScreen !== "undefined") {
		coffeeHouse.x = coffeeHouse.xScreen;
		coffeeHouse.y = coffeeHouse.yScreen;
	}
	// (bottomCloud render removed)
	// (hazard removed)
	// --- Distance ---
	distance = Math.floor((player.x + cameraX) / 10);
	distTxt.setText(distance + "m");
	// --- Win/Lose Conditions ---
	// Fall off screen
	if (player.y > 2732) {
		LK.effects.flashScreen(0xff0000, 1000);
		playerLives--;
		updateHearts();
		// Find the platform the player was last above before falling
		if (typeof lastFallenPlatformIndex === "undefined") {
			lastFallenPlatformIndex = 0;
		}
		lastFallenPlatformIndex = 0;
		var minDist = Infinity;
		for (var i = 0; i < platforms.length; i++) {
			var plat = platforms[i];
			// Check if player was horizontally above this platform when falling
			if (player.x + player.width / 2 >= plat.x && player.x - player.width / 2 <= plat.x + plat.width) {
				// Find the closest platform vertically below the player
				var dy = player.y - plat.y;
				if (dy >= 0 && dy < minDist) {
					minDist = dy;
					lastFallenPlatformIndex = i;
				}
			}
		}
		// Find the nearest checkpoint at or before the fallen platform
		var checkpointToRespawn = 0;
		if (typeof checkpoints !== "undefined" && checkpoints.length) {
			var closestCheckpointIndex = -1;
			for (var i = 0; i < checkpoints.length; i++) {
				var checkpoint = checkpoints[i];
				if (checkpoint.platformIndex <= lastFallenPlatformIndex) {
					if (closestCheckpointIndex === -1 || checkpoint.platformIndex > checkpoints[closestCheckpointIndex].platformIndex) {
						closestCheckpointIndex = i;
					}
				}
			}
			if (closestCheckpointIndex !== -1) {
				checkpointToRespawn = checkpoints[closestCheckpointIndex].platformIndex;
				// Mark checkpoint as collected
				if (!checkpoints[closestCheckpointIndex].collected) {
					checkpoints[closestCheckpointIndex].collected = true;
					lastCheckpointIndex = checkpointToRespawn;
					checkpoints[closestCheckpointIndex].alpha = 0.5;
				}
			}
		}
		if (playerLives <= 0) {
			gameOver = true;
			LK.showGameOver();
			return;
		} else {
			// Respawn player at the nearest checkpoint (every 10th platform), or at the platform they fell from if no checkpoint reached
			if (typeof checkpointToRespawn !== "undefined" && checkpointToRespawn > 0 && checkpointToRespawn < platforms.length) {
				lastFallenPlatformIndex = checkpointToRespawn;
			}
			resetPlayer(true);
			// Optionally, move camera to player
			updateCamera();
			return;
		}
	}
	// Reached coffee house (win condition)
	if (coffeeHouse && intersectsAABB({
		x: player.x - player.width / 2,
		y: player.y - player.height,
		width: player.width,
		height: player.height
	}, {
		x: coffeeHouse.x - coffeeHouse.width / 2,
		y: coffeeHouse.y - coffeeHouse.height,
		width: coffeeHouse.width,
		height: coffeeHouse.height
	})) {
		LK.effects.flashScreen(0x00ff00, 1000);
		LK.setScore(score);
		// If on level 1, 2, 3, or 4, transition to next level
		if (typeof currentLevel === "undefined" || currentLevel === 1 || currentLevel === 2 || currentLevel === 3 || currentLevel === 4) {
			if (typeof showKiraathaneSection === "function") {
				showKiraathaneSection();
			} else {
				// Fallback: just pause the game and show a message overlay
				var overlay = new Text2("Kıraathaneye ulaştın!\nYeni bölüm geliyor...", {
					size: 120,
					fill: 0x222222,
					align: "center"
				});
				overlay.anchor.set(0.5, 0.5);
				overlay.x = 2048 / 2;
				overlay.y = 2732 / 2;
				LK.gui.center.addChild(overlay);
				gameOver = true;
			}
			return;
		}
	}
	// Win condition: player reaches the last platform
	// (Removed win condition when stepping on the last platform so the game does not end)
	// if (platforms.length > 0) {
	// var lastPlat = platforms[platforms.length - 1];
	// if (player.x + player.width / 2 >= lastPlat.x && player.x - player.width / 2 <= lastPlat.x + lastPlat.width && player.y >= lastPlat.y && player.y - player.height <= lastPlat.y + lastPlat.height) {
	// LK.effects.flashScreen(0x00ff00, 1000);
	// LK.setScore(score);
	// LK.showYouWin();
	// gameOver = true;
	// return;
	// }
	// }
};
// --- Game Start ---
// --- Title Screen with Play Button ---
var gameStarted = false;
var titleScreen = null;
var playButton = null;
var gameTitle = null;
function createTitleScreen() {
	// Create animated background elements first
	var bgElements = [];
	// Add moving clouds
	for (var i = 0; i < 5; i++) {
		var cloud = LK.getAsset('cloud', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		cloud.x = i * 500 - 200;
		cloud.y = 300 + Math.random() * 400;
		cloud.speed = 2 + Math.random() * 3;
		cloud.alpha = 0.3;
		bgElements.push(cloud);
		game.addChild(cloud);
	}
	// Add moving platforms across entire screen area
	for (var i = 0; i < 6; i++) {
		var platform = LK.getAsset('platformBox', {
			anchorX: 0,
			anchorY: 0
		});
		platform.x = i * 700 - 1000; // Fewer platforms, wider spacing
		// Store original Y for animation reference
		platform.baseY = Math.random() * 2732; // Distribute across entire screen height (0 to 2732)
		platform.y = platform.baseY;
		platform.speed = 1.5 + Math.random() * 3; // Varied speed range
		platform.alpha = 0.3 + Math.random() * 0.3; // Varied transparency
		bgElements.push(platform);
		game.addChild(platform);
		// Gentle up-down animation using tween, looped
		(function animatePlatformY(p) {
			var amplitude = 40 + Math.random() * 30; // 40-70px
			var duration = 1200 + Math.random() * 600; // 1.2-1.8s
			tween(p, {
				y: p.baseY + amplitude
			}, {
				duration: duration,
				easing: tween.sineInOut,
				onFinish: function onFinish() {
					tween(p, {
						y: p.baseY - amplitude
					}, {
						duration: duration,
						easing: tween.sineInOut,
						onFinish: function onFinish() {
							animatePlatformY(p);
						}
					});
				}
			});
		})(platform);
	}
	// Add animated tea (çay) assets with gentle up-down animation
	for (var i = 0; i < 3; i++) {
		var cay = LK.getAsset('centerCircle', {
			anchorX: 0.5,
			anchorY: 0.5,
			scaleX: 0.7,
			scaleY: 0.7
		});
		// Place çay at visually pleasing locations on the title screen
		cay.x = 600 + i * 400;
		cay.baseY = 1200 + Math.random() * 400;
		cay.y = cay.baseY;
		cay.alpha = 0.85;
		bgElements.push(cay);
		game.addChild(cay);
		// Gentle up-down animation using tween, looped
		(function animateCayY(c) {
			var amplitude = 30 + Math.random() * 20; // 30-50px
			var duration = 1100 + Math.random() * 500; // 1.1-1.6s
			tween(c, {
				y: c.baseY + amplitude
			}, {
				duration: duration,
				easing: tween.sineInOut,
				onFinish: function onFinish() {
					tween(c, {
						y: c.baseY - amplitude
					}, {
						duration: duration,
						easing: tween.sineInOut,
						onFinish: function onFinish() {
							animateCayY(c);
						}
					});
				}
			});
		})(cay);
	}
	// Add market building moving across title screen
	var market = LK.getAsset('coffeeHouse', {
		anchorX: 0.5,
		anchorY: 1
	});
	market.x = -600; // Start off screen left
	market.y = 1800 + Math.random() * 400; // Position in lower area
	market.speed = 2.5 + Math.random() * 2; // Medium speed
	market.alpha = 0.5;
	market.scaleX = 0.8;
	market.scaleY = 0.8;
	bgElements.push(market);
	game.addChild(market);
	// Add occasional boss passing through (every ~8-12 seconds)
	var boss = LK.getAsset('bossUnique', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	boss.x = -800; // Start off screen left
	boss.y = 1000 + Math.random() * 600;
	boss.speed = 6 + Math.random() * 3; // Faster than other elements
	boss.alpha = 0.6;
	boss.nextSpawnTime = 480 + Math.random() * 240; // 8-12 seconds at 60fps
	boss.isVisible = false;
	bgElements.push(boss);
	game.addChild(boss);
	// Add moving sun
	var sun = LK.getAsset('sun', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	sun.x = 300;
	sun.y = 200;
	sun.alpha = 0.5;
	bgElements.push(sun);
	game.addChild(sun);
	// Store background elements for animation
	game.titleBgElements = bgElements;
	// Create title background - use existing color background instead of asset
	game.setBackgroundColor(0x87ceeb); // Keep sky blue background visible
	// Create game title as image asset
	gameTitle = LK.getAsset('kebabRunnerTitle', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 1.5,
		scaleY: 1.5
	});
	gameTitle.x = 2048 / 2;
	gameTitle.y = 400;
	game.addChild(gameTitle);
	// Create play button background
	playButton = LK.getAsset('playButton', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 0.3,
		scaleY: 0.3
	});
	playButton.x = 2048 / 2 - 400 - 150 + 300 + 200 + 100 - 30;
	playButton.y = 1600;
	playButton.interactive = true;
	game.addChild(playButton);
	// Shop button removed
	// (Removed shop text below icon as requested)
	// Add pulsing animation to play button
	if (playButton) {
		tween(playButton, {
			scaleX: 0.35,
			scaleY: 0.35
		}, {
			duration: 1000,
			easing: tween.easeInOut,
			onFinish: function onFinish() {
				if (playButton) {
					tween(playButton, {
						scaleX: 0.3,
						scaleY: 0.3
					}, {
						duration: 1000,
						easing: tween.easeInOut,
						onFinish: function onFinish() {
							// Recursive call to create infinite loop
							if (playButton && !gameStarted) {
								tween(playButton, {
									scaleX: 0.35,
									scaleY: 0.35
								}, {
									duration: 1000,
									easing: tween.easeInOut,
									onFinish: arguments.callee.caller
								});
							}
						}
					});
				}
			}
		});
	}
	// Hide game UI during title screen
	if (scoreTxt) {
		scoreTxt.visible = false;
	}
	if (distTxt) {
		distTxt.visible = false;
	}
	if (heartAssets && heartAssets.length) {
		for (var i = 0; i < heartAssets.length; i++) {
			if (heartAssets[i]) {
				heartAssets[i].visible = false;
			}
		}
	}
	// Hide control buttons during title screen
	if (leftBtn) {
		leftBtn.visible = false;
	}
	if (rightBtn) {
		rightBtn.visible = false;
	}
	if (jumpBtn) {
		jumpBtn.visible = false;
	}
	if (fireBtn) {
		fireBtn.visible = false;
	}
	if (leftIcon) {
		leftIcon.visible = false;
	}
	if (rightIcon) {
		rightIcon.visible = false;
	}
	if (jumpIcon) {
		jumpIcon.visible = false;
	}
	if (terlikIcon) {
		terlikIcon.visible = false;
	}
}
function removeTitleScreen() {
	// Clean up animated background elements
	if (game.titleBgElements) {
		for (var i = 0; i < game.titleBgElements.length; i++) {
			if (game.titleBgElements[i]) {
				game.titleBgElements[i].destroy();
			}
		}
		game.titleBgElements = null;
	}
	if (titleScreen) {
		titleScreen.destroy();
		titleScreen = null;
	}
	if (playButton) {
		playButton.destroy();
		playButton = null;
	}
	if (gameTitle) {
		gameTitle.destroy();
		gameTitle = null;
	}
	// Shop button cleanup removed
	// Show control buttons when title screen is removed
	if (leftBtn) {
		leftBtn.visible = true;
	}
	if (rightBtn) {
		rightBtn.visible = true;
	}
	if (jumpBtn) {
		jumpBtn.visible = true;
	}
	if (fireBtn) {
		fireBtn.visible = true;
	}
	if (leftIcon) {
		leftIcon.visible = true;
	}
	if (rightIcon) {
		rightIcon.visible = true;
	}
	if (jumpIcon) {
		jumpIcon.visible = true;
	}
	if (terlikIcon) {
		terlikIcon.visible = true;
	}
}
function startGameFromTitle() {
	gameStarted = true;
	removeTitleScreen();
	// Show game UI
	if (scoreTxt) {
		scoreTxt.visible = true;
	}
	if (distTxt) {
		distTxt.visible = true;
	}
	if (heartAssets && heartAssets.length) {
		for (var i = 0; i < heartAssets.length; i++) {
			if (heartAssets[i]) {
				heartAssets[i].visible = i < playerLives;
			}
		}
	}
	// Start the actual game
	startGame();
}
// Check if point is inside play button
function isInsidePlayButton(x, y) {
	if (!playButton) {
		return false;
	}
	var bx = playButton.x;
	var by = playButton.y;
	var bw = playButton.width;
	var bh = playButton.height;
	return x >= bx - bw / 2 && x <= bx + bw / 2 && y >= by - bh / 2 && y <= by + bh / 2;
}
// Check if point is inside shop button
function isInsideShopButton(x, y) {
	return false;
}
// Shop system functions removed
// Create title screen initially
createTitleScreen();
var _origUpdate = game.update;
game.update = function () {
	// Animate title screen background elements
	if (!gameStarted && game.titleBgElements) {
		for (var i = 0; i < game.titleBgElements.length; i++) {
			var element = game.titleBgElements[i];
			if (element) {
				// Special handling for boss element
				if (element.nextSpawnTime !== undefined) {
					// This is the boss element
					if (!element.isVisible) {
						// Boss is waiting to spawn
						element.nextSpawnTime--;
						if (element.nextSpawnTime <= 0) {
							// Time to spawn boss
							element.isVisible = true;
							element.x = -800;
							element.y = 1000 + Math.random() * 600;
							element.visible = true;
							// Add slight tween animation for dramatic effect
							tween(element, {
								scaleX: 1.2,
								scaleY: 1.2
							}, {
								duration: 500,
								easing: tween.easeOut,
								onFinish: function onFinish() {
									tween(element, {
										scaleX: 1,
										scaleY: 1
									}, {
										duration: 500,
										easing: tween.easeInOut
									});
								}
							});
						}
					} else {
						// Boss is moving across screen
						element.x += element.speed || 6;
						// Reset when off screen
						if (element.x > 2048 + 400) {
							element.isVisible = false;
							element.visible = false;
							element.nextSpawnTime = 480 + Math.random() * 240; // 8-12 seconds
						}
					}
				} else {
					// Regular element movement
					element.x += element.speed || 2;
					// Reset position when off screen
					if (element.x > 2048 + 200) {
						element.x = -500; // Start further off-screen for better distribution
						// Randomize Y position for clouds, platforms, and market
						if (element.speed < 5) {
							// clouds have lower speed
							element.y = 300 + Math.random() * 400;
						} else if (element.scaleX === 0.8 && element.scaleY === 0.8) {
							// market building - reset in lower area
							element.y = 1800 + Math.random() * 400;
						} else {
							// platforms - reset across entire screen height (0 to 2732)
							element.y = Math.random() * 2732;
						}
					}
					// Add gentle floating animation to sun
					if (element === game.titleBgElements[game.titleBgElements.length - 1] && element.nextSpawnTime === undefined) {
						element.y = 200 + Math.sin(LK.ticks * 0.02) * 20;
					}
				}
			}
		}
	}
	if (_origUpdate) {
		return _origUpdate.apply(this, arguments);
	}
};
function startGame() {
	score = 0;
	distance = 0;
	gameOver = false;
	playerLives = 3;
	maxPlayerAmmo = 10;
	playerAmmo = maxPlayerAmmo; // Ava: refill ammo at game start
	// Ava: Initialize shopCoins from storage if available
	if (typeof storage !== "undefined" && typeof storage.shopCoins !== "undefined") {
		shopCoins = storage.shopCoins;
	} else {
		shopCoins = 0;
	}
	scoreTxt.setText(score);
	distTxt.setText(distance + "m");
	// Reset level to 1 at game start
	currentLevel = 1;
	// Reset enemies array and destroy old enemies if any
	if (typeof enemies !== "undefined" && enemies && enemies.length) {
		for (var i = 0; i < enemies.length; i++) {
			if (enemies[i] && typeof enemies[i].destroy === "function") {
				enemies[i].destroy();
			}
		}
	}
	enemies = [];
	// Reset checkpoints and lastCheckpointIndex
	checkpoints = [];
	lastCheckpointIndex = 0;
	freezingEnemySpawned = false; // Ava: Reset freezing enemy spawn for new level
	createLevel();
	resetPlayer();
	updateHearts();
	// (hazard removed)
	// Remove hazards if any
	if (typeof hazards !== "undefined" && hazards.length) {
		for (var i = 0; i < hazards.length; i++) {
			if (hazards[i] && typeof hazards[i].destroy === "function") {
				hazards[i].destroy();
			}
		}
	}
	hazards = [];
	cameraX = 0;
	moveDir = 0;
	enemyStartDelay = 180; // 3 seconds at 60fps
}
// --- Start ---
// Game will start when play button is pressed on title screen
// Show new section/scene after reaching coffeehouse (placeholder, can be customized)
// Track current level globally (1-based)
var currentLevel = 1;
if (typeof currentLevel === "undefined") {
	currentLevel = 1;
}
function showKiraathaneSection() {
	// Increase level up to 5
	if (typeof currentLevel === "undefined") {
		currentLevel = 1;
	}
	if (currentLevel < 5) {
		currentLevel++;
	}
	// Remove all game objects except GUI
	for (var i = 0; i < platforms.length; i++) {
		platforms[i].destroy();
	}
	for (var i = 0; i < coins.length; i++) {
		coins[i].destroy();
	}
	if (player) {
		player.destroy();
	}
	if (coffeeHouse) {
		coffeeHouse.destroy();
	}
	for (var i = 0; i < enemies.length; i++) {
		enemies[i].destroy();
	}
	for (var i = 0; i < bullets.length; i++) {
		bullets[i].destroy();
	}
	if (typeof boss !== "undefined" && boss) {
		boss.destroy();
		boss = null;
	}
	// Reset arrays
	platforms = [];
	coins = [];
	enemies = [];
	bullets = [];
	coffeeHouse = null;
	// Optionally, clear checkpoints for the new section
	checkpoints = [];
	lastCheckpointIndex = 0;
	// Remove hazards if any
	if (typeof hazards !== "undefined" && hazards.length) {
		for (var i = 0; i < hazards.length; i++) {
			if (hazards[i] && typeof hazards[i].destroy === "function") {
				hazards[i].destroy();
			}
		}
	}
	hazards = [];
	// Move camera to the start
	cameraX = 0;
	// Create a new set of platforms, coins, and coffeehouse (same as first section)
	freezingEnemySpawned = false; // Ava: Reset freezing enemy spawn for new level
	createLevel();
	resetPlayer();
	playerAmmo = maxPlayerAmmo; // Ava: refill ammo on level transition
	// Reset game state for the new section
	gameOver = false;
	moveDir = 0;
	enemyStartDelay = 180; // 3 seconds at 60fps
	// Show overlay for transition, indicating level number with black background and white text
	var levelText = currentLevel + ". lvl";
	var overlayBg = LK.getAsset('centerCircle', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 900,
		height: 300,
		color: 0x000000
	});
	overlayBg.x = 2048 / 2;
	overlayBg.y = 2732 / 2;
	overlayBg.alpha = 0.85;
	LK.gui.center.addChild(overlayBg);
	var kiraathaneOverlay = new Text2(levelText, {
		size: 180,
		fill: 0xffffff,
		align: "center"
	});
	kiraathaneOverlay.anchor.set(0.5, 0.5);
	kiraathaneOverlay.x = 2048 / 2;
	kiraathaneOverlay.y = 2732 / 2;
	LK.gui.center.addChild(kiraathaneOverlay);
	// Remove overlay after 1.5 seconds
	LK.setTimeout(function () {
		kiraathaneOverlay.destroy();
		overlayBg.destroy();
	}, 1500);
} /**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/**** 
* Classes
****/ 
// Boss class (for 2nd area end boss)
var Boss = Container.expand(function () {
	var self = Container.call(this);
	// Use the new unique boss image asset for the boss look
	var bossAsset = self.attachAsset('bossUnique', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.width = bossAsset.width;
	self.height = bossAsset.height;
	self.vx = -2; // Slow horizontal movement (optional)
	self.vy = 0;
	self.lastX = 0;
	self.lastY = 0;
	self.lastWasIntersecting = false;
	self.hp = 15; // Boss hit points (increased by 50%)
	self.isBoss = true;
	// Boss fight state
	self.phase = 1; // 1: normal, 2: jump, 3: fast
	self.attackTimer = 0;
	self.attackCooldown = 60; // frames between attacks (1.0 seconds at 60fps)
	// Boss only starts firing after player reaches boss platform
	self.bossStartFiring = false;
	self.jumpTimer = 0;
	self.isJumping = false;
	self.jumpVy = 0;
	self.groundY = self.y; // y position where boss stands
	self.shieldActive = false;
	self.shieldTimer = 0;
	self.shieldDuration = 60; // frames
	self.weakSpotOpen = false;
	self.weakSpotTimer = 0;
	self.weakSpotDuration = 40; // frames
	self.lastPhase = 1;
	self.update = function () {
		self.lastX = self.x;
		self.lastY = self.y;
		// --- Boss Phase Logic ---
		// Phase changes based on HP
		if (self.hp <= 7.5 && self.phase === 1) {
			self.phase = 2; // Start jumping attacks
			self.attackCooldown = 60; // 1.0 seconds at 60fps
		}
		if (self.hp <= 3 && self.phase === 2) {
			self.phase = 3; // Faster, more aggressive
			self.attackCooldown = 60; // 1.0 seconds at 60fps
		}
		// --- Boss Shield (defense) ---
		if (!self.shieldActive && Math.random() < 0.008 && self.phase > 1) {
			self.shieldActive = true;
			self.shieldTimer = self.shieldDuration;
			// Optional: visual effect for shield (tint blue)
			if (self.displayObject) {
				self.displayObject.tint = 0x44aaff;
			}
		}
		if (self.shieldActive) {
			self.shieldTimer--;
			if (self.shieldTimer <= 0) {
				self.shieldActive = false;
				if (self.displayObject) {
					self.displayObject.tint = 0xffffff;
				}
			}
		}
		// --- Weak Spot (vulnerable) ---
		if (!self.weakSpotOpen && Math.random() < 0.01 && self.phase > 1 && !self.shieldActive) {
			self.weakSpotOpen = true;
			self.weakSpotTimer = self.weakSpotDuration;
			// Optional: visual effect for weak spot (tint yellow)
			if (self.displayObject) {
				self.displayObject.tint = 0xffee44;
			}
		}
		if (self.weakSpotOpen) {
			self.weakSpotTimer--;
			if (self.weakSpotTimer <= 0) {
				self.weakSpotOpen = false;
				if (self.displayObject) {
					self.displayObject.tint = 0xffffff;
				}
			}
		}
		// --- Boss Attacks ---
		if (self.bossStartFiring) {
			self.attackTimer++;
			if (self.attackTimer >= self.attackCooldown && !self.shieldActive && !self.isJumping && !self.isLeaping) {
				self.attackTimer = 0;
				// Choose attack: 50% chance to leap, 50% to fire
				var doLeap = false;
				if (self.phase >= 2 && Math.random() < 0.5) {
					doLeap = true;
				}
				if (doLeap) {
					// Start leap attack: jump toward player, then return
					self.isLeaping = true;
					self.leapPhase = 0; // 0: going to player, 1: returning
					self.leapStartX = self.x;
					self.leapStartY = self.y;
					// Target player position at leap start
					self.leapTargetX = typeof player !== "undefined" ? player.x : self.x;
					self.leapTargetY = self.groundY;
					// Calculate leap velocity to reach player in N frames
					var leapFrames = 24;
					self.leapTimer = 0;
					self.leapTotalFrames = leapFrames;
					self.leapVX = (self.leapTargetX - self.x) / leapFrames;
					self.leapVY = -44; // Upward velocity
					self.leapGravity = (self.groundY - self.y - self.leapVY * leapFrames) * 2 / (leapFrames * leapFrames);
				} else {
					// Boss always fires projectile at player every attack, regardless of phase
					if (typeof bossFireProjectile === "function") {
						bossFireProjectile(self, self.phase === 3);
					}
				}
			}
		}
		// --- Boss Leap Attack ---
		if (self.isLeaping) {
			// Leap phase 0: jump toward player
			if (self.leapPhase === 0) {
				self.x += self.leapVX;
				self.y += self.leapVY;
				self.leapVY += self.leapGravity;
				self.leapTimer++;
				// If reached or passed groundY, land and start return
				if (self.y >= self.groundY) {
					self.y = self.groundY;
					self.leapPhase = 1;
					// On landing, create shockwave (damage if player is close)
					if (typeof bossShockwave === "function") {
						bossShockwave(self);
					}
					// Prepare return leap
					var returnFrames = 24;
					self.leapTimer = 0;
					self.leapTotalFrames = returnFrames;
					self.leapVX = (self.leapStartX - self.x) / returnFrames;
					self.leapVY = -38; // Upward velocity for return
					self.leapGravity = (self.groundY - self.y - self.leapVY * returnFrames) * 2 / (returnFrames * returnFrames);
				}
			} else if (self.leapPhase === 1) {
				// Return leap to original position
				self.x += self.leapVX;
				self.y += self.leapVY;
				self.leapVY += self.leapGravity;
				self.leapTimer++;
				if (self.y >= self.groundY || self.leapTimer >= self.leapTotalFrames) {
					self.y = self.groundY;
					self.x = self.leapStartX;
					self.isLeaping = false;
					self.leapPhase = 0;
					// On landing, create shockwave (damage if player is close)
					if (typeof bossShockwave === "function") {
						bossShockwave(self);
					}
				}
			}
		}
		// --- Boss Jumping (old jump attack, only used if not leaping) ---
		if (self.isJumping) {
			self.y += self.jumpVy;
			self.jumpVy += 4.5; // gravity
			if (self.y >= self.groundY) {
				self.y = self.groundY;
				self.isJumping = false;
				// On landing, create shockwave (damage if player is close)
				if (typeof bossShockwave === "function") {
					bossShockwave(self);
				}
			}
		}
		// --- Boss Movement (side to side in phase 3) ---
		if (self.phase === 3 && !self.isJumping && !self.isLeaping) {
			// Move left and right slowly
			if (!self.moveDir) {
				self.moveDir = -1;
			}
			self.x += self.moveDir * 7;
			// Clamp to wide platform area (assume platform at y = self.groundY + boss.height/2 + 200)
			var minX = self.x0 || self.x - 600;
			var maxX = self.x1 || self.x + 600;
			if (!self.x0) {
				self.x0 = self.x - 600;
			}
			if (!self.x1) {
				self.x1 = self.x + 600;
			}
			if (self.x < minX) {
				self.x = minX;
				self.moveDir = 1;
			}
			if (self.x > maxX) {
				self.x = maxX;
				self.moveDir = -1;
			}
		}
	};
	return self;
});
// BossBullet class: used for boss projectiles, uses bossBullet asset
var BossBullet = Container.expand(function () {
	var self = Container.call(this);
	var bossBulletAsset = self.attachAsset('bossBullet', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.width = bossBulletAsset.width;
	self.height = bossBulletAsset.height;
	self.vx = 0;
	self.vy = 0;
	self.lastX = 0;
	self.lastY = 0;
	self.isBossProjectile = true;
	self.update = function () {
		self.lastX = self.x;
		self.lastY = self.y;
		self.x += self.vx;
		self.y += self.vy;
		// Clamp boss projectiles within boss platform bounds
		if (typeof platforms !== "undefined" && platforms.length > 0) {
			// Find the boss platform (the widest one, used for boss)
			var bossPlat = null;
			for (var i = 0; i < platforms.length; i++) {
				if (platforms[i].width >= 1800) {
					bossPlat = platforms[i];
					break;
				}
			}
			if (bossPlat) {
				var minX = bossPlat.x;
				var maxX = bossPlat.x + bossPlat.width;
				// Clamp self.x to platform bounds
				if (self.x < minX) {
					self.x = minX;
				}
				if (self.x > maxX) {
					self.x = maxX;
				}
			}
		}
	};
	return self;
});
// Bullet class
var Bullet = Container.expand(function () {
	var self = Container.call(this);
	// Use the new bullet figure asset
	var bulletAsset = self.attachAsset('bulletFigure', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.width = bulletAsset.width;
	self.height = bulletAsset.height;
	self.vx = 40; // Bullet speed (right)
	self.vy = 0; // Add vy for vertical movement
	self.active = true;
	self.lastX = 0;
	self.lastY = 0;
	self.isControlled = false; // If true, player can control direction
	self.update = function () {
		self.lastX = self.x;
		self.lastY = self.y;
		// If controlled, vx/vy may be set by player, else keep moving
		self.x += self.vx;
		self.y += self.vy;
	};
	return self;
});
// Coin class
var Coin = Container.expand(function () {
	var self = Container.call(this);
	var coinAsset = self.attachAsset('coinCircle', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.width = coinAsset.width;
	self.height = coinAsset.height;
	return self;
});
// Enemy class: simple flying enemy that moves left across the screen
var Enemy = Container.expand(function () {
	var self = Container.call(this);
	// Use a unique asset for the enemy (use '682f46a9c0116d543bc37477' as image)
	var enemyAsset = self.attachAsset('682f46a9c0116d543bc37477', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.width = enemyAsset.width;
	self.height = enemyAsset.height;
	self.vx = -14 - Math.random() * 6; // Move left at random speed
	self.vy = 0;
	self.lastX = 0;
	self.lastY = 0;
	self.lastWasIntersecting = false;
	self.isBossProjectile = false; // Not a boss projectile
	self.update = function () {
		self.lastX = self.x;
		self.lastY = self.y;
		self.x += self.vx;
		self.y += self.vy;
		// Optionally, add up/down movement for variety
		if (Math.random() < 0.02) {
			self.vy = (Math.random() - 0.5) * 8;
		}
		// Clamp Y to play area
		if (self.y < 200) {
			self.y = 200;
		}
		if (self.y > 2300) {
			self.y = 2300;
		}
	};
	return self;
});
// FreezingEnemy class: special enemy that appears only once per level
var FreezingEnemy = Container.expand(function () {
	var self = Container.call(this);
	// Use the freezing enemy asset
	var freezingAsset = self.attachAsset('freezingEnemy', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.width = freezingAsset.width;
	self.height = freezingAsset.height;
	// Initial speed toward left, but will accelerate
	self.vx = -10 - Math.random() * 4;
	self.vy = 0;
	self.acceleration = 0.7 + Math.random() * 0.3; // How quickly it turns toward player
	self.maxSpeed = 22 + Math.random() * 4; // Max speed increases for more threat
	self.lastX = 0;
	self.lastY = 0;
	self.lastWasIntersecting = false;
	self.isBossProjectile = false;
	self.update = function () {
		self.lastX = self.x;
		self.lastY = self.y;
		// Home in on player if player exists
		if (typeof player !== "undefined" && player) {
			var dx = player.x - self.x;
			var dy = player.y - player.height / 2 - self.y;
			var len = Math.sqrt(dx * dx + dy * dy);
			if (len > 0) {
				// Normalize direction
				var targetVx = dx / len * self.maxSpeed;
				var targetVy = dy / len * self.maxSpeed;
				// Accelerate vx/vy toward targetVx/targetVy
				self.vx += (targetVx - self.vx) * self.acceleration * 0.08;
				self.vy += (targetVy - self.vy) * self.acceleration * 0.08;
				// Clamp speed to maxSpeed
				var speed = Math.sqrt(self.vx * self.vx + self.vy * self.vy);
				if (speed > self.maxSpeed) {
					self.vx = self.vx / speed * self.maxSpeed;
					self.vy = self.vy / speed * self.maxSpeed;
				}
			}
		}
		self.x += self.vx;
		self.y += self.vy;
		// Clamp Y to play area
		if (self.y < 200) {
			self.y = 200;
		}
		if (self.y > 2300) {
			self.y = 2300;
		}
	};
	return self;
});
// Platform class
var Platform = Container.expand(function () {
	var self = Container.call(this);
	var platAsset = self.attachAsset('platformBox', {
		anchorX: 0,
		anchorY: 0
	});
	self.width = platAsset.width;
	self.height = platAsset.height;
	return self;
});
// Player character class
var Player = Container.expand(function () {
	var self = Container.call(this);
	// Attach player asset (always use playerBox)
	self.skinId = 'playerBox';
	var playerAsset = self.attachAsset(self.skinId, {
		anchorX: 0.5,
		anchorY: 1
	});
	// Method to change skin
	self.setSkin = function (skinId) {
		if (self.displayObject && self.displayObject.parent) {
			self.displayObject.parent.removeChild(self.displayObject);
		}
		var newAsset = self.attachAsset(skinId, {
			anchorX: 0.5,
			anchorY: 1
		});
		self.width = newAsset.width;
		self.height = newAsset.height;
		self.displayObject = newAsset;
		self.skinId = skinId;
	};
	// Physics properties
	self.vx = 0;
	self.vy = 0;
	self.isOnGround = false;
	self.width = playerAsset.width;
	self.height = playerAsset.height;
	// For jump control
	self.jumpRequested = false;
	// Animation properties
	self.isRunning = false;
	self.runningTween = null;
	self.jumpingTween = null;
	self.originalScaleX = 1;
	self.originalScaleY = 1;
	// Animation methods
	self.startRunningAnimation = function () {
		if (!self.isRunning && !self.runningTween) {
			self.isRunning = true;
			// Create bobbing animation while running
			self.runningTween = tween(playerAsset, {
				scaleY: 0.9,
				scaleX: 1.1
			}, {
				duration: 150,
				easing: tween.easeInOut,
				onFinish: function onFinish() {
					if (self.isRunning) {
						// Bounce back
						tween(playerAsset, {
							scaleY: 1.1,
							scaleX: 0.9
						}, {
							duration: 150,
							easing: tween.easeInOut,
							onFinish: function onFinish() {
								if (self.isRunning) {
									self.runningTween = null;
									self.startRunningAnimation(); // Loop animation
								}
							}
						});
					}
				}
			});
		}
	};
	self.stopRunningAnimation = function () {
		if (self.isRunning) {
			self.isRunning = false;
			if (self.runningTween) {
				tween.stop(playerAsset, {
					scaleX: true,
					scaleY: true
				});
				self.runningTween = null;
			}
			// Return to original scale smoothly
			tween(playerAsset, {
				scaleX: self.originalScaleX,
				scaleY: self.originalScaleY
			}, {
				duration: 100,
				easing: tween.easeOut
			});
		}
	};
	self.startJumpAnimation = function () {
		if (!self.jumpingTween) {
			// Squash before jump
			self.jumpingTween = tween(playerAsset, {
				scaleY: 0.7,
				scaleX: 1.3
			}, {
				duration: 80,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					// Stretch during jump
					tween(playerAsset, {
						scaleY: 1.2,
						scaleX: 0.8
					}, {
						duration: 120,
						easing: tween.easeInOut,
						onFinish: function onFinish() {
							// Return to normal on landing
							tween(playerAsset, {
								scaleX: self.originalScaleX,
								scaleY: self.originalScaleY
							}, {
								duration: 100,
								easing: tween.easeOut,
								onFinish: function onFinish() {
									self.jumpingTween = null;
								}
							});
						}
					});
				}
			});
		}
	};
	// Touch down on player (for jump)
	self.down = function (x, y, obj) {
		// Only allow jump if on ground and not frozen
		if (self.isOnGround && !self.isFrozen) {
			self.jumpRequested = true;
		}
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x87ceeb // Sky blue
});
/**** 
* Game Code
****/ 
// Ava: Freezing enemy asset
// --- Shop System Removed ---
var shopCoins = 0; // Ava: Track shop coins collected by player
// Ava: Track if freezing enemy has spawned this level
var freezingEnemySpawned = false;
// new kebabBox asset (fullscreen, kebab color)
// Boss attack: fire projectile at player
// Unique boss asset
// New bullet figure asset (example: blue ellipse, unique id)
// Sun and cloud assets (example IDs, replace with real asset IDs as needed)
// --- Asset Initialization (shapes) ---
// Karakterin terliği için örnek asset (id: '6832a1b2terlikicon')
// Boss health bar assets
// --- Game Variables ---
// --- Shop System Removed ---
function _typeof(o) {
	"@babel/helpers - typeof";
	return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
		return typeof o;
	} : function (o) {
		return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
	}, _typeof(o);
}
function bossFireProjectile(boss, fast) {
	// Fire 1 or 2 projectiles toward player
	var num = fast ? 2 : 1;
	for (var i = 0; i < num; i++) {
		var proj = new BossBullet();
		proj.x = boss.x;
		proj.y = boss.y + boss.height / 2 - 80 + i * 60;
		// Aim at player
		var dx = player.x - boss.x;
		var dy = player.y - player.height / 2 - proj.y;
		var len = Math.sqrt(dx * dx + dy * dy);
		var speed = fast ? 28 : 18;
		if (len > 0) {
			proj.vx = dx / len * speed;
			proj.vy = dy / len * speed;
		} else {
			proj.vx = speed;
			proj.vy = 0;
		}
		// Mark as boss projectile (for collision logic)
		proj.isBossProjectile = true;
		enemies.push(proj);
		game.addChild(proj);
	}
}
// Boss shockwave: damage player if close to boss when landing
function bossShockwave(boss) {
	// If player is within 220px horizontally and below boss, take damage
	var px = player.x;
	var py = player.y;
	var bx = boss.x;
	var by = boss.y + boss.height / 2;
	if (Math.abs(px - bx) < 220 && py > by) {
		LK.effects.flashScreen(0xff0000, 800);
		playerLives--;
		updateHearts();
		if (playerLives <= 0) {
			gameOver = true;
			LK.showGameOver();
			return;
		}
	}
	// Optional: visual effect for shockwave (flash boss yellow)
	if (boss.displayObject) {
		boss.displayObject.tint = 0xffff00;
		LK.setTimeout(function () {
			if (boss.displayObject) {
				boss.displayObject.tint = 0xffffff;
			}
		}, 200);
	}
}
var GRAVITY = 2.2;
var JUMP_VELOCITY = -54;
var PLAYER_SPEED = 16;
var SCROLL_SPEED = 10;
var LEVEL_LENGTH = 950 * 9 + 600 + 500; // 10 platforms, spacing 950, start at 600, plus last platform width
var player;
var platforms = [];
var coins = [];
var bullets = []; // Bullets array for shooting
var enemies = []; // Array for flying enemies
var coffeeHouse = null;
var boss = null; // Boss instance for 2nd area
var cameraX = 0;
var score = 0;
var distance = 0;
var gameOver = false;
var hazards = [];
var checkpoints = [];
var currentLevel = 1;
var autoMoveRightActive = false;
var lastCheckpointIndex = 0;
// --- Ava: Cephane refill timer ---
var playerAmmo = 0;
var maxPlayerAmmo = 10;
var ammoRefillTimer = LK.setInterval(function () {
	if (typeof playerAmmo === "undefined") {
		playerAmmo = 0;
	}
	if (typeof maxPlayerAmmo === "undefined") {
		maxPlayerAmmo = 10;
	}
	if (playerAmmo < maxPlayerAmmo) {
		playerAmmo++;
	}
}, 250);
// --- GUI ---
// Hearts (5 total, left-aligned, with spacing)
var heartAssets = [];
var heartSpacing = 120;
var playerLives = 3; // Total lives/can
// --- Melody Button (Sound/Music Toggle) ---
// Use a simple ellipse as the button background, and a Text2 for the icon
// Melody button (Sound/Music Toggle) - use btnFireBg for a unique look, no centerCircle above it
var melodyBtn = LK.getAsset('btnFireBg', {
	anchorX: 0.5,
	anchorY: 0.5,
	scaleX: 0.7,
	scaleY: 0.7
});
melodyBtn.x = 100 + 60 - 700 - 90; // 790px more to the left from previous position
melodyBtn.y = 100 + 60 + 100; // 100px margin from top, 60px for radius, 100px further down
melodyBtn.width = 120;
melodyBtn.height = 120;
melodyBtn.interactive = true;
melodyBtn.alpha = 0.92;
// Melody icon (♪)
var melodyIcon = new Text2('♪', {
	size: 80,
	fill: 0x222222
});
melodyIcon.anchor.set(0.5, 0.5);
melodyIcon.x = melodyBtn.x;
melodyIcon.y = melodyBtn.y;
// Track mute state
var isMuted = false;
function updateMelodyIcon() {
	if (isMuted) {
		melodyIcon.setText('🔇');
		melodyBtn.alpha = 0.5;
	} else {
		melodyIcon.setText('♪');
		melodyBtn.alpha = 0.92;
	}
}
// Add to GUI (top left, but offset to avoid platform menu)
LK.gui.top.addChild(melodyBtn);
LK.gui.top.addChild(melodyIcon);
updateMelodyIcon();
// Melody button touch handler
melodyBtn.down = function (x, y, obj) {
	isMuted = !isMuted;
	updateMelodyIcon();
	// Mute/unmute all sounds and music
	if (isMuted) {
		if (typeof LK.setMuted === "function") {
			LK.setMuted(true);
		}
	} else {
		if (typeof LK.setMuted === "function") {
			LK.setMuted(false);
		}
	}
};
// Also allow toggling by tapping the icon itself
melodyIcon.down = function (x, y, obj) {
	melodyBtn.down(x, y, obj);
};
function updateHearts() {
	for (var i = 0; i < heartAssets.length; i++) {
		if (i < playerLives) {
			heartAssets[i].visible = true;
		} else {
			heartAssets[i].visible = false;
		}
	}
}
for (var i = 0; i < 5; i++) {
	var heart = LK.getAsset('centerCircle', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	heart.x = 180 + i * heartSpacing; // Shifted 150px left from previous position
	heart.y = 100; // Moved hearts higher up
	LK.gui.top.addChild(heart);
	heartAssets.push(heart);
}
updateHearts();
var scoreTxt = new Text2('0', {
	size: 100,
	fill: 0xFFF700
});
scoreTxt.anchor.set(0.5, 0);
scoreTxt.y = 20; // Moved score text to very top
LK.gui.top.addChild(scoreTxt);
var distTxt = new Text2('0m', {
	size: 60,
	fill: 0xFFFFFF
});
distTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(distTxt);
distTxt.y = 120; // Moved distance text higher
// --- Level Generation ---
function createLevel() {
	// Clear old
	for (var i = 0; i < platforms.length; i++) {
		platforms[i].destroy();
	}
	for (var i = 0; i < coins.length; i++) {
		coins[i].destroy();
	}
	if (typeof coffeeHouse !== "undefined" && coffeeHouse) {
		coffeeHouse.destroy();
	}
	platforms = [];
	coins = [];
	coffeeHouse = null;
	// Add sun to the sky
	var sun = LK.getAsset('sun', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	sun.x = 300;
	sun.y = 300;
	game.addChild(sun);
	// Add a few clouds at different positions
	var cloud1 = LK.getAsset('cloud', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	cloud1.x = 700;
	cloud1.y = 400;
	game.addChild(cloud1);
	var cloud2 = LK.getAsset('cloud', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	cloud2.x = 1400;
	cloud2.y = 600;
	game.addChild(cloud2);
	var cloud3 = LK.getAsset('cloud', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	cloud3.x = 2000;
	cloud3.y = 350;
	game.addChild(cloud3);
	// (bottomCloud removed)
	// Clear and initialize hazards array properly
	if (typeof hazards !== "undefined" && hazards && hazards.length) {
		for (var i = 0; i < hazards.length; i++) {
			if (hazards[i] && typeof hazards[i].destroy === "function") {
				hazards[i].destroy();
			}
		}
	}
	hazards = [];
	// --- Restore old hazard spawning logic: spawn falling hazards on random platforms except boss level ---
	if (!isBossLevel) {
		var hazardCount = Math.max(2, Math.floor(numPlatforms / 3));
		for (var h = 0; h < hazardCount; h++) {
			// Pick a random platform (not the first or last)
			var platIdx = 1 + Math.floor(Math.random() * (numPlatforms - 2));
			var plat = platforms[platIdx];
			if (!plat) {
				continue;
			}
			var hazard = LK.getAsset('hazard', {
				anchorX: 0.5,
				anchorY: 0.5
			});
			// Place hazard above the platform, random X within platform width
			hazard.x = plat.x + plat.width * (0.2 + 0.6 * Math.random());
			hazard.y = plat.y - 400 - Math.random() * 300;
			hazard.width = 120;
			hazard.height = 120;
			hazard.vy = 12 + Math.random() * 6;
			hazards.push(hazard);
			game.addChild(hazard);
		}
	}
	// Platform layout: up/down, not fixed order, player can jump between them
	// 5 levels: 1-4 classic, 5 is boss fight
	var isBossLevel = typeof currentLevel !== "undefined" && currentLevel === 5;
	// Set platform count per level
	var numPlatforms = 10;
	if (typeof currentLevel !== "undefined") {
		if (currentLevel === 1) {
			numPlatforms = 15;
		} else if (currentLevel === 2) {
			numPlatforms = 15;
		} else if (currentLevel === 3) {
			numPlatforms = 20;
		} else if (currentLevel === 4) {
			numPlatforms = 20;
		} else if (currentLevel === 5) {
			numPlatforms = 15;
		}
	}
	var platSpacingX = 950; // Further increased horizontal spacing for much more space
	var platMinY = 400; // Moved higher up to use more of top area
	var platMaxY = 2400; // Extended lower to use more bottom area
	// Calculate max jump height based on physics
	// vy = JUMP_VELOCITY, gravity = GRAVITY
	// maxJumpHeight = - (vy^2) / (2 * gravity)
	var maxJumpHeight = -(JUMP_VELOCITY * JUMP_VELOCITY) / (2 * GRAVITY);
	// Use 90% of maxJumpHeight for margin of error
	var platformGapY = Math.floor(maxJumpHeight * 0.9);
	var lastY = 1800;
	// (Removed initial spawn platform and its coin)
	for (var i = 0; i < numPlatforms; i++) {
		// If this is the last platform of the boss level, add a wide area instead of a platform
		if (isBossLevel && i === numPlatforms - 1) {
			// Create a wide area using a platform asset, but much wider
			var wideArea = new Platform();
			wideArea.x = 600 + i * platSpacingX;
			wideArea.y = lastY;
			wideArea.width = 2048; // Full screen width
			wideArea.height = 300; // Taller for effect
			// Set the display object size as well
			if (wideArea.displayObject) {
				wideArea.displayObject.width = wideArea.width;
				wideArea.displayObject.height = wideArea.height;
			}
			platforms.push(wideArea);
			game.addChild(wideArea);
			// Optionally, add a coin or heart in the middle of the wide area
			var coin = new Coin();
			coin.x = wideArea.x + wideArea.width / 2;
			coin.y = wideArea.y - 80;
			coins.push(coin);
			game.addChild(coin);
			// Add boss at the right end of the wide area
			if (typeof boss !== "undefined" && boss) {
				boss.destroy();
			}
			// Remove all hazards before boss fight
			if (typeof hazards !== "undefined" && hazards.length) {
				for (var h = 0; h < hazards.length; h++) {
					if (hazards[h] && typeof hazards[h].destroy === "function") {
						hazards[h].destroy();
					}
				}
			}
			hazards = [];
			boss = new Boss();
			// Place boss so its feet are 200px above the platform
			boss.x = wideArea.x + wideArea.width - boss.width / 2 - 60; // Near right edge
			// Boss anchorY is 0.5, so y is at center. To put feet 200px above platform: y = platform.y + platform.height - boss.height/2 - 200
			boss.y = wideArea.y + wideArea.height - boss.height / 2 - 200;
			// Set boss.groundY to correct y so boss doesn't jump to top
			boss.groundY = boss.y;
			game.addChild(boss);
			// No checkpoint on the wide area
			continue;
		}
		var plat = new Platform();
		plat.x = 600 + i * platSpacingX;
		// Alternate up/down, but keep within jumpable range
		if (i === 0) {
			plat.y = lastY;
		} else {
			// Randomly go up or down, but clamp to min/max
			var deltaY = (Math.random() > 0.5 ? -1 : 1) * (platformGapY + Math.floor(Math.random() * 40) - 20); // Small random offset
			plat.y = lastY + deltaY;
			if (plat.y < platMinY) {
				plat.y = platMinY;
			}
			if (plat.y > platMaxY) {
				plat.y = platMaxY;
			}
			lastY = plat.y;
		}
		platforms.push(plat);
		game.addChild(plat);
		// Place a coin above every platform, but rarely replace with a heart (extra life)
		if (Math.random() < 0.07) {
			// ~7% chance, very rare
			var heart = LK.getAsset('centerCircle', {
				anchorX: 0.5,
				anchorY: 0.5
			});
			heart.x = plat.x + plat.width / 2;
			heart.y = plat.y - 80;
			heart.isHeart = true;
			coins.push(heart);
			game.addChild(heart);
		} else {
			var coin = new Coin();
			coin.x = plat.x + plat.width / 2;
			coin.y = plat.y - 80;
			coins.push(coin);
			game.addChild(coin);
		}
		// Add a checkpoint marker every 10th platform (not the first platform)
		if (i > 0 && i % 10 === 0) {
			var checkpoint = LK.getAsset('centerCircle', {
				anchorX: 0.5,
				anchorY: 0.5
			});
			checkpoint.x = plat.x + plat.width / 2;
			checkpoint.y = plat.y - 120;
			checkpoint.width = 120;
			checkpoint.height = 120;
			checkpoint.isCheckpoint = true;
			checkpoint.platformIndex = i;
			game.addChild(checkpoint);
			// Initialize checkpoints array if not defined
			var checkpoints = [];
			// Store checkpoint objects in an array for respawn logic
			if (typeof checkpoints === "undefined") {
				checkpoints = [];
			}
			checkpoints.push(checkpoint);
		}
	}
	// Add coffee house on the last platform for levels 1, 2, 3, 4 (not boss level)
	if (platforms.length > 0 && (typeof currentLevel === "undefined" || currentLevel === 1 || currentLevel === 2 || currentLevel === 3 || currentLevel === 4)) {
		var lastPlat = platforms[platforms.length - 1];
		coffeeHouse = LK.getAsset('coffeeHouse', {
			anchorX: 0.5,
			anchorY: 1
		});
		coffeeHouse.x = lastPlat.x + lastPlat.width / 2;
		coffeeHouse.y = lastPlat.y;
		game.addChild(coffeeHouse);
	}
}
// --- Player Initialization ---
// Track the last safe platform index for respawn
var lastSafePlatformIndex = 0;
// Track the platform the player fell from for respawn
var lastFallenPlatformIndex = 0;
function resetPlayer(respawnToLastSafe) {
	if (player) {
		player.destroy();
	}
	player = new Player();
	// No shop skin logic
	// Place player on the start platform or the platform where they fell if requested
	if (platforms.length > 0) {
		var platIdx = 0;
		if (respawnToLastSafe && typeof lastFallenPlatformIndex === "number" && lastFallenPlatformIndex >= 0 && lastFallenPlatformIndex < platforms.length) {
			platIdx = lastFallenPlatformIndex;
		} else if (respawnToLastSafe && typeof lastSafePlatformIndex === "number" && lastSafePlatformIndex >= 0 && lastSafePlatformIndex < platforms.length) {
			platIdx = lastSafePlatformIndex;
		}
		player.x = platforms[platIdx].x + platforms[platIdx].width / 2;
		player.y = platforms[platIdx].y;
	} else {
		player.x = 200;
		player.y = 2000; // Moved default spawn position higher for better screen usage
	}
	player.vx = 0;
	player.vy = 0;
	player.isOnGround = false;
	// No upgrades to apply
	game.addChild(player);
	// --- Ava: Stop auto-move and movement if spawning on first platform ---
	if (typeof autoMoveRightActive === "undefined") {
		autoMoveRightActive = false;
	}
	if (typeof moveDir === "undefined") {
		moveDir = 0;
	}
	if (platIdx === 0) {
		autoMoveRightActive = false;
		moveDir = 0;
		// Set a flag to require left button press to resume movement
		player.waitingForLeftBtn = true;
	} else {
		player.waitingForLeftBtn = false;
	}
}
// --- Camera ---
function updateCamera() {
	// Camera always follows player, no clamping
	cameraX = player.x - 600;
	// Move all game objects (except GUI) by -cameraX
	for (var i = 0; i < platforms.length; i++) {
		platforms[i].xScreen = platforms[i].x - cameraX;
	}
	for (var i = 0; i < coins.length; i++) {
		coins[i].xScreen = coins[i].x - cameraX;
	}
	player.xScreen = player.x - cameraX;
	// Move coffeeHouse relative to camera
	if (coffeeHouse && platforms.length > 0) {
		var lastPlat = platforms[platforms.length - 1];
		coffeeHouse.xScreen = coffeeHouse.x - cameraX;
		coffeeHouse.yScreen = coffeeHouse.y;
	}
	// --- Ava: Keep bottomCloud at fixed screen position if it exists ---
	if (typeof bottomCloud !== "undefined" && bottomCloud) {
		bottomCloud.x = 2048 / 2 - 200;
		bottomCloud.y = 2732 - 120;
	}
	// (hazard removed)
}
// --- Utility: AABB collision ---
function intersectsAABB(a, b) {
	return a.x < b.x + b.width && a.x + a.width > b.x && a.y < b.y + b.height && a.y + a.height > b.y;
}
// --- Touch Controls ---
// On-screen left, right, and jump buttons (bottom left corner)
// Only these buttons control movement/jump; fire is still tap/double-tap on right side
var moveDir = 0; // -1 = left, 1 = right, 0 = none
var leftBtn, rightBtn, jumpBtn;
var leftBtnPressed = false,
	rightBtnPressed = false,
	jumpBtnPressed = false;
// Create left button
leftBtn = LK.getAsset('btnLeftBg', {
	anchorX: 0.5,
	anchorY: 0.5
});
leftBtn.x = 180;
// Move control buttons visually in front of platforms by increasing their y position (platforms are at y ~400-2400, so buttons should be in front)
leftBtn.y = 2400 + 120; // Place left button just in front of lowest platform
leftBtn.width = 260;
leftBtn.height = 260;
var leftIcon = LK.getAsset('btnLeftIcon', {
	anchorX: 0.5,
	anchorY: 0.5
});
leftIcon.x = leftBtn.x;
leftIcon.y = leftBtn.y;
leftIcon.width = 140;
leftIcon.height = 140;
// Create right button
rightBtn = LK.getAsset('btnRightBg', {
	anchorX: 0.5,
	anchorY: 0.5
});
rightBtn.x = 470 + 150 - 125;
rightBtn.y = 2400 + 120; // Place right button just in front of lowest platform
rightBtn.width = 260;
rightBtn.height = 260;
var rightIcon = LK.getAsset('btnRightIcon', {
	anchorX: 0.5,
	anchorY: 0.5
});
rightIcon.x = rightBtn.x;
rightIcon.y = rightBtn.y;
rightIcon.width = 140;
rightIcon.height = 140;
// Create jump button
jumpBtn = LK.getAsset('btnJumpBg', {
	anchorX: 0.5,
	anchorY: 0.5
});
jumpBtn.x = 220 + 200 - 90;
jumpBtn.y = 2400 - 120; // Place jump button just above the other buttons, still in front of platforms
jumpBtn.width = 260;
jumpBtn.height = 260;
var jumpIcon = LK.getAsset('btnJumpIcon', {
	anchorX: 0.5,
	anchorY: 0.5
});
jumpIcon.x = jumpBtn.x;
jumpIcon.y = jumpBtn.y;
jumpIcon.width = 140;
jumpIcon.height = 140;
// Create fire button (bottom right, red circle)
var fireBtn = LK.getAsset('btnFireBg', {
	anchorX: 0.5,
	anchorY: 0.5
});
fireBtn.x = 2048 - 180;
fireBtn.y = 2400 + 120; // Place fire button just in front of lowest platform
fireBtn.width = 260;
fireBtn.height = 260;
// Terlik ikonunu fire butonun ortasına ekle
var terlikIcon = LK.getAsset('terlikIcon', {
	anchorX: 0.5,
	anchorY: 0.5
});
terlikIcon.x = fireBtn.x;
terlikIcon.y = fireBtn.y;
terlikIcon.width = 160;
terlikIcon.height = 160;
// Add all buttons and icons to the display list at the very end so they are always in front
game.addChild(leftBtn);
game.addChild(leftIcon);
game.addChild(rightBtn);
game.addChild(rightIcon);
game.addChild(jumpBtn);
game.addChild(jumpIcon);
game.addChild(fireBtn);
game.addChild(terlikIcon);
// --- Ava: Move all control and UI buttons to the absolute front of the display list every frame to guarantee they are always in front of everything, including the player and platforms ---
game.bringButtonsToFront = function () {
	if (leftBtn && leftBtn.parent) {
		leftBtn.parent.setChildIndex(leftBtn, leftBtn.parent.children.length - 1);
	}
	if (leftIcon && leftIcon.parent) {
		leftIcon.parent.setChildIndex(leftIcon, leftIcon.parent.children.length - 1);
	}
	if (rightBtn && rightBtn.parent) {
		rightBtn.parent.setChildIndex(rightBtn, rightBtn.parent.children.length - 1);
	}
	if (rightIcon && rightIcon.parent) {
		rightIcon.parent.setChildIndex(rightIcon, rightIcon.parent.children.length - 1);
	}
	if (jumpBtn && jumpBtn.parent) {
		jumpBtn.parent.setChildIndex(jumpBtn, jumpBtn.parent.children.length - 1);
	}
	if (jumpIcon && jumpIcon.parent) {
		jumpIcon.parent.setChildIndex(jumpIcon, jumpIcon.parent.children.length - 1);
	}
	if (fireBtn && fireBtn.parent) {
		fireBtn.parent.setChildIndex(fireBtn, fireBtn.parent.children.length - 1);
	}
	if (terlikIcon && terlikIcon.parent) {
		terlikIcon.parent.setChildIndex(terlikIcon, terlikIcon.parent.children.length - 1);
	}
};
// Call this in every game.update to ensure buttons are always in front
var _origUpdate = game.update;
game.update = function () {
	game.bringButtonsToFront && game.bringButtonsToFront();
	if (_origUpdate) {
		return _origUpdate.apply(this, arguments);
	}
};
// Helper to check if a point is inside a button
function isInsideBtn(btn, x, y) {
	var bx = btn.x,
		by = btn.y,
		bw = btn.width,
		bh = btn.height;
	// LK.gui is scaled, so use screen coordinates directly
	return x >= bx - bw / 2 && x <= bx + bw / 2 && y >= by - bh / 2 && y <= by + bh / 2;
}
// Overwrite game.down for button controls
game.down = function (x, y, obj) {
	// Handle title screen play button
	if (!gameStarted && playButton && isInsidePlayButton(x, y)) {
		startGameFromTitle();
		return;
	}
	// Shop logic removed
	// Don't process game controls if game hasn't started yet
	if (!gameStarted) {
		return;
	}
	if (gameOver) {
		return;
	}
	// Check if pressed on left, right, or jump button
	if (player && player.isFrozen) {
		return; // Block all movement/jump button actions while frozen
	}
	if (isInsideBtn(leftBtn, x, y)) {
		leftBtnPressed = true;
		// --- Ava: If waitingForLeftBtn, allow movement to resume only on left button press ---
		if (player && player.waitingForLeftBtn) {
			player.waitingForLeftBtn = false;
			moveDir = -1;
		} else if (!player.waitingForLeftBtn) {
			moveDir = -1;
		}
		// Stop auto-move right if active
		if (typeof autoMoveRightActive !== "undefined" && autoMoveRightActive) {
			autoMoveRightActive = false;
		}
		// Play 'y' sound on left button press
		var ySound = LK.getSound && LK.getSound('y');
		if (ySound && typeof ySound.play === "function") {
			ySound.play();
		}
	}
	if (isInsideBtn(rightBtn, x, y)) {
		rightBtnPressed = true;
		// --- Ava: If waitingForLeftBtn, allow movement to resume on right button as well ---
		if (player && player.waitingForLeftBtn) {
			player.waitingForLeftBtn = false;
			moveDir = 1;
		} else if (!player.waitingForLeftBtn) {
			moveDir = 1;
		}
		// --- Double-tap detection for right button ---
		if (typeof rightBtnLastTapTime === "undefined") {
			rightBtnLastTapTime = 0;
			rightBtnTapCount = 0;
		}
		var now = Date.now();
		if (now - rightBtnLastTapTime < 400) {
			rightBtnTapCount++;
		} else {
			rightBtnTapCount = 1;
		}
		rightBtnLastTapTime = now;
		if (rightBtnTapCount === 2) {
			// Toggle auto-move right: if already active, turn off; if not, turn on
			if (typeof autoMoveRightActive === "undefined") {
				autoMoveRightActive = false;
			}
			if (autoMoveRightActive) {
				autoMoveRightActive = false;
				moveDir = 0;
			} else {
				autoMoveRightActive = true;
				moveDir = 1;
			}
			rightBtnTapCount = 0;
		}
		// Play 'y' sound on right button press
		var ySound = LK.getSound && LK.getSound('y');
		if (ySound && typeof ySound.play === "function") {
			ySound.play();
		}
	}
	if (isInsideBtn(jumpBtn, x, y)) {
		jumpBtnPressed = true;
		if (player.isOnGround) {
			player.jumpRequested = true;
		}
	}
	// Fire button: shoot bullet
	if (typeof fireBtn !== "undefined" && isInsideBtn(fireBtn, x, y)) {
		if (typeof playerAmmo === "undefined" || playerAmmo > 0) {
			var bullet = new Bullet();
			bullet.x = player.x;
			bullet.y = player.y - player.height / 2;
			bullet.lastX = bullet.x;
			bullet.vx = 40;
			bullet.vy = 0;
			bullet.isControlled = false;
			bullets.push(bullet);
			game.addChild(bullet);
			if (typeof playerAmmo !== "undefined") {
				playerAmmo--;
			}
		}
		return;
	}
	// If not on any button, allow fire mechanic as before (right half of screen)
	if (!isInsideBtn(leftBtn, x, y) && !isInsideBtn(rightBtn, x, y) && !isInsideBtn(jumpBtn, x, y)) {
		// Fire a bullet only if this is a double-tap (within 350ms) on the right side
		if (x > 2048 / 2) {
			if (typeof lastFireTapTime === "undefined") {
				lastFireTapTime = 0;
			}
			var now = Date.now();
			if (now - lastFireTapTime < 350) {
				// Double-tap detected: fire bullet
				if (typeof playerAmmo === "undefined" || playerAmmo > 0) {
					var bullet = new Bullet();
					bullet.x = player.x;
					bullet.y = player.y - player.height / 2;
					bullet.lastX = bullet.x;
					// Set initial direction to right, but allow control
					bullet.vx = 0;
					bullet.vy = 0;
					bullet.isControlled = true; // Mark as controlled
					bullets.push(bullet);
					game.addChild(bullet);
					// Store the controlled bullet reference for move/up
					game.controlledBullet = bullet;
					if (typeof playerAmmo !== "undefined") {
						playerAmmo--;
					}
				}
				lastFireTapTime = 0; // Reset
			} else {
				// First tap: just record time
				lastFireTapTime = now;
			}
		}
	}
};
// Overwrite game.up for button controls
game.up = function (x, y, obj) {
	// Don't process game controls if game hasn't started yet
	if (!gameStarted) {
		return;
	}
	// Release movement/jump on button up
	if (isInsideBtn(leftBtn, x, y)) {
		leftBtnPressed = false;
		if (!rightBtnPressed) {
			moveDir = 0;
		} else {
			moveDir = 1;
		}
	}
	if (isInsideBtn(rightBtn, x, y)) {
		rightBtnPressed = false;
		if (!leftBtnPressed) {
			moveDir = 0;
		} else {
			moveDir = -1;
		}
	}
	if (isInsideBtn(jumpBtn, x, y)) {
		jumpBtnPressed = false;
	}
	// Release bullet control on touch up
	if (game.controlledBullet && game.controlledBullet.isControlled) {
		game.controlledBullet.isControlled = false;
		game.controlledBullet = null;
	}
};
// Overwrite game.move for button controls and bullet direction
game.move = function (x, y, obj) {
	// Don't process game controls if game hasn't started yet
	if (!gameStarted) {
		return;
	}
	// Block movement and jump while frozen
	if (player && player.isFrozen) {
		return;
	}
	// If dragging on left/right button, update moveDir
	if (leftBtnPressed && isInsideBtn(leftBtn, x, y)) {
		moveDir = -1;
	} else if (rightBtnPressed && isInsideBtn(rightBtn, x, y)) {
		moveDir = 1;
	} else if (!leftBtnPressed && !rightBtnPressed) {
		moveDir = 0;
	}
	// If a controlled bullet exists, update its velocity based on drag direction
	if (game.controlledBullet && game.controlledBullet.isControlled) {
		var bx = game.controlledBullet.x;
		var by = game.controlledBullet.y;
		var gx = x + cameraX;
		var gy = y;
		var dx = gx - bx;
		var dy = gy - by;
		var len = Math.sqrt(dx * dx + dy * dy);
		if (len > 0) {
			// Set bullet speed (fixed magnitude, e.g. 40 px/frame)
			var speed = 40;
			game.controlledBullet.vx = dx / len * speed;
			game.controlledBullet.vy = dy / len * speed;
		}
	}
};
// --- Game Update Loop ---
game.update = function () {
	// Don't run game logic if game hasn't started yet
	if (!gameStarted) {
		return;
	}
	if (gameOver) {
		return;
	}
	// --- Player Movement ---
	// Auto-move right logic
	if (typeof autoMoveRightActive === "undefined") {
		autoMoveRightActive = false;
	}
	if (autoMoveRightActive) {
		// Play 'y' sound every time auto-move right is active and player is on ground and moving
		if (typeof player.lastAutoMoveYSound === "undefined") {
			player.lastAutoMoveYSound = 0;
		}
		// Only play every 12 frames to avoid spamming
		if (player.isOnGround && Math.abs(player.vx) > 0 && LK.ticks - player.lastAutoMoveYSound > 12) {
			var ySound = LK.getSound && LK.getSound('y');
			if (ySound && typeof ySound.play === "function") {
				ySound.play();
			}
			player.lastAutoMoveYSound = LK.ticks;
		}
		moveDir = 1;
	}
	// --- Ava: Prevent all movement if waitingForLeftBtn is true or player is frozen ---
	if (player && (player.waitingForLeftBtn || player.isFrozen)) {
		player.vx = 0;
		player.vy = player.isFrozen ? 0 : player.vy; // If frozen, also stop vertical movement
		// Prevent jump while frozen
		if (player.isFrozen) {
			player.jumpRequested = false;
		}
	} else {
		var speedMultiplier = 1 + (player.speedBoost || 0) * 0.2;
		player.vx = moveDir * PLAYER_SPEED * speedMultiplier;
	}
	// --- Character Animations ---
	// Running animation
	if (Math.abs(player.vx) > 0 && player.isOnGround) {
		// Start running animation if not already running
		if (typeof player.startRunningAnimation === "function") {
			player.startRunningAnimation();
		}
	} else {
		// Stop running animation if not moving or not on ground
		if (typeof player.stopRunningAnimation === "function") {
			player.stopRunningAnimation();
		}
	}
	// Apply gravity
	player.vy += GRAVITY;
	// Jump
	if (player.jumpRequested) {
		var jumpMultiplier = 1 + (player.jumpBoost || 0) * 0.15;
		player.vy = JUMP_VELOCITY * jumpMultiplier;
		player.jumpRequested = false;
		player.isOnGround = false;
		// Start jump animation
		if (typeof player.startJumpAnimation === "function") {
			player.startJumpAnimation();
		}
		// Play jump sound only if not muted
		if (!isMuted) {
			var zSound = LK.getSound && LK.getSound('z');
			if (zSound && typeof zSound.play === "function") {
				zSound.play();
			}
		}
	}
	// --- Play 'r' and 'y' sound on each step (horizontal movement, only once per step) ---
	if (typeof player.lastStepX === "undefined") {
		player.lastStepX = player.x;
	}
	if (typeof player.hasPlayedStepSound === "undefined") {
		player.hasPlayedStepSound = false;
	}
	if (player.isOnGround && Math.abs(player.vx) > 0 && Math.abs(player.x - player.lastStepX) >= player.width * 0.7 // step size: 0.7x width
	) {
		if (!player.hasPlayedStepSound) {
			if (!isMuted) {
				var rSound = LK.getSound && LK.getSound('r');
				if (rSound && typeof rSound.play === "function") {
					rSound.play();
				}
				var ySound = LK.getSound && LK.getSound('y');
				if (ySound && typeof ySound.play === "function") {
					ySound.play();
				}
			}
			player.hasPlayedStepSound = true;
		}
		// Update lastStepX to current position
		player.lastStepX = player.x;
	} else if (player.isOnGround && Math.abs(player.vx) === 0) {
		// Reset flag when player stops moving
		player.hasPlayedStepSound = false;
	}
	// Move horizontally, check collisions
	player.x += player.vx;
	var collidedX = false;
	for (var i = 0; i < platforms.length; i++) {
		var plat = platforms[i];
		if (intersectsAABB({
			x: player.x - player.width / 2,
			y: player.y - player.height,
			width: player.width,
			height: player.height
		}, {
			x: plat.x,
			y: plat.y,
			width: plat.width,
			height: plat.height
		})) {
			// Collided horizontally, push player out
			if (player.vx > 0) {
				player.x = plat.x - player.width / 2;
			} else if (player.vx < 0) {
				player.x = plat.x + plat.width + player.width / 2;
			}
			collidedX = true;
		}
	}
	// Move vertically, check collisions
	player.y += player.vy;
	var collidedY = false;
	player.isOnGround = false;
	for (var i = 0; i < platforms.length; i++) {
		var plat = platforms[i];
		if (intersectsAABB({
			x: player.x - player.width / 2,
			y: player.y - player.height,
			width: player.width,
			height: player.height
		}, {
			x: plat.x,
			y: plat.y,
			width: plat.width,
			height: plat.height
		})) {
			// Collided vertically
			if (player.vy > 0) {
				// Falling, land on platform
				player.y = plat.y;
				player.vy = 0;
				player.isOnGround = true;
				// Update last safe platform index to this platform
				lastSafePlatformIndex = i;
				// If this is the boss platform and boss exists, start boss firing
				if (boss && plat.width >= 1800 &&
				// Boss platform is the wide one
				typeof boss.bossStartFiring !== "undefined") {
					boss.bossStartFiring = true;
				}
			} else if (player.vy < 0) {
				// Hitting head
				player.y = plat.y + plat.height + player.height;
				player.vy = 0;
			}
			collidedY = true;
		}
	}
	// (bottomCloud platform collision removed)
	// (bottomCloud instant death logic removed)
	// --- Coin/Heart Collection ---
	for (var i = coins.length - 1; i >= 0; i--) {
		var coin = coins[i];
		if (intersectsAABB({
			x: player.x - player.width / 2,
			y: player.y - player.height,
			width: player.width,
			height: player.height
		}, {
			x: coin.x - coin.width / 2,
			y: coin.y - coin.height / 2,
			width: coin.width,
			height: coin.height
		})) {
			// If this is a heart (centerCircle), increase playerLives, up to max 5
			if (coin.isHeart) {
				if (playerLives < 5) {
					playerLives++;
					updateHearts();
				} else {
					// If already at max health, give 20 points instead
					score += 20;
					scoreTxt.setText(score);
					// Every 20 points, convert to 1 life (up to max 5)
					if (score >= 20) {
						var extraLives = Math.floor(score / 20);
						var livesToAdd = Math.min(extraLives, 5 - playerLives);
						if (livesToAdd > 0) {
							playerLives += livesToAdd;
							updateHearts();
							score -= livesToAdd * 20;
							scoreTxt.setText(score);
						}
					}
				}
			} else {
				// Otherwise, it's a coin, increase score and shop coins
				score += 1;
				shopCoins += 1;
				storage.shopCoins = shopCoins;
				scoreTxt.setText(score);
				// Every 20 points, convert to 1 life (up to max 5)
				if (score >= 20) {
					var extraLives = Math.floor(score / 20);
					var livesToAdd = Math.min(extraLives, 5 - playerLives);
					if (livesToAdd > 0) {
						playerLives += livesToAdd;
						updateHearts();
						score -= livesToAdd * 20;
						scoreTxt.setText(score);
					}
				}
			}
			coin.destroy();
			coins.splice(i, 1);
		}
	}
	// --- Checkpoint Collection ---
	// Only mark checkpoint as collected when falling, not on touch
	// (handled in fall logic below)
	// --- Bullets Update ---
	var bossFightActive = boss && boss.bossStartFiring === true;
	// Only update bullets if not in boss fight, or if they are boss/player bullets
	for (var i = bullets.length - 1; i >= 0; i--) {
		var bullet = bullets[i];
		// During boss fight, only allow boss/player bullets to move (skip all others)
		if (bossFightActive && !bullet.isBossProjectile) {
			// Pause non-boss bullets (do not update position)
			// Optionally, you could hide or destroy them here if desired
			continue;
		}
		bullet.update();
		// Remove bullet if off screen (right side)
		if (bullet.lastX <= LEVEL_LENGTH && bullet.x > LEVEL_LENGTH) {
			bullet.destroy();
			bullets.splice(i, 1);
			continue;
		}
		// Remove bullet if off left or out of vertical bounds, respawn at top if falls below
		if (bullet.x < 0 || bullet.y < 0) {
			bullet.destroy();
			bullets.splice(i, 1);
			continue;
		} else if (bullet.y > 2732) {
			// Respawn bullet at the top of the screen, keep its x and vx/vy
			bullet.y = 0;
			// Optionally, you can randomize x or keep as is
			// bullet.x = Math.random() * 2048;
			// Keep lastY in sync to avoid false triggers
			bullet.lastY = bullet.y;
		}
		// --- Bullet stuck detection: remove if not moving for 12 frames ---
		if (typeof bullet.stuckFrames === "undefined") {
			bullet.stuckFrames = 0;
		}
		if (Math.abs(bullet.x - bullet.lastX) < 1 && Math.abs(bullet.y - bullet.lastY) < 1) {
			bullet.stuckFrames++;
			if (bullet.stuckFrames > 12) {
				bullet.destroy();
				bullets.splice(i, 1);
				continue;
			}
		} else {
			bullet.stuckFrames = 0;
		}
		// Render bullet at camera-relative position
		bullet.displayObject = bullet.displayObject || bullet;
		bullet.displayObject.x = bullet.x - cameraX;
		bullet.displayObject.y = bullet.y;
	}
	// --- Auto-fire at boss when visible ---
	if (!bossFightActive) {
		if (boss && _typeof(boss) === "object" && typeof boss.x === "number" && typeof boss.y === "number") {
			// Check if boss is visible on screen (simple check: boss.x - cameraX in [0, 2048])
			var bossScreenX = boss.x - cameraX;
			if (bossScreenX > 0 && bossScreenX < 2048) {
				// Only fire if enough time has passed since last auto-fire
				if (typeof bossAutoFireTimer === "undefined") {
					bossAutoFireTimer = 0;
				}
				bossAutoFireTimer++;
				// Fire every 18 frames (~3 shots per second)
				if (bossAutoFireTimer > 18) {
					bossAutoFireTimer = 0;
					// Create a bullet aimed at boss
					var autoBullet = new Bullet();
					autoBullet.x = player.x;
					autoBullet.y = player.y - player.height / 2;
					autoBullet.lastX = autoBullet.x;
					// Aim at boss center
					var dx = boss.x - autoBullet.x;
					var dy = boss.y - boss.height / 2 - autoBullet.y;
					var len = Math.sqrt(dx * dx + dy * dy);
					var speed = 40;
					if (len > 0) {
						autoBullet.vx = dx / len * speed;
						autoBullet.vy = dy / len * speed;
					} else {
						autoBullet.vx = speed;
						autoBullet.vy = 0;
					}
					autoBullet.isControlled = false;
					bullets.push(autoBullet);
					game.addChild(autoBullet);
				}
			} else {
				// Reset timer if boss is not visible
				bossAutoFireTimer = 18;
			}
		}
	}
	// --- Enemy Update & Collision ---
	if (!bossFightActive) {
		// Delay enemy movement for 3 seconds after game start
		if (typeof enemyStartDelay === "undefined") {
			enemyStartDelay = 180;
		} // 3 seconds at 60fps
		if (enemyStartDelay > 0) {
			enemyStartDelay--;
		} else {
			if (typeof enemySpawnTimer === "undefined") {
				enemySpawnTimer = 0;
			}
			enemySpawnTimer++;
			// Spawn a new enemy every 120-200 frames (randomized)
			if (enemySpawnTimer > 120 + Math.floor(Math.random() * 80)) {
				// Ava: Only spawn freezing enemy if not spawned this level, and with low probability
				if (!freezingEnemySpawned && Math.random() < 0.18) {
					// ~18% chance per spawn window, so rare
					var freezingEnemy = new FreezingEnemy();
					freezingEnemy.x = cameraX + 2048 + freezingEnemy.width / 2;
					freezingEnemy.y = 400 + Math.random() * (2100 - 400);
					freezingEnemy.lastX = freezingEnemy.x;
					freezingEnemy.lastWasIntersecting = false;
					enemies.push(freezingEnemy);
					game.addChild(freezingEnemy);
					freezingEnemySpawned = true;
				} else {
					var enemy = new Enemy();
					// Spawn at right edge, random Y within play area
					enemy.x = cameraX + 2048 + enemy.width / 2;
					// Avoid top 200px and bottom 400px
					enemy.y = 400 + Math.random() * (2100 - 400);
					enemy.lastX = enemy.x;
					enemy.lastWasIntersecting = false;
					enemies.push(enemy);
					game.addChild(enemy);
				}
				enemySpawnTimer = 0;
			}
			// Update and render enemies
			for (var i = enemies.length - 1; i >= 0; i--) {
				var enemy = enemies[i];
				enemy.update();
				// Remove if off left side
				if (enemy.lastX >= -enemy.width && enemy.x < -enemy.width) {
					enemy.destroy();
					enemies.splice(i, 1);
					continue;
				}
				// Render at camera-relative position
				enemy.displayObject = enemy.displayObject || enemy;
				enemy.displayObject.x = enemy.x - cameraX;
				enemy.displayObject.y = enemy.y;
				// --- Bullet-Enemy Collision ---
				var enemyDestroyed = false;
				for (var j = bullets.length - 1; j >= 0; j--) {
					var bullet = bullets[j];
					// Boss projectiles do not collide with other enemies
					if (enemy.isBossProjectile) {
						continue;
					}
					// Use AABB for bullet-enemy collision
					if (intersectsAABB({
						x: bullet.x - bullet.width / 2,
						y: bullet.y - bullet.height / 2,
						width: bullet.width,
						height: bullet.height
					}, {
						x: enemy.x - enemy.width / 2,
						y: enemy.y - enemy.height / 2,
						width: enemy.width,
						height: enemy.height
					})) {
						// Destroy both bullet and enemy
						bullet.destroy();
						bullets.splice(j, 1);
						enemy.destroy();
						enemies.splice(i, 1);
						// Optionally, add score or effect here
						score += 5;
						scoreTxt.setText(score);
						// Every 20 points, convert to 1 life (up to max 5)
						if (score >= 20) {
							var extraLives = Math.floor(score / 20);
							var livesToAdd = Math.min(extraLives, 5 - playerLives);
							if (livesToAdd > 0) {
								playerLives += livesToAdd;
								updateHearts();
								score -= livesToAdd * 20;
								scoreTxt.setText(score);
							}
						}
						enemyDestroyed = true;
						break;
					}
				}
				if (enemyDestroyed) {
					continue;
				}
				// Check collision with player (only on the frame it starts)
				var isIntersecting = intersectsAABB({
					x: player.x - player.width / 2,
					y: player.y - player.height,
					width: player.width,
					height: player.height
				}, {
					x: enemy.x - enemy.width / 2,
					y: enemy.y - enemy.height / 2,
					width: enemy.width,
					height: enemy.height
				});
				if (!enemy.lastWasIntersecting && isIntersecting) {
					// If this is a boss projectile, damage player and destroy projectile
					if (enemy.isBossProjectile) {
						LK.effects.flashScreen(0xff0000, 1000);
						playerLives--;
						updateHearts();
						if (playerLives <= 0) {
							gameOver = true;
							LK.showGameOver();
							return;
						}
						enemy.destroy();
						enemies.splice(i, 1);
						continue;
					}
					// --- FreezingEnemy collision logic ---
					if (enemy instanceof FreezingEnemy) {
						// Destroy freezing enemy
						enemy.destroy();
						enemies.splice(i, 1);
						// Freeze player for 2 seconds (120 frames)
						if (!player.isFrozen) {
							player.isFrozen = true;
							var prevVx = player.vx;
							var prevVy = player.vy;
							var prevMoveDir = moveDir;
							moveDir = 0;
							player.vx = 0;
							player.vy = 0;
							// Optional: visual effect (tint player blue)
							if (player.displayObject) {
								player.displayObject.tint = 0x66ccff;
							}
							// Set a timer to unfreeze after 2 seconds
							LK.setTimeout(function () {
								player.isFrozen = false;
								// Restore player tint
								if (player.displayObject) {
									player.displayObject.tint = 0xffffff;
								}
							}, 2000);
						}
						// Show freeze effect
						LK.effects.flashScreen(0x66ccff, 600);
						// Do not damage player or reduce lives
						enemy.lastWasIntersecting = isIntersecting;
						continue;
					}
					// Player hit by enemy!
					LK.effects.flashScreen(0xff0000, 1000);
					playerLives--;
					updateHearts();
					if (playerLives <= 0) {
						gameOver = true;
						LK.showGameOver();
						return;
					}
					// Do not respawn or move player, just continue playing
				}
				enemy.lastWasIntersecting = isIntersecting;
			}
		} // end else for enemyStartDelay
	}
	// --- Boss Fight: Boss projectiles damage player ---
	if (bossFightActive) {
		for (var i = enemies.length - 1; i >= 0; i--) {
			var enemy = enemies[i];
			enemy.update();
			// Remove if off left side or out of bounds
			if (enemy.lastX >= -enemy.width && enemy.x < -enemy.width) {
				enemy.destroy();
				enemies.splice(i, 1);
				continue;
			}
			// Render at camera-relative position
			enemy.displayObject = enemy.displayObject || enemy;
			enemy.displayObject.x = enemy.x - cameraX;
			enemy.displayObject.y = enemy.y;
			// Only check boss projectiles for player collision
			if (enemy.isBossProjectile) {
				var isIntersecting = intersectsAABB({
					x: player.x - player.width / 2,
					y: player.y - player.height,
					width: player.width,
					height: player.height
				}, {
					x: enemy.x - enemy.width / 2,
					y: enemy.y - enemy.height / 2,
					width: enemy.width,
					height: enemy.height
				});
				if (!enemy.lastWasIntersecting && isIntersecting) {
					LK.effects.flashScreen(0xff0000, 1000);
					playerLives--;
					updateHearts();
					if (playerLives <= 0) {
						gameOver = true;
						LK.showGameOver();
						return;
					}
					enemy.destroy();
					enemies.splice(i, 1);
					continue;
				}
				enemy.lastWasIntersecting = isIntersecting;
			}
		}
	}
	// --- Boss Update & Collision ---
	// Boss health bar setup (global, so only one at a time)
	if (typeof bossHealthBarBg === "undefined") {
		bossHealthBarBg = null;
	}
	if (typeof bossHealthBarFill === "undefined") {
		bossHealthBarFill = null;
	}
	if (boss && typeof boss.update === "function") {
		boss.update();
		// Render boss at camera-relative position
		boss.displayObject = boss.displayObject || boss;
		boss.displayObject.x = boss.x - cameraX;
		boss.displayObject.y = boss.y;
		// --- Boss Health Bar ---
		// Create health bar if not exists
		if (!bossHealthBarBg) {
			// Background bar (custom asset)
			bossHealthBarBg = LK.getAsset('bossHealthBarBg', {
				anchorX: 0.5,
				anchorY: 0.5
			});
			bossHealthBarBg.alpha = 0.7;
			game.addChild(bossHealthBarBg);
			// Fill bar (custom asset)
			bossHealthBarFill = LK.getAsset('bossHealthBarFill', {
				anchorX: 0,
				anchorY: 0.5
			});
			bossHealthBarFill.alpha = 0.95;
			game.addChild(bossHealthBarFill);
		}
		// Update health bar position above boss
		if (bossHealthBarBg && bossHealthBarFill) {
			// Bar width and percent
			var barW = boss.width * 0.8;
			var barH = 44;
			var fillW = boss.width * 0.78;
			var fillH = 32;
			var percent = Math.max(0, boss.hp / 15);
			// Position above boss head (50px above top)
			var barX = boss.x - cameraX;
			var barY = boss.y - boss.height / 2 - 50;
			bossHealthBarBg.x = barX;
			bossHealthBarBg.y = barY;
			bossHealthBarBg.width = barW;
			bossHealthBarBg.height = barH;
			bossHealthBarBg.visible = true;
			bossHealthBarFill.x = barX - fillW / 2;
			bossHealthBarFill.y = barY;
			bossHealthBarFill.width = fillW * percent;
			bossHealthBarFill.height = fillH;
			bossHealthBarFill.visible = true;
		}
		// Bullet-boss collision
		for (var j = bullets.length - 1; j >= 0; j--) {
			var bullet = bullets[j];
			if (intersectsAABB({
				x: bullet.x - bullet.width / 2,
				y: bullet.y - bullet.height / 2,
				width: bullet.width,
				height: bullet.height
			}, {
				x: boss.x - boss.width / 2,
				y: boss.y - boss.height / 2,
				width: boss.width,
				height: boss.height
			})) {
				// Boss can only be damaged if not shielded, or if weak spot is open
				if (!boss.shieldActive && (boss.phase === 1 || boss.weakSpotOpen || boss.phase === 1)) {
					boss.hp--;
					bullet.destroy();
					bullets.splice(j, 1);
					// Flash boss on hit
					LK.effects.flashObject(boss, 0xff0000, 200);
					// If boss defeated
					if (boss.hp <= 0) {
						LK.effects.flashScreen(0x00ff00, 1000);
						boss.destroy();
						boss = null;
						score += 50;
						scoreTxt.setText(score);
						// Remove boss health bar
						if (bossHealthBarBg) {
							bossHealthBarBg.visible = false;
							bossHealthBarBg.destroy();
							bossHealthBarBg = null;
						}
						if (bossHealthBarFill) {
							bossHealthBarFill.visible = false;
							bossHealthBarFill.destroy();
							bossHealthBarFill = null;
						}
						// End the game with a win when boss is defeated
						LK.setScore(score);
						LK.showYouWin();
						return;
					}
					break;
				} else {
					// Boss is shielded or not vulnerable, bullet bounces off (destroy bullet)
					bullet.destroy();
					bullets.splice(j, 1);
					// Optional: flash boss blue for shield
					if (boss.shieldActive && boss.displayObject) {
						LK.effects.flashObject(boss, 0x44aaff, 120);
					}
					break;
				}
			}
		}
		// Boss-player collision (only on the frame it starts)
		if (boss) {
			// Defensive: boss may have been destroyed above
			var bossIntersect = intersectsAABB({
				x: player.x - player.width / 2,
				y: player.y - player.height,
				width: player.width,
				height: player.height
			}, {
				x: boss.x - boss.width / 2,
				y: boss.y - boss.height / 2,
				width: boss.width,
				height: boss.height
			});
			if (!boss.lastWasIntersecting && bossIntersect) {
				LK.effects.flashScreen(0xff0000, 1000);
				playerLives--;
				updateHearts();
				if (playerLives <= 0) {
					gameOver = true;
					LK.showGameOver();
					// Remove boss health bar
					if (bossHealthBarBg) {
						bossHealthBarBg.visible = false;
						bossHealthBarBg.destroy();
						bossHealthBarBg = null;
					}
					if (bossHealthBarFill) {
						bossHealthBarFill.visible = false;
						bossHealthBarFill.destroy();
						bossHealthBarFill = null;
					}
					return;
				}
			}
			boss.lastWasIntersecting = bossIntersect;
		}
	} else {
		// No boss: remove health bar if exists
		if (bossHealthBarBg) {
			bossHealthBarBg.visible = false;
			bossHealthBarBg.destroy();
			bossHealthBarBg = null;
		}
		if (bossHealthBarFill) {
			bossHealthBarFill.visible = false;
			bossHealthBarFill.destroy();
			bossHealthBarFill = null;
		}
	}
	// --- Hazard Update & Collision ---
	// Remove hazards during boss fight (currentLevel === 2 and boss exists)
	if (typeof hazards !== "undefined" && hazards.length && (typeof currentLevel === "undefined" || currentLevel === 1 || typeof currentLevel !== "undefined" && currentLevel === 2 && !boss)) {
		for (var i = hazards.length - 1; i >= 0; i--) {
			var hazard = hazards[i];
			// Ensure hazard has valid properties
			if (!hazard || typeof hazard.x !== "number" || typeof hazard.y !== "number") {
				hazards.splice(i, 1);
				continue;
			}
			// Initialize velocity if not set
			if (typeof hazard.vy !== "number") {
				hazard.vy = 12 + Math.random() * 6;
			}
			// Move hazard down
			hazard.y += hazard.vy;
			// Render at camera-relative position
			hazard.displayObject = hazard.displayObject || hazard;
			if (hazard.displayObject) {
				hazard.displayObject.x = hazard.x - cameraX;
				hazard.displayObject.y = hazard.y;
			}
			// Remove if off screen
			if (hazard.y > 2732 + 200) {
				hazard.destroy();
				hazards.splice(i, 1);
				continue;
			}
			// Check collision with player (AABB)
			if (player.x - player.width / 2 < hazard.x + hazard.width / 2 && player.x + player.width / 2 > hazard.x - hazard.width / 2 && player.y - player.height < hazard.y + hazard.height / 2 && player.y > hazard.y - hazard.height / 2) {
				LK.effects.flashScreen(0xff0000, 800);
				playerLives--;
				updateHearts();
				hazard.destroy();
				hazards.splice(i, 1);
				if (playerLives <= 0) {
					gameOver = true;
					LK.showGameOver();
					return;
				}
			}
		}
	} else if (typeof hazards !== "undefined" && hazards.length && typeof currentLevel !== "undefined" && currentLevel === 2 && boss) {
		// If boss fight is active, despawn all hazards immediately
		for (var i = hazards.length - 1; i >= 0; i--) {
			if (hazards[i] && typeof hazards[i].destroy === "function") {
				hazards[i].destroy();
			}
		}
		hazards = [];
	}
	// --- Camera & Distance ---
	updateCamera();
	// Move all objects to screen position (for rendering only, do not overwrite world position)
	for (var i = 0; i < platforms.length; i++) {
		platforms[i].displayObject = platforms[i].displayObject || platforms[i];
		platforms[i].displayObject.x = platforms[i].xScreen;
		platforms[i].displayObject.y = platforms[i].y;
	}
	for (var i = 0; i < coins.length; i++) {
		coins[i].displayObject = coins[i].displayObject || coins[i];
		coins[i].displayObject.x = coins[i].xScreen;
		coins[i].displayObject.y = coins[i].y;
	}
	player.displayObject = player.displayObject || player;
	player.displayObject.x = player.xScreen;
	player.displayObject.y = player.y;
	// Move coffeeHouse to screen position if exists
	if (coffeeHouse && typeof coffeeHouse.xScreen !== "undefined") {
		coffeeHouse.x = coffeeHouse.xScreen;
		coffeeHouse.y = coffeeHouse.yScreen;
	}
	// (bottomCloud render removed)
	// (hazard removed)
	// --- Distance ---
	distance = Math.floor((player.x + cameraX) / 10);
	distTxt.setText(distance + "m");
	// --- Win/Lose Conditions ---
	// Fall off screen
	if (player.y > 2732) {
		LK.effects.flashScreen(0xff0000, 1000);
		playerLives--;
		updateHearts();
		// Find the platform the player was last above before falling
		if (typeof lastFallenPlatformIndex === "undefined") {
			lastFallenPlatformIndex = 0;
		}
		lastFallenPlatformIndex = 0;
		var minDist = Infinity;
		for (var i = 0; i < platforms.length; i++) {
			var plat = platforms[i];
			// Check if player was horizontally above this platform when falling
			if (player.x + player.width / 2 >= plat.x && player.x - player.width / 2 <= plat.x + plat.width) {
				// Find the closest platform vertically below the player
				var dy = player.y - plat.y;
				if (dy >= 0 && dy < minDist) {
					minDist = dy;
					lastFallenPlatformIndex = i;
				}
			}
		}
		// Find the nearest checkpoint at or before the fallen platform
		var checkpointToRespawn = 0;
		if (typeof checkpoints !== "undefined" && checkpoints.length) {
			var closestCheckpointIndex = -1;
			for (var i = 0; i < checkpoints.length; i++) {
				var checkpoint = checkpoints[i];
				if (checkpoint.platformIndex <= lastFallenPlatformIndex) {
					if (closestCheckpointIndex === -1 || checkpoint.platformIndex > checkpoints[closestCheckpointIndex].platformIndex) {
						closestCheckpointIndex = i;
					}
				}
			}
			if (closestCheckpointIndex !== -1) {
				checkpointToRespawn = checkpoints[closestCheckpointIndex].platformIndex;
				// Mark checkpoint as collected
				if (!checkpoints[closestCheckpointIndex].collected) {
					checkpoints[closestCheckpointIndex].collected = true;
					lastCheckpointIndex = checkpointToRespawn;
					checkpoints[closestCheckpointIndex].alpha = 0.5;
				}
			}
		}
		if (playerLives <= 0) {
			gameOver = true;
			LK.showGameOver();
			return;
		} else {
			// Respawn player at the nearest checkpoint (every 10th platform), or at the platform they fell from if no checkpoint reached
			if (typeof checkpointToRespawn !== "undefined" && checkpointToRespawn > 0 && checkpointToRespawn < platforms.length) {
				lastFallenPlatformIndex = checkpointToRespawn;
			}
			resetPlayer(true);
			// Optionally, move camera to player
			updateCamera();
			return;
		}
	}
	// Reached coffee house (win condition)
	if (coffeeHouse && intersectsAABB({
		x: player.x - player.width / 2,
		y: player.y - player.height,
		width: player.width,
		height: player.height
	}, {
		x: coffeeHouse.x - coffeeHouse.width / 2,
		y: coffeeHouse.y - coffeeHouse.height,
		width: coffeeHouse.width,
		height: coffeeHouse.height
	})) {
		LK.effects.flashScreen(0x00ff00, 1000);
		LK.setScore(score);
		// If on level 1, 2, 3, or 4, transition to next level
		if (typeof currentLevel === "undefined" || currentLevel === 1 || currentLevel === 2 || currentLevel === 3 || currentLevel === 4) {
			if (typeof showKiraathaneSection === "function") {
				showKiraathaneSection();
			} else {
				// Fallback: just pause the game and show a message overlay
				var overlay = new Text2("Kıraathaneye ulaştın!\nYeni bölüm geliyor...", {
					size: 120,
					fill: 0x222222,
					align: "center"
				});
				overlay.anchor.set(0.5, 0.5);
				overlay.x = 2048 / 2;
				overlay.y = 2732 / 2;
				LK.gui.center.addChild(overlay);
				gameOver = true;
			}
			return;
		}
	}
	// Win condition: player reaches the last platform
	// (Removed win condition when stepping on the last platform so the game does not end)
	// if (platforms.length > 0) {
	// var lastPlat = platforms[platforms.length - 1];
	// if (player.x + player.width / 2 >= lastPlat.x && player.x - player.width / 2 <= lastPlat.x + lastPlat.width && player.y >= lastPlat.y && player.y - player.height <= lastPlat.y + lastPlat.height) {
	// LK.effects.flashScreen(0x00ff00, 1000);
	// LK.setScore(score);
	// LK.showYouWin();
	// gameOver = true;
	// return;
	// }
	// }
};
// --- Game Start ---
// --- Title Screen with Play Button ---
var gameStarted = false;
var titleScreen = null;
var playButton = null;
var gameTitle = null;
function createTitleScreen() {
	// Create animated background elements first
	var bgElements = [];
	// Add moving clouds
	for (var i = 0; i < 5; i++) {
		var cloud = LK.getAsset('cloud', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		cloud.x = i * 500 - 200;
		cloud.y = 300 + Math.random() * 400;
		cloud.speed = 2 + Math.random() * 3;
		cloud.alpha = 0.3;
		bgElements.push(cloud);
		game.addChild(cloud);
	}
	// Add moving platforms across entire screen area
	for (var i = 0; i < 6; i++) {
		var platform = LK.getAsset('platformBox', {
			anchorX: 0,
			anchorY: 0
		});
		platform.x = i * 700 - 1000; // Fewer platforms, wider spacing
		// Store original Y for animation reference
		platform.baseY = Math.random() * 2732; // Distribute across entire screen height (0 to 2732)
		platform.y = platform.baseY;
		platform.speed = 1.5 + Math.random() * 3; // Varied speed range
		platform.alpha = 0.3 + Math.random() * 0.3; // Varied transparency
		bgElements.push(platform);
		game.addChild(platform);
		// Gentle up-down animation using tween, looped
		(function animatePlatformY(p) {
			var amplitude = 40 + Math.random() * 30; // 40-70px
			var duration = 1200 + Math.random() * 600; // 1.2-1.8s
			tween(p, {
				y: p.baseY + amplitude
			}, {
				duration: duration,
				easing: tween.sineInOut,
				onFinish: function onFinish() {
					tween(p, {
						y: p.baseY - amplitude
					}, {
						duration: duration,
						easing: tween.sineInOut,
						onFinish: function onFinish() {
							animatePlatformY(p);
						}
					});
				}
			});
		})(platform);
	}
	// Add animated tea (çay) assets with gentle up-down animation
	for (var i = 0; i < 3; i++) {
		var cay = LK.getAsset('centerCircle', {
			anchorX: 0.5,
			anchorY: 0.5,
			scaleX: 0.7,
			scaleY: 0.7
		});
		// Place çay at visually pleasing locations on the title screen
		cay.x = 600 + i * 400;
		cay.baseY = 1200 + Math.random() * 400;
		cay.y = cay.baseY;
		cay.alpha = 0.85;
		bgElements.push(cay);
		game.addChild(cay);
		// Gentle up-down animation using tween, looped
		(function animateCayY(c) {
			var amplitude = 30 + Math.random() * 20; // 30-50px
			var duration = 1100 + Math.random() * 500; // 1.1-1.6s
			tween(c, {
				y: c.baseY + amplitude
			}, {
				duration: duration,
				easing: tween.sineInOut,
				onFinish: function onFinish() {
					tween(c, {
						y: c.baseY - amplitude
					}, {
						duration: duration,
						easing: tween.sineInOut,
						onFinish: function onFinish() {
							animateCayY(c);
						}
					});
				}
			});
		})(cay);
	}
	// Add market building moving across title screen
	var market = LK.getAsset('coffeeHouse', {
		anchorX: 0.5,
		anchorY: 1
	});
	market.x = -600; // Start off screen left
	market.y = 1800 + Math.random() * 400; // Position in lower area
	market.speed = 2.5 + Math.random() * 2; // Medium speed
	market.alpha = 0.5;
	market.scaleX = 0.8;
	market.scaleY = 0.8;
	bgElements.push(market);
	game.addChild(market);
	// Add occasional boss passing through (every ~8-12 seconds)
	var boss = LK.getAsset('bossUnique', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	boss.x = -800; // Start off screen left
	boss.y = 1000 + Math.random() * 600;
	boss.speed = 6 + Math.random() * 3; // Faster than other elements
	boss.alpha = 0.6;
	boss.nextSpawnTime = 480 + Math.random() * 240; // 8-12 seconds at 60fps
	boss.isVisible = false;
	bgElements.push(boss);
	game.addChild(boss);
	// Add moving sun
	var sun = LK.getAsset('sun', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	sun.x = 300;
	sun.y = 200;
	sun.alpha = 0.5;
	bgElements.push(sun);
	game.addChild(sun);
	// Store background elements for animation
	game.titleBgElements = bgElements;
	// Create title background - use existing color background instead of asset
	game.setBackgroundColor(0x87ceeb); // Keep sky blue background visible
	// Create game title as image asset
	gameTitle = LK.getAsset('kebabRunnerTitle', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 1.5,
		scaleY: 1.5
	});
	gameTitle.x = 2048 / 2;
	gameTitle.y = 400;
	game.addChild(gameTitle);
	// Create play button background
	playButton = LK.getAsset('playButton', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 0.3,
		scaleY: 0.3
	});
	playButton.x = 2048 / 2 - 400 - 150 + 300 + 200 + 100 - 30;
	playButton.y = 1600;
	playButton.interactive = true;
	game.addChild(playButton);
	// Shop button removed
	// (Removed shop text below icon as requested)
	// Add pulsing animation to play button
	if (playButton) {
		tween(playButton, {
			scaleX: 0.35,
			scaleY: 0.35
		}, {
			duration: 1000,
			easing: tween.easeInOut,
			onFinish: function onFinish() {
				if (playButton) {
					tween(playButton, {
						scaleX: 0.3,
						scaleY: 0.3
					}, {
						duration: 1000,
						easing: tween.easeInOut,
						onFinish: function onFinish() {
							// Recursive call to create infinite loop
							if (playButton && !gameStarted) {
								tween(playButton, {
									scaleX: 0.35,
									scaleY: 0.35
								}, {
									duration: 1000,
									easing: tween.easeInOut,
									onFinish: arguments.callee.caller
								});
							}
						}
					});
				}
			}
		});
	}
	// Hide game UI during title screen
	if (scoreTxt) {
		scoreTxt.visible = false;
	}
	if (distTxt) {
		distTxt.visible = false;
	}
	if (heartAssets && heartAssets.length) {
		for (var i = 0; i < heartAssets.length; i++) {
			if (heartAssets[i]) {
				heartAssets[i].visible = false;
			}
		}
	}
	// Hide control buttons during title screen
	if (leftBtn) {
		leftBtn.visible = false;
	}
	if (rightBtn) {
		rightBtn.visible = false;
	}
	if (jumpBtn) {
		jumpBtn.visible = false;
	}
	if (fireBtn) {
		fireBtn.visible = false;
	}
	if (leftIcon) {
		leftIcon.visible = false;
	}
	if (rightIcon) {
		rightIcon.visible = false;
	}
	if (jumpIcon) {
		jumpIcon.visible = false;
	}
	if (terlikIcon) {
		terlikIcon.visible = false;
	}
}
function removeTitleScreen() {
	// Clean up animated background elements
	if (game.titleBgElements) {
		for (var i = 0; i < game.titleBgElements.length; i++) {
			if (game.titleBgElements[i]) {
				game.titleBgElements[i].destroy();
			}
		}
		game.titleBgElements = null;
	}
	if (titleScreen) {
		titleScreen.destroy();
		titleScreen = null;
	}
	if (playButton) {
		playButton.destroy();
		playButton = null;
	}
	if (gameTitle) {
		gameTitle.destroy();
		gameTitle = null;
	}
	// Shop button cleanup removed
	// Show control buttons when title screen is removed
	if (leftBtn) {
		leftBtn.visible = true;
	}
	if (rightBtn) {
		rightBtn.visible = true;
	}
	if (jumpBtn) {
		jumpBtn.visible = true;
	}
	if (fireBtn) {
		fireBtn.visible = true;
	}
	if (leftIcon) {
		leftIcon.visible = true;
	}
	if (rightIcon) {
		rightIcon.visible = true;
	}
	if (jumpIcon) {
		jumpIcon.visible = true;
	}
	if (terlikIcon) {
		terlikIcon.visible = true;
	}
}
function startGameFromTitle() {
	gameStarted = true;
	removeTitleScreen();
	// Show game UI
	if (scoreTxt) {
		scoreTxt.visible = true;
	}
	if (distTxt) {
		distTxt.visible = true;
	}
	if (heartAssets && heartAssets.length) {
		for (var i = 0; i < heartAssets.length; i++) {
			if (heartAssets[i]) {
				heartAssets[i].visible = i < playerLives;
			}
		}
	}
	// Start the actual game
	startGame();
}
// Check if point is inside play button
function isInsidePlayButton(x, y) {
	if (!playButton) {
		return false;
	}
	var bx = playButton.x;
	var by = playButton.y;
	var bw = playButton.width;
	var bh = playButton.height;
	return x >= bx - bw / 2 && x <= bx + bw / 2 && y >= by - bh / 2 && y <= by + bh / 2;
}
// Check if point is inside shop button
function isInsideShopButton(x, y) {
	return false;
}
// Shop system functions removed
// Create title screen initially
createTitleScreen();
var _origUpdate = game.update;
game.update = function () {
	// Animate title screen background elements
	if (!gameStarted && game.titleBgElements) {
		for (var i = 0; i < game.titleBgElements.length; i++) {
			var element = game.titleBgElements[i];
			if (element) {
				// Special handling for boss element
				if (element.nextSpawnTime !== undefined) {
					// This is the boss element
					if (!element.isVisible) {
						// Boss is waiting to spawn
						element.nextSpawnTime--;
						if (element.nextSpawnTime <= 0) {
							// Time to spawn boss
							element.isVisible = true;
							element.x = -800;
							element.y = 1000 + Math.random() * 600;
							element.visible = true;
							// Add slight tween animation for dramatic effect
							tween(element, {
								scaleX: 1.2,
								scaleY: 1.2
							}, {
								duration: 500,
								easing: tween.easeOut,
								onFinish: function onFinish() {
									tween(element, {
										scaleX: 1,
										scaleY: 1
									}, {
										duration: 500,
										easing: tween.easeInOut
									});
								}
							});
						}
					} else {
						// Boss is moving across screen
						element.x += element.speed || 6;
						// Reset when off screen
						if (element.x > 2048 + 400) {
							element.isVisible = false;
							element.visible = false;
							element.nextSpawnTime = 480 + Math.random() * 240; // 8-12 seconds
						}
					}
				} else {
					// Regular element movement
					element.x += element.speed || 2;
					// Reset position when off screen
					if (element.x > 2048 + 200) {
						element.x = -500; // Start further off-screen for better distribution
						// Randomize Y position for clouds, platforms, and market
						if (element.speed < 5) {
							// clouds have lower speed
							element.y = 300 + Math.random() * 400;
						} else if (element.scaleX === 0.8 && element.scaleY === 0.8) {
							// market building - reset in lower area
							element.y = 1800 + Math.random() * 400;
						} else {
							// platforms - reset across entire screen height (0 to 2732)
							element.y = Math.random() * 2732;
						}
					}
					// Add gentle floating animation to sun
					if (element === game.titleBgElements[game.titleBgElements.length - 1] && element.nextSpawnTime === undefined) {
						element.y = 200 + Math.sin(LK.ticks * 0.02) * 20;
					}
				}
			}
		}
	}
	if (_origUpdate) {
		return _origUpdate.apply(this, arguments);
	}
};
function startGame() {
	score = 0;
	distance = 0;
	gameOver = false;
	playerLives = 3;
	maxPlayerAmmo = 10;
	playerAmmo = maxPlayerAmmo; // Ava: refill ammo at game start
	// Ava: Initialize shopCoins from storage if available
	if (typeof storage !== "undefined" && typeof storage.shopCoins !== "undefined") {
		shopCoins = storage.shopCoins;
	} else {
		shopCoins = 0;
	}
	scoreTxt.setText(score);
	distTxt.setText(distance + "m");
	// Reset level to 1 at game start
	currentLevel = 1;
	// Reset enemies array and destroy old enemies if any
	if (typeof enemies !== "undefined" && enemies && enemies.length) {
		for (var i = 0; i < enemies.length; i++) {
			if (enemies[i] && typeof enemies[i].destroy === "function") {
				enemies[i].destroy();
			}
		}
	}
	enemies = [];
	// Reset checkpoints and lastCheckpointIndex
	checkpoints = [];
	lastCheckpointIndex = 0;
	freezingEnemySpawned = false; // Ava: Reset freezing enemy spawn for new level
	createLevel();
	resetPlayer();
	updateHearts();
	// (hazard removed)
	// Remove hazards if any
	if (typeof hazards !== "undefined" && hazards.length) {
		for (var i = 0; i < hazards.length; i++) {
			if (hazards[i] && typeof hazards[i].destroy === "function") {
				hazards[i].destroy();
			}
		}
	}
	hazards = [];
	cameraX = 0;
	moveDir = 0;
	enemyStartDelay = 180; // 3 seconds at 60fps
}
// --- Start ---
// Game will start when play button is pressed on title screen
// Show new section/scene after reaching coffeehouse (placeholder, can be customized)
// Track current level globally (1-based)
var currentLevel = 1;
if (typeof currentLevel === "undefined") {
	currentLevel = 1;
}
function showKiraathaneSection() {
	// Increase level up to 5
	if (typeof currentLevel === "undefined") {
		currentLevel = 1;
	}
	if (currentLevel < 5) {
		currentLevel++;
	}
	// Remove all game objects except GUI
	for (var i = 0; i < platforms.length; i++) {
		platforms[i].destroy();
	}
	for (var i = 0; i < coins.length; i++) {
		coins[i].destroy();
	}
	if (player) {
		player.destroy();
	}
	if (coffeeHouse) {
		coffeeHouse.destroy();
	}
	for (var i = 0; i < enemies.length; i++) {
		enemies[i].destroy();
	}
	for (var i = 0; i < bullets.length; i++) {
		bullets[i].destroy();
	}
	if (typeof boss !== "undefined" && boss) {
		boss.destroy();
		boss = null;
	}
	// Reset arrays
	platforms = [];
	coins = [];
	enemies = [];
	bullets = [];
	coffeeHouse = null;
	// Optionally, clear checkpoints for the new section
	checkpoints = [];
	lastCheckpointIndex = 0;
	// Remove hazards if any
	if (typeof hazards !== "undefined" && hazards.length) {
		for (var i = 0; i < hazards.length; i++) {
			if (hazards[i] && typeof hazards[i].destroy === "function") {
				hazards[i].destroy();
			}
		}
	}
	hazards = [];
	// Move camera to the start
	cameraX = 0;
	// Create a new set of platforms, coins, and coffeehouse (same as first section)
	freezingEnemySpawned = false; // Ava: Reset freezing enemy spawn for new level
	createLevel();
	resetPlayer();
	playerAmmo = maxPlayerAmmo; // Ava: refill ammo on level transition
	// Reset game state for the new section
	gameOver = false;
	moveDir = 0;
	enemyStartDelay = 180; // 3 seconds at 60fps
	// Show overlay for transition, indicating level number with black background and white text
	var levelText = currentLevel + ". lvl";
	var overlayBg = LK.getAsset('centerCircle', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 900,
		height: 300,
		color: 0x000000
	});
	overlayBg.x = 2048 / 2;
	overlayBg.y = 2732 / 2;
	overlayBg.alpha = 0.85;
	LK.gui.center.addChild(overlayBg);
	var kiraathaneOverlay = new Text2(levelText, {
		size: 180,
		fill: 0xffffff,
		align: "center"
	});
	kiraathaneOverlay.anchor.set(0.5, 0.5);
	kiraathaneOverlay.x = 2048 / 2;
	kiraathaneOverlay.y = 2732 / 2;
	LK.gui.center.addChild(kiraathaneOverlay);
	// Remove overlay after 1.5 seconds
	LK.setTimeout(function () {
		kiraathaneOverlay.destroy();
		overlayBg.destroy();
	}, 1500);
}
:quality(85)/https://cdn.frvr.ai/682b8e1745555ea7fe553337.png%3F3) 
 cloud. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
:quality(85)/https://cdn.frvr.ai/682b8ede45555ea7fe553387.png%3F3) 
 sun. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
:quality(85)/https://cdn.frvr.ai/682b92c545555ea7fe5534c9.png%3F3) 
 çay bardağı. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
:quality(85)/https://cdn.frvr.ai/682e0d36ac933a1cc80f4012.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/682e0f51ac933a1cc80f4036.png%3F3) 
 a kebap. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
:quality(85)/https://cdn.frvr.ai/682e14f4ac933a1cc80f40c0.png%3F3) 
 baba terliği. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
:quality(85)/https://cdn.frvr.ai/682e1c6dac933a1cc80f416d.png%3F3) 
 starbucks kahvesi ama kızgın ve canlı. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
:quality(85)/https://cdn.frvr.ai/682e3a8aa4825517a9e6ccc4.png%3F3) 
 geleneksel türk kıraathanesi. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
:quality(85)/https://cdn.frvr.ai/682e48ef924e3fefd71263ab.png%3F3) 
 starbucks kahvesi ama kaslı ve kıravartı olan sinirli bir starbucks kahvesi. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
:quality(85)/https://cdn.frvr.ai/682f46a9c0116d543bc37477.png%3F3) 
 180 derece stabucks kahvesi . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
:quality(85)/https://cdn.frvr.ai/6830c24288c6459c16af97e9.png%3F3) 
 kırmızı ok. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
:quality(85)/https://cdn.frvr.ai/6831a4cd788cfa6295109aec.png%3F3) 
 okun ucu sola baksın ve hiçbirşey değişmesin
:quality(85)/https://cdn.frvr.ai/6831a53e788cfa6295109afb.png%3F3) 
 şimdi ok yine değişmesin sadece ucu sağa baksın
:quality(85)/https://cdn.frvr.ai/68349d093737768a6d9aea8e.png%3F3) 
 şiş in içine geçmiş bir şekilde play yazıcak ama domates biber ve etten yani gerçek kebab gibi ama harfler var. daha çizgifilmsel olacak mesela "p" et "l" biber "a" domates "y" et
:quality(85)/https://cdn.frvr.ai/6834a1243737768a6d9aeb17.png%3F3) 
 "Kebab Runner" yaz ama 1 şiş kebab yazının üstünde duracak olacak yani oyunun
:quality(85)/https://cdn.frvr.ai/6834db0fef6aa3b4f2a85361.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/6838818305b0e3b567f48949.png%3F3) 
 çaydanlık adam. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
:quality(85)/https://cdn.frvr.ai/68388cf805b0e3b567f48a47.png%3F3) 
 buzlu bir americano ama stabucks kahvesi çevresi beyaz olsun içinde çok buz olsun No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat