/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/**** 
* Classes
****/ 
var Boss = Container.expand(function () {
	var self = Container.call(this);
	var bossGraphics = self.attachAsset('boss', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.health = 200;
	self.maxHealth = 200;
	self.attackPattern = 0;
	self.jumpCount = 0; // Initialize jump count
	self.attackCooldown = 3000; // ms
	self.canAttack = true;
	self.attackTimer = null;
	self.movementSpeed = 1.5; // Reduced speed for slower movement
	self.direction = 1; // 1 = right, -1 = left
	self.phaseChangeThreshold = 50; // Health threshold for phase change
	self.isPhaseTwo = false;
	self.update = function () {
		// Boss movement
		if (!self.isPhaseTwo) {
			// Phase 1 movement: back and forth
			self.x += self.movementSpeed * self.direction;
			if (self.x > 1800 || self.x < 600) {
				self.direction *= -1;
			}
		} else {
			// Phase 2 movement: predictive follow player
			// Maintain a safe distance from the hero
			var safeDistance = 200;
			var predictionFactor = 0.1; // Factor to predict hero's future position
			var predictedHeroX = hero.x + hero.speed * predictionFactor * (pressedRight ? 1 : pressedLeft ? -1 : 0);
			if (self.x < predictedHeroX - safeDistance) {
				self.x += self.movementSpeed * 0.5;
			} else if (self.x > predictedHeroX + safeDistance) {
				self.x -= self.movementSpeed * 0.5;
			}
		}
		// Always perform long jumps and attack
		if (self.isGrounded || self.jumpCount < 4) {
			self.velocityY = -30; // Increased jump force for long jumps
			self.isGrounded = false;
			self.jumpCount++; // Increment jump count
			self.attack(); // Attack during jump
		}
		self.velocityY += 0.7; // Gravity
		self.y += self.velocityY;
		if (self.y >= groundLevel - bossGraphics.height / 2) {
			self.y = groundLevel - bossGraphics.height / 2;
			self.velocityY = 0;
			self.isGrounded = true;
			self.jumpCount = 0; // Reset jump count when grounded
		}
		// Attack if possible
		if (self.canAttack) {
			self.attack();
		}
		// Check for phase change
		if (!self.isPhaseTwo && self.health <= self.phaseChangeThreshold) {
			self.enterPhaseTwo();
		}
	};
	self.attack = function () {
		self.canAttack = false;
		// Different attack patterns
		if (self.isPhaseTwo) {
			// Phase 2 - more aggressive attacks
			switch (Math.floor(Math.random() * 3)) {
				case 0:
					self.spreadAttack();
					break;
				case 1:
					self.targetedAttack();
					break;
			}
		} else {
			// Phase 1 - basic attacks
			if (Math.random() > 0.5) {
				self.singleAttack();
			} else {
				self.targetedAttack();
			}
		}
		// Reset attack cooldown
		self.attackTimer = LK.setTimeout(function () {
			self.canAttack = true;
		}, self.attackCooldown);
	};
	self.singleAttack = function () {
		var projectile = new BossProjectile();
		projectile.x = self.x;
		projectile.y = self.y;
		game.addChild(projectile);
		bossProjectiles.push(projectile);
	};
	self.spreadAttack = function () {
		for (var i = -2; i <= 2; i++) {
			var projectile = new BossProjectile();
			projectile.x = self.x;
			projectile.y = self.y;
			projectile.velocityX = -5 + i * 2;
			projectile.velocityY = 5;
			game.addChild(projectile);
			bossProjectiles.push(projectile);
		}
	};
	self.targetedAttack = function () {
		var projectile = new BossProjectile();
		projectile.x = self.x;
		projectile.y = self.y;
		// Calculate direction toward player
		var dx = hero.x - self.x;
		var dy = hero.y - self.y;
		var angle = Math.atan2(dy, dx);
		projectile.velocityX = Math.cos(angle) * 8;
		projectile.velocityY = Math.sin(angle) * 8;
		game.addChild(projectile);
		bossProjectiles.push(projectile);
	};
	self.takeDamage = function (damage) {
		self.health -= damage;
		// Flash boss red
		LK.effects.flashObject(self, 0xff0000, 300);
		if (self.health <= 0) {
			self.health = 0;
			self.onDefeat();
		}
		updateBossHealthBar();
		LK.getSound('hit').play();
	};
	self.enterPhaseTwo = function () {
		self.isPhaseTwo = true;
		self.attackCooldown = 1000; // Faster attacks in phase 2
		self.movementSpeed = 4; // Faster movement
		// Flash the boss to indicate phase change
		LK.effects.flashObject(self, 0xffff00, 1000);
		// Clear any existing attack timer and reset
		if (self.attackTimer) {
			LK.clearTimeout(self.attackTimer);
		}
		self.canAttack = true;
	};
	self.onDefeat = function () {
		LK.getSound('bossDeath').play();
		LK.showYouWin();
	};
	return self;
});
var BossProjectile = Container.expand(function () {
	var self = Container.call(this);
	var projectileGraphics = self.attachAsset('projectile', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.velocityX = -8; // Normal speed for enemy bullets
	self.velocityY = 0;
	self.damage = 5;
	self.update = function () {
		self.x += self.velocityX;
		self.y += self.velocityY;
		// Remove if off screen
		if (self.x < -projectileGraphics.width || self.x > 2048 + projectileGraphics.width || self.y < -projectileGraphics.height || self.y > 2732 + projectileGraphics.height) {
			self.destroy();
			var index = bossProjectiles.indexOf(self);
			if (index !== -1) {
				bossProjectiles.splice(index, 1);
			}
		}
	};
	return self;
});
var Hero = Container.expand(function () {
	var self = Container.call(this);
	var heroGraphics = self.attachAsset('hero', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.health = 300;
	self.maxHealth = 300;
	self.speed = 7;
	self.jumpForce = -15;
	self.gravity = 0.7;
	self.velocityY = 0;
	self.isJumping = false;
	self.jumpCount = 0; // Initialize jump count
	self.isGrounded = false;
	self.canShoot = true;
	self.shootCooldown = 500; // ms
	self.invulnerable = false;
	self.invulnerabilityTime = 1000; // ms
	self.update = function () {
		// Apply gravity
		self.velocityY += self.gravity;
		self.y += self.velocityY;
		// Check if hero is on ground
		if (self.y >= groundLevel - heroGraphics.height / 2) {
			self.y = groundLevel - heroGraphics.height / 2;
			self.velocityY = 0;
			self.isGrounded = true;
			self.isJumping = false;
			self.jumpCount = 0; // Reset jump count when grounded
		} else {
			self.isGrounded = false;
		}
		// Keep hero within game boundaries
		if (self.x < heroGraphics.width / 2) {
			self.x = heroGraphics.width / 2;
		} else if (self.x > 2048 - heroGraphics.width / 2) {
			self.x = 2048 - heroGraphics.width / 2;
		}
	};
	self.jump = function () {
		if (self.isGrounded || self.jumpCount < 4) {
			// Allow triple jump
			self.velocityY = self.jumpForce;
			self.isJumping = true;
			self.isGrounded = false;
			self.jumpCount++; // Increment jump count
		}
	};
	self.shoot = function () {
		if (!self.canShoot) {
			return;
		}
		var projectile = new HeroProjectile();
		projectile.x = self.x + (pressedLeft ? -50 : 50); // Adjust position based on direction
		projectile.y = self.y;
		projectile.velocityX = pressedLeft ? -15 : 15; // Adjust velocity based on direction
		game.addChild(projectile);
		projectiles.push(projectile);
		LK.getSound('shoot').play();
		self.canShoot = false;
		LK.setTimeout(function () {
			self.canShoot = true;
		}, self.shootCooldown);
	};
	self.takeDamage = function (damage) {
		if (self.invulnerable) {
			return;
		}
		self.health -= damage;
		if (self.health <= 0) {
			self.health = 0;
			LK.showGameOver();
		}
		LK.getSound('playerHit').play();
		updateHealthBar();
		// Flash hero and make invulnerable temporarily
		self.invulnerable = true;
		LK.effects.flashObject(self, 0xffffff, 1000);
		LK.setTimeout(function () {
			self.invulnerable = false;
		}, self.invulnerabilityTime);
	};
	return self;
});
var HeroProjectile = Container.expand(function () {
	var self = Container.call(this);
	var projectileGraphics = self.attachAsset('heroProjectile', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.velocityX = 10; // Increased bullet speed
	self.damage = 10;
	self.update = function () {
		self.x += self.velocityX;
		// Remove if off screen
		if (self.x > 2048 + projectileGraphics.width) {
			self.destroy();
			var index = projectiles.indexOf(self);
			if (index !== -1) {
				projectiles.splice(index, 1);
			}
		}
	};
	return self;
});
var Platform = Container.expand(function () {
	var self = Container.call(this);
	var platformGraphics = self.attachAsset('platform', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.update = function () {
		// Store lastY for transition detection
		if (self.lastY === undefined) {
			self.lastY = self.y;
		}
		// Update lastY
		self.lastY = self.y;
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x34495e
});
/**** 
* Game Code
****/ 
// Game variables
var hero;
var boss;
var platforms = [];
var projectiles = [];
var bossProjectiles = [];
var groundLevel = 2400;
var heroHealthBar;
var heroHealthBarBg;
var bossHealthBar;
var bossHealthBarBg;
var moveLeftBtn;
var moveRightBtn;
var jumpBtn;
var shootBtn;
var pressedLeft = false;
var pressedRight = false;
// Set up game environment
function setupGame() {
	// Add background image
	var background = LK.getAsset('backgroundImage', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: 1024,
		y: 1366
	});
	game.addChild(background);
	// Create hero
	hero = new Hero();
	hero.x = 400;
	hero.y = groundLevel - hero.height / 2;
	game.addChild(hero);
	// Create boss
	boss = new Boss();
	boss.x = 1600;
	boss.y = groundLevel - boss.height / 2;
	game.addChild(boss);
	// Create platforms
	createPlatforms();
	// Create UI
	createUI();
	// Start background music
	LK.playMusic('battleMusic');
}
function createPlatforms() {
	// Ground platform
	var ground = new Platform();
	ground.x = 1024;
	ground.y = groundLevel + 20;
	ground.scaleX = 5.12; // Cover full width (2048 / 400)
	game.addChild(ground);
	platforms.push(ground);
	// Add some floating platforms
	var platformPositions = [{
		x: 600,
		y: 2200
	}, {
		x: 1200,
		y: 2100
	}, {
		x: 1800,
		y: 2200
	}, {
		x: 1000,
		y: 2000
	}, {
		x: 1500,
		y: 1900
	}];
	for (var i = 0; i < platformPositions.length; i++) {
		var platform = new Platform();
		platform.x = platformPositions[i].x;
		platform.y = platformPositions[i].y;
		game.addChild(platform);
		platforms.push(platform);
	}
}
function createUI() {
	// Create hero health bar background
	heroHealthBarBg = LK.getAsset('healthBarBackground', {
		anchorX: 0,
		anchorY: 0.5,
		x: 20,
		y: 50
	});
	LK.gui.topLeft.addChild(heroHealthBarBg);
	// Create hero health bar
	heroHealthBar = LK.getAsset('healthBar', {
		anchorX: 0,
		anchorY: 0.5,
		x: 20,
		y: 50
	});
	LK.gui.topLeft.addChild(heroHealthBar);
	// Create hero secondary health bar
	heroSecondaryHealthBar = LK.getAsset('healthBar', {
		anchorX: 0,
		anchorY: 0.5,
		x: 20,
		y: 90
	});
	LK.gui.topLeft.addChild(heroSecondaryHealthBar);
	// Create boss health bar background
	bossHealthBarBg = LK.getAsset('healthBarBackground', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: 1024,
		y: 50
	});
	LK.gui.top.addChild(bossHealthBarBg);
	// Create boss health bar
	bossHealthBar = LK.getAsset('healthBar', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: 0,
		y: 50
	});
	LK.gui.top.addChild(bossHealthBar);
	// Create boss secondary health bar
	bossSecondaryHealthBar = LK.getAsset('healthBar', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: 0,
		y: 90
	});
	LK.gui.top.addChild(bossSecondaryHealthBar);
	// Create control buttons
	createControlButtons();
}
function createControlButtons() {
	// Left movement button
	moveLeftBtn = LK.getAsset('platform', {
		anchorX: 0.5,
		anchorY: 0.5,
		alpha: 0.5,
		x: 150,
		y: -150
	});
	moveLeftBtn.width = 150;
	moveLeftBtn.height = 150;
	moveLeftBtn.tint = 0x3498db;
	LK.gui.bottomLeft.addChild(moveLeftBtn);
	// Right movement button
	moveRightBtn = LK.getAsset('platform', {
		anchorX: 0.5,
		anchorY: 0.5,
		alpha: 0.5,
		x: 320,
		y: -150
	});
	moveRightBtn.width = 150;
	moveRightBtn.height = 150;
	moveRightBtn.tint = 0x3498db;
	LK.gui.bottomLeft.addChild(moveRightBtn);
	// Jump button
	jumpBtn = LK.getAsset('platform', {
		anchorX: 0.5,
		anchorY: 0.5,
		alpha: 0.5,
		x: -150,
		y: -150
	});
	jumpBtn.width = 150;
	jumpBtn.height = 150;
	jumpBtn.tint = 0x2ecc71;
	LK.gui.bottomRight.addChild(jumpBtn);
	// Shoot button
	shootBtn = LK.getAsset('platform', {
		anchorX: 0.5,
		anchorY: 0.5,
		alpha: 0.5,
		x: -320,
		y: -150
	});
	shootBtn.width = 150;
	shootBtn.height = 150;
	shootBtn.tint = 0xe74c3c;
	LK.gui.bottomRight.addChild(shootBtn);
	// Add event handlers
	moveLeftBtn.interactive = true;
	moveRightBtn.interactive = true;
	jumpBtn.interactive = true;
	shootBtn.interactive = true;
	// Setup button events
	moveLeftBtn.down = function () {
		pressedLeft = true;
	};
	moveLeftBtn.up = function () {
		pressedLeft = false;
	};
	moveRightBtn.down = function () {
		pressedRight = true;
	};
	moveRightBtn.up = function () {
		pressedRight = false;
	};
	jumpBtn.down = function () {
		hero.jump();
	};
	shootBtn.down = function () {
		hero.shoot();
	};
}
function updateHealthBar() {
	var healthPercentage = hero.health / hero.maxHealth;
	heroHealthBar.scaleX = healthPercentage;
	// Update secondary health bar
	var secondaryHealthPercentage = Math.max(0, (hero.health - hero.maxHealth / 2) / (hero.maxHealth / 2));
	heroSecondaryHealthBar.scaleX = secondaryHealthPercentage;
}
function updateBossHealthBar() {
	var healthPercentage = boss.health / boss.maxHealth;
	bossHealthBar.scaleX = healthPercentage;
	// Update secondary health bar
	var secondaryHealthPercentage = Math.max(0, (boss.health - boss.maxHealth / 2) / (boss.maxHealth / 2));
	bossSecondaryHealthBar.scaleX = secondaryHealthPercentage;
}
function checkCollisions() {
	// Check hero-boss collision
	if (hero.intersects(boss) && !hero.invulnerable) {
		hero.takeDamage(20);
		// Knock hero back
		hero.velocityY = -10;
		if (hero.x < boss.x) {
			hero.x -= 100;
		} else {
			hero.x += 100;
		}
	}
	// Check platform collisions for hero
	for (var i = 0; i < platforms.length; i++) {
		var platform = platforms[i];
		// Only check if hero is falling
		if (hero.velocityY > 0) {
			var heroPrevY = hero.y - hero.velocityY;
			// Check if hero was above platform in previous frame
			if (heroPrevY + hero.height / 2 <= platform.y - platform.height / 2) {
				// Check if hero is now colliding with platform
				if (hero.intersects(platform)) {
					hero.y = platform.y - platform.height / 2 - hero.height / 2;
					hero.velocityY = 0;
					hero.isGrounded = true;
					hero.isJumping = false;
				}
			}
		}
	}
	// Check hero projectile collisions with boss
	for (var j = projectiles.length - 1; j >= 0; j--) {
		var projectile = projectiles[j];
		if (projectile.intersects(boss)) {
			boss.takeDamage(projectile.damage);
			// Remove projectile
			projectile.destroy();
			projectiles.splice(j, 1);
		}
	}
	// Check boss projectile collisions with hero
	for (var k = bossProjectiles.length - 1; k >= 0; k--) {
		var bossProjectile = bossProjectiles[k];
		if (bossProjectile.intersects(hero) && !hero.invulnerable) {
			hero.takeDamage(bossProjectile.damage);
			// Remove projectile
			bossProjectile.destroy();
			bossProjectiles.splice(k, 1);
		}
	}
}
function handleGameInput() {
	// Handle movement based on button states
	if (pressedLeft) {
		hero.x -= hero.speed;
	}
	if (pressedRight) {
		hero.x += hero.speed;
	}
}
// Set up game
setupGame();
boss.onDefeat = function () {
	LK.getSound('bossDeath').play();
	LK.showYouWin();
};
// Game update loop
game.update = function () {
	// Update hero
	hero.update();
	// Update boss
	boss.update();
	// Update platforms
	for (var i = 0; i < platforms.length; i++) {
		platforms[i].update();
	}
	// Update projectiles
	for (var i = 0; i < projectiles.length; i++) {
		projectiles[i].update();
	}
	for (var j = 0; j < bossProjectiles.length; j++) {
		bossProjectiles[j].update();
	}
	// Handle input
	handleGameInput();
	// Check collisions
	checkCollisions();
};
// Touch events for the game area
game.down = function (x, y, obj) {
	// Check if touch was on control buttons
	var touchPoint = {
		x: x,
		y: y
	};
	var moveLeftPos = moveLeftBtn.parent.toGlobal(moveLeftBtn.position);
	var moveRightPos = moveRightBtn.parent.toGlobal(moveRightBtn.position);
	var jumpPos = jumpBtn.parent.toGlobal(jumpBtn.position);
	var shootPos = shootBtn.parent.toGlobal(shootBtn.position);
	// Simple distance check for buttons
	if (distance(touchPoint, moveLeftPos) < 75) {
		pressedLeft = true;
	} else if (distance(touchPoint, moveRightPos) < 75) {
		pressedRight = true;
	} else if (distance(touchPoint, jumpPos) < 75) {
		hero.jump();
	} else if (distance(touchPoint, shootPos) < 75) {
		hero.shoot();
	}
};
game.up = function (x, y, obj) {
	// Stop movement when touch is released
	pressedLeft = false;
	pressedRight = false;
};
// Helper function to calculate distance between points
function distance(p1, p2) {
	return Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2));
} /**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/**** 
* Classes
****/ 
var Boss = Container.expand(function () {
	var self = Container.call(this);
	var bossGraphics = self.attachAsset('boss', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.health = 200;
	self.maxHealth = 200;
	self.attackPattern = 0;
	self.jumpCount = 0; // Initialize jump count
	self.attackCooldown = 3000; // ms
	self.canAttack = true;
	self.attackTimer = null;
	self.movementSpeed = 1.5; // Reduced speed for slower movement
	self.direction = 1; // 1 = right, -1 = left
	self.phaseChangeThreshold = 50; // Health threshold for phase change
	self.isPhaseTwo = false;
	self.update = function () {
		// Boss movement
		if (!self.isPhaseTwo) {
			// Phase 1 movement: back and forth
			self.x += self.movementSpeed * self.direction;
			if (self.x > 1800 || self.x < 600) {
				self.direction *= -1;
			}
		} else {
			// Phase 2 movement: predictive follow player
			// Maintain a safe distance from the hero
			var safeDistance = 200;
			var predictionFactor = 0.1; // Factor to predict hero's future position
			var predictedHeroX = hero.x + hero.speed * predictionFactor * (pressedRight ? 1 : pressedLeft ? -1 : 0);
			if (self.x < predictedHeroX - safeDistance) {
				self.x += self.movementSpeed * 0.5;
			} else if (self.x > predictedHeroX + safeDistance) {
				self.x -= self.movementSpeed * 0.5;
			}
		}
		// Always perform long jumps and attack
		if (self.isGrounded || self.jumpCount < 4) {
			self.velocityY = -30; // Increased jump force for long jumps
			self.isGrounded = false;
			self.jumpCount++; // Increment jump count
			self.attack(); // Attack during jump
		}
		self.velocityY += 0.7; // Gravity
		self.y += self.velocityY;
		if (self.y >= groundLevel - bossGraphics.height / 2) {
			self.y = groundLevel - bossGraphics.height / 2;
			self.velocityY = 0;
			self.isGrounded = true;
			self.jumpCount = 0; // Reset jump count when grounded
		}
		// Attack if possible
		if (self.canAttack) {
			self.attack();
		}
		// Check for phase change
		if (!self.isPhaseTwo && self.health <= self.phaseChangeThreshold) {
			self.enterPhaseTwo();
		}
	};
	self.attack = function () {
		self.canAttack = false;
		// Different attack patterns
		if (self.isPhaseTwo) {
			// Phase 2 - more aggressive attacks
			switch (Math.floor(Math.random() * 3)) {
				case 0:
					self.spreadAttack();
					break;
				case 1:
					self.targetedAttack();
					break;
			}
		} else {
			// Phase 1 - basic attacks
			if (Math.random() > 0.5) {
				self.singleAttack();
			} else {
				self.targetedAttack();
			}
		}
		// Reset attack cooldown
		self.attackTimer = LK.setTimeout(function () {
			self.canAttack = true;
		}, self.attackCooldown);
	};
	self.singleAttack = function () {
		var projectile = new BossProjectile();
		projectile.x = self.x;
		projectile.y = self.y;
		game.addChild(projectile);
		bossProjectiles.push(projectile);
	};
	self.spreadAttack = function () {
		for (var i = -2; i <= 2; i++) {
			var projectile = new BossProjectile();
			projectile.x = self.x;
			projectile.y = self.y;
			projectile.velocityX = -5 + i * 2;
			projectile.velocityY = 5;
			game.addChild(projectile);
			bossProjectiles.push(projectile);
		}
	};
	self.targetedAttack = function () {
		var projectile = new BossProjectile();
		projectile.x = self.x;
		projectile.y = self.y;
		// Calculate direction toward player
		var dx = hero.x - self.x;
		var dy = hero.y - self.y;
		var angle = Math.atan2(dy, dx);
		projectile.velocityX = Math.cos(angle) * 8;
		projectile.velocityY = Math.sin(angle) * 8;
		game.addChild(projectile);
		bossProjectiles.push(projectile);
	};
	self.takeDamage = function (damage) {
		self.health -= damage;
		// Flash boss red
		LK.effects.flashObject(self, 0xff0000, 300);
		if (self.health <= 0) {
			self.health = 0;
			self.onDefeat();
		}
		updateBossHealthBar();
		LK.getSound('hit').play();
	};
	self.enterPhaseTwo = function () {
		self.isPhaseTwo = true;
		self.attackCooldown = 1000; // Faster attacks in phase 2
		self.movementSpeed = 4; // Faster movement
		// Flash the boss to indicate phase change
		LK.effects.flashObject(self, 0xffff00, 1000);
		// Clear any existing attack timer and reset
		if (self.attackTimer) {
			LK.clearTimeout(self.attackTimer);
		}
		self.canAttack = true;
	};
	self.onDefeat = function () {
		LK.getSound('bossDeath').play();
		LK.showYouWin();
	};
	return self;
});
var BossProjectile = Container.expand(function () {
	var self = Container.call(this);
	var projectileGraphics = self.attachAsset('projectile', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.velocityX = -8; // Normal speed for enemy bullets
	self.velocityY = 0;
	self.damage = 5;
	self.update = function () {
		self.x += self.velocityX;
		self.y += self.velocityY;
		// Remove if off screen
		if (self.x < -projectileGraphics.width || self.x > 2048 + projectileGraphics.width || self.y < -projectileGraphics.height || self.y > 2732 + projectileGraphics.height) {
			self.destroy();
			var index = bossProjectiles.indexOf(self);
			if (index !== -1) {
				bossProjectiles.splice(index, 1);
			}
		}
	};
	return self;
});
var Hero = Container.expand(function () {
	var self = Container.call(this);
	var heroGraphics = self.attachAsset('hero', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.health = 300;
	self.maxHealth = 300;
	self.speed = 7;
	self.jumpForce = -15;
	self.gravity = 0.7;
	self.velocityY = 0;
	self.isJumping = false;
	self.jumpCount = 0; // Initialize jump count
	self.isGrounded = false;
	self.canShoot = true;
	self.shootCooldown = 500; // ms
	self.invulnerable = false;
	self.invulnerabilityTime = 1000; // ms
	self.update = function () {
		// Apply gravity
		self.velocityY += self.gravity;
		self.y += self.velocityY;
		// Check if hero is on ground
		if (self.y >= groundLevel - heroGraphics.height / 2) {
			self.y = groundLevel - heroGraphics.height / 2;
			self.velocityY = 0;
			self.isGrounded = true;
			self.isJumping = false;
			self.jumpCount = 0; // Reset jump count when grounded
		} else {
			self.isGrounded = false;
		}
		// Keep hero within game boundaries
		if (self.x < heroGraphics.width / 2) {
			self.x = heroGraphics.width / 2;
		} else if (self.x > 2048 - heroGraphics.width / 2) {
			self.x = 2048 - heroGraphics.width / 2;
		}
	};
	self.jump = function () {
		if (self.isGrounded || self.jumpCount < 4) {
			// Allow triple jump
			self.velocityY = self.jumpForce;
			self.isJumping = true;
			self.isGrounded = false;
			self.jumpCount++; // Increment jump count
		}
	};
	self.shoot = function () {
		if (!self.canShoot) {
			return;
		}
		var projectile = new HeroProjectile();
		projectile.x = self.x + (pressedLeft ? -50 : 50); // Adjust position based on direction
		projectile.y = self.y;
		projectile.velocityX = pressedLeft ? -15 : 15; // Adjust velocity based on direction
		game.addChild(projectile);
		projectiles.push(projectile);
		LK.getSound('shoot').play();
		self.canShoot = false;
		LK.setTimeout(function () {
			self.canShoot = true;
		}, self.shootCooldown);
	};
	self.takeDamage = function (damage) {
		if (self.invulnerable) {
			return;
		}
		self.health -= damage;
		if (self.health <= 0) {
			self.health = 0;
			LK.showGameOver();
		}
		LK.getSound('playerHit').play();
		updateHealthBar();
		// Flash hero and make invulnerable temporarily
		self.invulnerable = true;
		LK.effects.flashObject(self, 0xffffff, 1000);
		LK.setTimeout(function () {
			self.invulnerable = false;
		}, self.invulnerabilityTime);
	};
	return self;
});
var HeroProjectile = Container.expand(function () {
	var self = Container.call(this);
	var projectileGraphics = self.attachAsset('heroProjectile', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.velocityX = 10; // Increased bullet speed
	self.damage = 10;
	self.update = function () {
		self.x += self.velocityX;
		// Remove if off screen
		if (self.x > 2048 + projectileGraphics.width) {
			self.destroy();
			var index = projectiles.indexOf(self);
			if (index !== -1) {
				projectiles.splice(index, 1);
			}
		}
	};
	return self;
});
var Platform = Container.expand(function () {
	var self = Container.call(this);
	var platformGraphics = self.attachAsset('platform', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.update = function () {
		// Store lastY for transition detection
		if (self.lastY === undefined) {
			self.lastY = self.y;
		}
		// Update lastY
		self.lastY = self.y;
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x34495e
});
/**** 
* Game Code
****/ 
// Game variables
var hero;
var boss;
var platforms = [];
var projectiles = [];
var bossProjectiles = [];
var groundLevel = 2400;
var heroHealthBar;
var heroHealthBarBg;
var bossHealthBar;
var bossHealthBarBg;
var moveLeftBtn;
var moveRightBtn;
var jumpBtn;
var shootBtn;
var pressedLeft = false;
var pressedRight = false;
// Set up game environment
function setupGame() {
	// Add background image
	var background = LK.getAsset('backgroundImage', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: 1024,
		y: 1366
	});
	game.addChild(background);
	// Create hero
	hero = new Hero();
	hero.x = 400;
	hero.y = groundLevel - hero.height / 2;
	game.addChild(hero);
	// Create boss
	boss = new Boss();
	boss.x = 1600;
	boss.y = groundLevel - boss.height / 2;
	game.addChild(boss);
	// Create platforms
	createPlatforms();
	// Create UI
	createUI();
	// Start background music
	LK.playMusic('battleMusic');
}
function createPlatforms() {
	// Ground platform
	var ground = new Platform();
	ground.x = 1024;
	ground.y = groundLevel + 20;
	ground.scaleX = 5.12; // Cover full width (2048 / 400)
	game.addChild(ground);
	platforms.push(ground);
	// Add some floating platforms
	var platformPositions = [{
		x: 600,
		y: 2200
	}, {
		x: 1200,
		y: 2100
	}, {
		x: 1800,
		y: 2200
	}, {
		x: 1000,
		y: 2000
	}, {
		x: 1500,
		y: 1900
	}];
	for (var i = 0; i < platformPositions.length; i++) {
		var platform = new Platform();
		platform.x = platformPositions[i].x;
		platform.y = platformPositions[i].y;
		game.addChild(platform);
		platforms.push(platform);
	}
}
function createUI() {
	// Create hero health bar background
	heroHealthBarBg = LK.getAsset('healthBarBackground', {
		anchorX: 0,
		anchorY: 0.5,
		x: 20,
		y: 50
	});
	LK.gui.topLeft.addChild(heroHealthBarBg);
	// Create hero health bar
	heroHealthBar = LK.getAsset('healthBar', {
		anchorX: 0,
		anchorY: 0.5,
		x: 20,
		y: 50
	});
	LK.gui.topLeft.addChild(heroHealthBar);
	// Create hero secondary health bar
	heroSecondaryHealthBar = LK.getAsset('healthBar', {
		anchorX: 0,
		anchorY: 0.5,
		x: 20,
		y: 90
	});
	LK.gui.topLeft.addChild(heroSecondaryHealthBar);
	// Create boss health bar background
	bossHealthBarBg = LK.getAsset('healthBarBackground', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: 1024,
		y: 50
	});
	LK.gui.top.addChild(bossHealthBarBg);
	// Create boss health bar
	bossHealthBar = LK.getAsset('healthBar', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: 0,
		y: 50
	});
	LK.gui.top.addChild(bossHealthBar);
	// Create boss secondary health bar
	bossSecondaryHealthBar = LK.getAsset('healthBar', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: 0,
		y: 90
	});
	LK.gui.top.addChild(bossSecondaryHealthBar);
	// Create control buttons
	createControlButtons();
}
function createControlButtons() {
	// Left movement button
	moveLeftBtn = LK.getAsset('platform', {
		anchorX: 0.5,
		anchorY: 0.5,
		alpha: 0.5,
		x: 150,
		y: -150
	});
	moveLeftBtn.width = 150;
	moveLeftBtn.height = 150;
	moveLeftBtn.tint = 0x3498db;
	LK.gui.bottomLeft.addChild(moveLeftBtn);
	// Right movement button
	moveRightBtn = LK.getAsset('platform', {
		anchorX: 0.5,
		anchorY: 0.5,
		alpha: 0.5,
		x: 320,
		y: -150
	});
	moveRightBtn.width = 150;
	moveRightBtn.height = 150;
	moveRightBtn.tint = 0x3498db;
	LK.gui.bottomLeft.addChild(moveRightBtn);
	// Jump button
	jumpBtn = LK.getAsset('platform', {
		anchorX: 0.5,
		anchorY: 0.5,
		alpha: 0.5,
		x: -150,
		y: -150
	});
	jumpBtn.width = 150;
	jumpBtn.height = 150;
	jumpBtn.tint = 0x2ecc71;
	LK.gui.bottomRight.addChild(jumpBtn);
	// Shoot button
	shootBtn = LK.getAsset('platform', {
		anchorX: 0.5,
		anchorY: 0.5,
		alpha: 0.5,
		x: -320,
		y: -150
	});
	shootBtn.width = 150;
	shootBtn.height = 150;
	shootBtn.tint = 0xe74c3c;
	LK.gui.bottomRight.addChild(shootBtn);
	// Add event handlers
	moveLeftBtn.interactive = true;
	moveRightBtn.interactive = true;
	jumpBtn.interactive = true;
	shootBtn.interactive = true;
	// Setup button events
	moveLeftBtn.down = function () {
		pressedLeft = true;
	};
	moveLeftBtn.up = function () {
		pressedLeft = false;
	};
	moveRightBtn.down = function () {
		pressedRight = true;
	};
	moveRightBtn.up = function () {
		pressedRight = false;
	};
	jumpBtn.down = function () {
		hero.jump();
	};
	shootBtn.down = function () {
		hero.shoot();
	};
}
function updateHealthBar() {
	var healthPercentage = hero.health / hero.maxHealth;
	heroHealthBar.scaleX = healthPercentage;
	// Update secondary health bar
	var secondaryHealthPercentage = Math.max(0, (hero.health - hero.maxHealth / 2) / (hero.maxHealth / 2));
	heroSecondaryHealthBar.scaleX = secondaryHealthPercentage;
}
function updateBossHealthBar() {
	var healthPercentage = boss.health / boss.maxHealth;
	bossHealthBar.scaleX = healthPercentage;
	// Update secondary health bar
	var secondaryHealthPercentage = Math.max(0, (boss.health - boss.maxHealth / 2) / (boss.maxHealth / 2));
	bossSecondaryHealthBar.scaleX = secondaryHealthPercentage;
}
function checkCollisions() {
	// Check hero-boss collision
	if (hero.intersects(boss) && !hero.invulnerable) {
		hero.takeDamage(20);
		// Knock hero back
		hero.velocityY = -10;
		if (hero.x < boss.x) {
			hero.x -= 100;
		} else {
			hero.x += 100;
		}
	}
	// Check platform collisions for hero
	for (var i = 0; i < platforms.length; i++) {
		var platform = platforms[i];
		// Only check if hero is falling
		if (hero.velocityY > 0) {
			var heroPrevY = hero.y - hero.velocityY;
			// Check if hero was above platform in previous frame
			if (heroPrevY + hero.height / 2 <= platform.y - platform.height / 2) {
				// Check if hero is now colliding with platform
				if (hero.intersects(platform)) {
					hero.y = platform.y - platform.height / 2 - hero.height / 2;
					hero.velocityY = 0;
					hero.isGrounded = true;
					hero.isJumping = false;
				}
			}
		}
	}
	// Check hero projectile collisions with boss
	for (var j = projectiles.length - 1; j >= 0; j--) {
		var projectile = projectiles[j];
		if (projectile.intersects(boss)) {
			boss.takeDamage(projectile.damage);
			// Remove projectile
			projectile.destroy();
			projectiles.splice(j, 1);
		}
	}
	// Check boss projectile collisions with hero
	for (var k = bossProjectiles.length - 1; k >= 0; k--) {
		var bossProjectile = bossProjectiles[k];
		if (bossProjectile.intersects(hero) && !hero.invulnerable) {
			hero.takeDamage(bossProjectile.damage);
			// Remove projectile
			bossProjectile.destroy();
			bossProjectiles.splice(k, 1);
		}
	}
}
function handleGameInput() {
	// Handle movement based on button states
	if (pressedLeft) {
		hero.x -= hero.speed;
	}
	if (pressedRight) {
		hero.x += hero.speed;
	}
}
// Set up game
setupGame();
boss.onDefeat = function () {
	LK.getSound('bossDeath').play();
	LK.showYouWin();
};
// Game update loop
game.update = function () {
	// Update hero
	hero.update();
	// Update boss
	boss.update();
	// Update platforms
	for (var i = 0; i < platforms.length; i++) {
		platforms[i].update();
	}
	// Update projectiles
	for (var i = 0; i < projectiles.length; i++) {
		projectiles[i].update();
	}
	for (var j = 0; j < bossProjectiles.length; j++) {
		bossProjectiles[j].update();
	}
	// Handle input
	handleGameInput();
	// Check collisions
	checkCollisions();
};
// Touch events for the game area
game.down = function (x, y, obj) {
	// Check if touch was on control buttons
	var touchPoint = {
		x: x,
		y: y
	};
	var moveLeftPos = moveLeftBtn.parent.toGlobal(moveLeftBtn.position);
	var moveRightPos = moveRightBtn.parent.toGlobal(moveRightBtn.position);
	var jumpPos = jumpBtn.parent.toGlobal(jumpBtn.position);
	var shootPos = shootBtn.parent.toGlobal(shootBtn.position);
	// Simple distance check for buttons
	if (distance(touchPoint, moveLeftPos) < 75) {
		pressedLeft = true;
	} else if (distance(touchPoint, moveRightPos) < 75) {
		pressedRight = true;
	} else if (distance(touchPoint, jumpPos) < 75) {
		hero.jump();
	} else if (distance(touchPoint, shootPos) < 75) {
		hero.shoot();
	}
};
game.up = function (x, y, obj) {
	// Stop movement when touch is released
	pressedLeft = false;
	pressedRight = false;
};
// Helper function to calculate distance between points
function distance(p1, p2) {
	return Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2));
}
 chibi mario bross stand fight Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
 chibi fat bowser left pose. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
 rock pattern. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
 chibi fire ball. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
 8 bit image dark castle corridor cartoon style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows