User prompt
özellik seçme ekranını kaldır
User prompt
Change feature selection popup 200 point
User prompt
muhteşem özellik seç ekranı her 300 puanda bir gelsin
User prompt
muhteşem özellik seç ekranı ingilizce yazmalı o ekran gelince oyun durmalı
User prompt
özellik seçme ekranı gelsin her 300 puanda bir muhteşem harika özellik ekranı açılsın 3 özellikten birini seçmeli kullanıcı
User prompt
özellikler birbiriyle combo yapsın birleşsinler
User prompt
add different features
User prompt
arkaplan her 200 puanda bir değişsin daha güzel olsun
User prompt
düşmanlar ekranın sağından ve solundan çıkmasın
User prompt
düşmanlar ekrandan çıksın
User prompt
düşmanlar ekranın aşşagısana gidince yok olsun
User prompt
ekranda parlama olmasın
User prompt
düşmanların can barı olsun ve düşmanlar ekrandan çıkmasın
User prompt
tekrar dene
User prompt
powerup daha çok gelsin
User prompt
powerup daha fazla özellik ekle gemiyi güçlendiren
User prompt
oyunu biraz kolaylaştır
User prompt
geminin canını arttır ve oyuna biraz eğlenceli şeyler ekle
User prompt
insan reflekslerine göre oyunu düzenle
User prompt
powerup daha çok gelsin
User prompt
özellikler daha çok gelsin ve farklı özellikler ekle
User prompt
yeni düşmanlar ekle
User prompt
düşmanlar daha hızlı ölmeli
User prompt
düşman öldürüncede puan gelsin ve combo sistemi olsuın
User prompt
Please fix the bug: 'TypeError: LK.effects.shakeScreen is not a function' in or related to this line: 'LK.effects.shakeScreen(8, 80);' Line Number: 413
/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
/**** 
* Classes
****/ 
// Enemy
var Enemy = Container.expand(function () {
	var self = Container.call(this);
	var enemyGfx = self.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.radius = enemyGfx.width * 0.5;
	self.speed = 8 + Math.random() * 8;
	self.moveType = Math.random() < 0.5 ? 'straight' : 'sine';
	self.sinePhase = Math.random() * Math.PI * 2;
	self.sineAmp = 120 + Math.random() * 120;
	self.shootCooldown = 60 + Math.floor(Math.random() * 60);
	// Health system for enemy
	self.maxHealth = 3;
	self.health = self.maxHealth;
	self.update = function () {
		if (self.moveType === 'straight') {
			self.y += self.speed;
		} else {
			self.y += self.speed * 0.85;
			self.x += Math.sin(self.y / 120 + self.sinePhase) * 6;
		}
		self.shootCooldown--;
	};
	self.takeDamage = function (dmg) {
		self.health -= dmg;
		LK.effects.flashObject(self, 0xffffff, 80);
		if (self.health <= 0) {
			self.health = 0;
			// Death handled in game loop
		}
	};
	return self;
});
// Enemy Bullet
var EnemyBullet = Container.expand(function () {
	var self = Container.call(this);
	var bulletGfx = self.attachAsset('enemyBullet', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 20;
	self.dirX = 0;
	self.dirY = 1;
	self.update = function () {
		self.x += self.dirX * self.speed;
		self.y += self.dirY * self.speed;
	};
	return self;
});
// Player Bullet
var PlayerBullet = Container.expand(function () {
	var self = Container.call(this);
	var bulletGfx = self.attachAsset('playerBullet', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = -32;
	self.update = function () {
		self.y += self.speed;
	};
	return self;
});
// Powerup
var Powerup = Container.expand(function () {
	var self = Container.call(this);
	var types = ['rapid', 'shield', 'heal'];
	var r = Math.random();
	if (r < 0.4) self.type = 'rapid';else if (r < 0.8) self.type = 'shield';else self.type = 'heal';
	var powerupGfx = self.attachAsset('powerup', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	if (self.type === 'rapid') powerupGfx.tint = 0xffe100;else if (self.type === 'shield') powerupGfx.tint = 0x00ffff;else powerupGfx.tint = 0x44ff44;
	self.speed = 10;
	self.update = function () {
		self.y += self.speed;
	};
	return self;
});
// Player Ship
var Ship = Container.expand(function () {
	var self = Container.call(this);
	var shipGfx = self.attachAsset('ship', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.radius = shipGfx.width * 0.5;
	self.shootCooldown = 0;
	self.rapidFire = false;
	self.rapidFireTimer = 0;
	self.shield = false;
	self.shieldTimer = 0;
	// Health system for player
	self.maxHealth = 5;
	self.health = self.maxHealth;
	// Health bar
	var healthBarBg = self.attachAsset('playerBullet', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 2.2,
		scaleY: 0.25,
		tint: 0x222222,
		y: shipGfx.height * 0.7
	});
	var healthBar = self.attachAsset('playerBullet', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 2,
		scaleY: 0.18,
		tint: 0xff4444,
		y: shipGfx.height * 0.7
	});
	// Visual shield indicator
	var shieldGfx = self.attachAsset('ship', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 1.3,
		scaleY: 1.3,
		tint: 0x00ffff
	});
	shieldGfx.alpha = 0.25;
	shieldGfx.visible = false;
	self.update = function () {
		// Handle powerup timers
		if (self.rapidFire) {
			self.rapidFireTimer--;
			// Visual feedback for rapid fire: pulse ship color
			shipGfx.tint = LK.ticks % 10 < 5 ? 0xffe100 : 0x33c1ff;
			if (self.rapidFireTimer <= 0) {
				self.rapidFire = false;
				shipGfx.tint = 0x33c1ff;
			}
		} else {
			shipGfx.tint = 0x33c1ff;
		}
		if (self.shield) {
			self.shieldTimer--;
			shieldGfx.visible = true;
			if (self.shieldTimer <= 0) {
				self.shield = false;
				shieldGfx.visible = false;
			}
		} else {
			shieldGfx.visible = false;
		}
		// Update health bar
		healthBar.scaleX = 2 * (self.health / self.maxHealth);
		if (self.health < 1) healthBar.scaleX = 0;
	};
	self.activateRapidFire = function (duration) {
		self.rapidFire = true;
		self.rapidFireTimer = duration;
	};
	self.activateShield = function (duration) {
		self.shield = true;
		self.shieldTimer = duration;
		shieldGfx.visible = true;
	};
	self.takeDamage = function (dmg) {
		if (self.shield) return;
		self.health -= dmg;
		LK.effects.flashObject(self, 0xff0000, 200);
		if (self.health < 0) self.health = 0;
	};
	self.heal = function (amount) {
		self.health += amount;
		if (self.health > self.maxHealth) self.health = self.maxHealth;
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	// No title, no description
	// Always backgroundColor is black
	backgroundColor: 0x000000
});
/**** 
* Game Code
****/ 
// Music
// Sound effects
// Powerup
// Enemy bullet
// Enemy
// Player bullet
// Spaceship (player)
// Game area
var GAME_W = 2048,
	GAME_H = 2732;
// Score
var score = 0;
var scoreTxt = new Text2('0', {
	size: 120,
	fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Player ship
var ship = new Ship();
game.addChild(ship);
ship.x = GAME_W / 2;
ship.y = GAME_H - 350;
// Arrays for game objects
var playerBullets = [];
var enemies = [];
var enemyBullets = [];
var powerups = [];
// Dragging
var dragNode = null;
// Difficulty
var enemySpawnTimer = 0;
var enemySpawnInterval = 60;
var minEnemyInterval = 18;
var enemySpeedInc = 0;
// Powerup spawn
var powerupTimer = 0;
var powerupInterval = 600;
// Last intersect states
var lastShipEnemyIntersect = false;
var lastShipEnemyBulletIntersect = false;
var lastShipPowerupIntersect = false;
// Music
LK.playMusic('bgmusic');
// Move handler (drag ship)
function handleMove(x, y, obj) {
	if (dragNode === ship) {
		// Clamp ship inside game area (with margin)
		var margin = 80;
		var nx = Math.max(margin, Math.min(GAME_W - margin, x));
		var ny = Math.max(margin, Math.min(GAME_H - margin, y));
		ship.x = nx;
		ship.y = ny;
		// Touch feedback: scale ship up slightly while dragging, then back
		ship.scale.set(1.15, 1.15);
		tween(ship.scale, {
			x: 1,
			y: 1
		}, {
			duration: 120
		});
	}
}
game.move = handleMove;
var dragAnywhereHintShown = false;
game.down = function (x, y, obj) {
	// User-friendly: allow drag to start if touch is on ship OR anywhere in lower half of screen
	var dx = x - ship.x,
		dy = y - ship.y;
	var onShip = dx * dx + dy * dy < ship.radius * ship.radius * 1.2;
	var inLowerHalf = y > GAME_H / 2;
	if (onShip || inLowerHalf) {
		dragNode = ship;
		handleMove(x, y, obj);
		// Visual feedback: flash ship blue for 120ms on drag start
		LK.effects.flashObject(ship, 0x33c1ff, 120);
		// Show floating helper text only the first time user drags from lower half (not on ship)
		if (!onShip && inLowerHalf && !dragAnywhereHintShown) {
			showFloatingText("Tip: Drag anywhere below to move!", ship.x, ship.y - 180, 0x33c1ff);
			dragAnywhereHintShown = true;
		}
	}
};
game.up = function (x, y, obj) {
	dragNode = null;
};
// Main update loop
game.update = function () {
	// Update ship
	ship.update();
	// --- Player shooting ---
	ship.shootCooldown--;
	var shootRate = ship.rapidFire ? 6 : 18;
	if (ship.shootCooldown <= 0) {
		// Auto-fire
		var pb = new PlayerBullet();
		pb.x = ship.x;
		pb.y = ship.y - ship.radius - 30;
		playerBullets.push(pb);
		game.addChild(pb);
		ship.shootCooldown = shootRate;
		LK.getSound('shoot').play();
	}
	// --- Update player bullets ---
	for (var i = playerBullets.length - 1; i >= 0; i--) {
		var b = playerBullets[i];
		b.update();
		// Remove if off screen
		if (b.y < -80) {
			b.destroy();
			playerBullets.splice(i, 1);
		}
	}
	// --- Update enemies ---
	for (var i = enemies.length - 1; i >= 0; i--) {
		var e = enemies[i];
		// --- Enemy AI: dodge if player is close horizontally ---
		if (Math.abs(ship.x - e.x) < 180 && Math.abs(ship.y - e.y) < 600) {
			// Try to dodge left or right
			if (ship.x < e.x) e.x += 10 + Math.random() * 6;else e.x -= 10 + Math.random() * 6;
		}
		e.update();
		// Remove if off screen
		if (e.y > GAME_H + 120) {
			e.destroy();
			enemies.splice(i, 1);
			continue;
		}
		// Enemy shooting
		if (e.shootCooldown <= 0) {
			var eb = new EnemyBullet();
			eb.x = e.x;
			eb.y = e.y + e.radius + 10;
			// Aim at ship
			var dx = ship.x - e.x,
				dy = ship.y - e.y;
			var len = Math.sqrt(dx * dx + dy * dy);
			if (len > 0) {
				eb.dirX = dx / len;
				eb.dirY = dy / len;
			}
			enemyBullets.push(eb);
			game.addChild(eb);
			e.shootCooldown = 90 + Math.floor(Math.random() * 60);
		}
	}
	// --- Update enemy bullets ---
	for (var i = enemyBullets.length - 1; i >= 0; i--) {
		var eb = enemyBullets[i];
		eb.update();
		if (eb.x < -100 || eb.x > GAME_W + 100 || eb.y < -100 || eb.y > GAME_H + 100) {
			eb.destroy();
			enemyBullets.splice(i, 1);
		}
	}
	// --- Update powerups ---
	for (var i = powerups.length - 1; i >= 0; i--) {
		var p = powerups[i];
		p.update();
		if (p.y > GAME_H + 100) {
			p.destroy();
			powerups.splice(i, 1);
		}
	}
	// --- Collision: Player bullets vs Enemies ---
	for (var i = playerBullets.length - 1; i >= 0; i--) {
		var b = playerBullets[i];
		for (var j = enemies.length - 1; j >= 0; j--) {
			var e = enemies[j];
			if (b.intersects(e)) {
				// Hit enemy
				e.takeDamage(1);
				// Recoil effect for enemy
				tween(e, {
					y: e.y - 30
				}, {
					duration: 60,
					yoyo: true,
					repeat: 1
				});
				// Camera shake on hit (simulate with quick flash)
				LK.effects.flashScreen(0xffffff, 80);
				LK.getSound('enemyDown').play();
				// Score only if enemy dies
				if (e.health <= 0) {
					score += 10;
					// Animate score text for feedback
					scoreTxt.setText(score);
					scoreTxt.scale.set(1.25, 1.25);
					tween(scoreTxt.scale, {
						x: 1,
						y: 1
					}, {
						duration: 200
					});
					e.destroy();
					enemies.splice(j, 1);
				}
				b.destroy();
				playerBullets.splice(i, 1);
				break;
			}
		}
	}
	// --- Collision: Ship vs Enemies ---
	var shipEnemyIntersect = false;
	for (var i = 0; i < enemies.length; i++) {
		var e = enemies[i];
		if (ship.intersects(e)) {
			shipEnemyIntersect = true;
			break;
		}
	}
	if (!lastShipEnemyIntersect && shipEnemyIntersect) {
		if (ship.shield) {
			// Absorb hit, destroy enemy
			LK.effects.flashObject(ship, 0x00ffff, 400);
			for (var i = 0; i < enemies.length; i++) {
				if (ship.intersects(enemies[i])) {
					enemies[i].destroy();
					enemies.splice(i, 1);
					break;
				}
			}
			ship.shield = false;
			ship.shieldTimer = 0;
			ship.children[1].visible = false;
		} else {
			// Take damage
			ship.takeDamage(2);
			// Camera shake (simulate with quick flash)
			LK.effects.flashScreen(0xffffff, 180);
			LK.getSound('hit').play();
			if (ship.health <= 0) {
				LK.effects.flashScreen(0xff0000, 1000);
				LK.showGameOver();
				return;
			}
		}
	}
	lastShipEnemyIntersect = shipEnemyIntersect;
	// --- Collision: Ship vs Enemy Bullets ---
	var shipEnemyBulletIntersect = false;
	for (var i = 0; i < enemyBullets.length; i++) {
		var eb = enemyBullets[i];
		if (ship.intersects(eb)) {
			shipEnemyBulletIntersect = true;
			break;
		}
	}
	if (!lastShipEnemyBulletIntersect && shipEnemyBulletIntersect) {
		if (ship.shield) {
			LK.effects.flashObject(ship, 0x00ffff, 400);
			// Remove bullet
			for (var i = 0; i < enemyBullets.length; i++) {
				if (ship.intersects(enemyBullets[i])) {
					enemyBullets[i].destroy();
					enemyBullets.splice(i, 1);
					break;
				}
			}
			ship.shield = false;
			ship.shieldTimer = 0;
			ship.children[1].visible = false;
		} else {
			// Take damage
			ship.takeDamage(1);
			// Camera shake (simulate with quick flash)
			LK.effects.flashScreen(0xffffff, 120);
			LK.getSound('hit').play();
			if (ship.health <= 0) {
				LK.effects.flashScreen(0xff0000, 1000);
				LK.showGameOver();
				return;
			}
		}
	}
	lastShipEnemyBulletIntersect = shipEnemyBulletIntersect;
	// --- Collision: Ship vs Powerups ---
	var shipPowerupIntersect = false;
	for (var i = powerups.length - 1; i >= 0; i--) {
		var p = powerups[i];
		if (ship.intersects(p)) {
			shipPowerupIntersect = true;
			// Apply powerup
			LK.getSound('powerup').play();
			if (p.type === 'rapid') {
				ship.activateRapidFire(360);
				showFloatingText("Rapid Fire!", ship.x, ship.y - 120, 0xffe100);
			} else if (p.type === 'shield') {
				ship.activateShield(480);
				showFloatingText("Shield!", ship.x, ship.y - 120, 0x00ffff);
			} else if (p.type === 'heal') {
				ship.heal(2);
				showFloatingText("+2 Health", ship.x, ship.y - 120, 0x44ff44);
			}
			p.destroy();
			powerups.splice(i, 1);
		}
	}
	lastShipPowerupIntersect = shipPowerupIntersect;
	// --- Mission system: show floating text for milestones ---
	if (score > 0 && score % 100 === 0 && !game['milestone_' + score]) {
		showFloatingText("Milestone: " + score + "!", GAME_W / 2, 320, 0xffe100);
		game['milestone_' + score] = true;
	}
	// --- Enemy spawn ---
	enemySpawnTimer--;
	if (enemySpawnTimer <= 0) {
		// Spawn enemy at random x
		var e = new Enemy();
		e.x = 180 + Math.random() * (GAME_W - 360);
		e.y = -100;
		// Increase speed as score increases
		e.speed += Math.floor(score / 200) * 2;
		enemies.push(e);
		game.addChild(e);
		// Decrease interval as score increases
		enemySpawnInterval = Math.max(minEnemyInterval, 60 - Math.floor(score / 100) * 4);
		enemySpawnTimer = enemySpawnInterval;
	}
	// --- Powerup spawn ---
	powerupTimer--;
	if (powerupTimer <= 0) {
		var p = new Powerup();
		p.x = 180 + Math.random() * (GAME_W - 360);
		p.y = -80;
		powerups.push(p);
		game.addChild(p);
		powerupInterval = 600 + Math.floor(Math.random() * 600);
		powerupTimer = powerupInterval;
	}
};
// Floating text helper for feedback
function showFloatingText(txt, x, y, color) {
	var t = new Text2(txt, {
		size: 90,
		fill: color || 0xffffff,
		stroke: 0x000000,
		strokeThickness: 8
	});
	t.anchor.set(0.5, 1);
	t.x = x;
	t.y = y;
	game.addChild(t);
	tween(t, {
		y: y - 120,
		alpha: 0
	}, {
		duration: 700,
		onFinish: function onFinish() {
			t.destroy();
		}
	});
}
// Show instructions at game start
var instructionTxt = new Text2("Drag the ship to move\nAuto-fire enabled\nCollect powerups!", {
	size: 90,
	fill: 0xffffff,
	stroke: 0x000000,
	strokeThickness: 8,
	align: "center"
});
instructionTxt.anchor.set(0.5, 0.5);
instructionTxt.x = GAME_W / 2;
instructionTxt.y = GAME_H / 2 - 200;
game.addChild(instructionTxt);
tween(instructionTxt, {
	alpha: 0
}, {
	duration: 1800,
	onFinish: function onFinish() {
		instructionTxt.destroy();
	}
}); /**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
/**** 
* Classes
****/ 
// Enemy
var Enemy = Container.expand(function () {
	var self = Container.call(this);
	var enemyGfx = self.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.radius = enemyGfx.width * 0.5;
	self.speed = 8 + Math.random() * 8;
	self.moveType = Math.random() < 0.5 ? 'straight' : 'sine';
	self.sinePhase = Math.random() * Math.PI * 2;
	self.sineAmp = 120 + Math.random() * 120;
	self.shootCooldown = 60 + Math.floor(Math.random() * 60);
	// Health system for enemy
	self.maxHealth = 3;
	self.health = self.maxHealth;
	self.update = function () {
		if (self.moveType === 'straight') {
			self.y += self.speed;
		} else {
			self.y += self.speed * 0.85;
			self.x += Math.sin(self.y / 120 + self.sinePhase) * 6;
		}
		self.shootCooldown--;
	};
	self.takeDamage = function (dmg) {
		self.health -= dmg;
		LK.effects.flashObject(self, 0xffffff, 80);
		if (self.health <= 0) {
			self.health = 0;
			// Death handled in game loop
		}
	};
	return self;
});
// Enemy Bullet
var EnemyBullet = Container.expand(function () {
	var self = Container.call(this);
	var bulletGfx = self.attachAsset('enemyBullet', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 20;
	self.dirX = 0;
	self.dirY = 1;
	self.update = function () {
		self.x += self.dirX * self.speed;
		self.y += self.dirY * self.speed;
	};
	return self;
});
// Player Bullet
var PlayerBullet = Container.expand(function () {
	var self = Container.call(this);
	var bulletGfx = self.attachAsset('playerBullet', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = -32;
	self.update = function () {
		self.y += self.speed;
	};
	return self;
});
// Powerup
var Powerup = Container.expand(function () {
	var self = Container.call(this);
	var types = ['rapid', 'shield', 'heal'];
	var r = Math.random();
	if (r < 0.4) self.type = 'rapid';else if (r < 0.8) self.type = 'shield';else self.type = 'heal';
	var powerupGfx = self.attachAsset('powerup', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	if (self.type === 'rapid') powerupGfx.tint = 0xffe100;else if (self.type === 'shield') powerupGfx.tint = 0x00ffff;else powerupGfx.tint = 0x44ff44;
	self.speed = 10;
	self.update = function () {
		self.y += self.speed;
	};
	return self;
});
// Player Ship
var Ship = Container.expand(function () {
	var self = Container.call(this);
	var shipGfx = self.attachAsset('ship', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.radius = shipGfx.width * 0.5;
	self.shootCooldown = 0;
	self.rapidFire = false;
	self.rapidFireTimer = 0;
	self.shield = false;
	self.shieldTimer = 0;
	// Health system for player
	self.maxHealth = 5;
	self.health = self.maxHealth;
	// Health bar
	var healthBarBg = self.attachAsset('playerBullet', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 2.2,
		scaleY: 0.25,
		tint: 0x222222,
		y: shipGfx.height * 0.7
	});
	var healthBar = self.attachAsset('playerBullet', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 2,
		scaleY: 0.18,
		tint: 0xff4444,
		y: shipGfx.height * 0.7
	});
	// Visual shield indicator
	var shieldGfx = self.attachAsset('ship', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 1.3,
		scaleY: 1.3,
		tint: 0x00ffff
	});
	shieldGfx.alpha = 0.25;
	shieldGfx.visible = false;
	self.update = function () {
		// Handle powerup timers
		if (self.rapidFire) {
			self.rapidFireTimer--;
			// Visual feedback for rapid fire: pulse ship color
			shipGfx.tint = LK.ticks % 10 < 5 ? 0xffe100 : 0x33c1ff;
			if (self.rapidFireTimer <= 0) {
				self.rapidFire = false;
				shipGfx.tint = 0x33c1ff;
			}
		} else {
			shipGfx.tint = 0x33c1ff;
		}
		if (self.shield) {
			self.shieldTimer--;
			shieldGfx.visible = true;
			if (self.shieldTimer <= 0) {
				self.shield = false;
				shieldGfx.visible = false;
			}
		} else {
			shieldGfx.visible = false;
		}
		// Update health bar
		healthBar.scaleX = 2 * (self.health / self.maxHealth);
		if (self.health < 1) healthBar.scaleX = 0;
	};
	self.activateRapidFire = function (duration) {
		self.rapidFire = true;
		self.rapidFireTimer = duration;
	};
	self.activateShield = function (duration) {
		self.shield = true;
		self.shieldTimer = duration;
		shieldGfx.visible = true;
	};
	self.takeDamage = function (dmg) {
		if (self.shield) return;
		self.health -= dmg;
		LK.effects.flashObject(self, 0xff0000, 200);
		if (self.health < 0) self.health = 0;
	};
	self.heal = function (amount) {
		self.health += amount;
		if (self.health > self.maxHealth) self.health = self.maxHealth;
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	// No title, no description
	// Always backgroundColor is black
	backgroundColor: 0x000000
});
/**** 
* Game Code
****/ 
// Music
// Sound effects
// Powerup
// Enemy bullet
// Enemy
// Player bullet
// Spaceship (player)
// Game area
var GAME_W = 2048,
	GAME_H = 2732;
// Score
var score = 0;
var scoreTxt = new Text2('0', {
	size: 120,
	fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Player ship
var ship = new Ship();
game.addChild(ship);
ship.x = GAME_W / 2;
ship.y = GAME_H - 350;
// Arrays for game objects
var playerBullets = [];
var enemies = [];
var enemyBullets = [];
var powerups = [];
// Dragging
var dragNode = null;
// Difficulty
var enemySpawnTimer = 0;
var enemySpawnInterval = 60;
var minEnemyInterval = 18;
var enemySpeedInc = 0;
// Powerup spawn
var powerupTimer = 0;
var powerupInterval = 600;
// Last intersect states
var lastShipEnemyIntersect = false;
var lastShipEnemyBulletIntersect = false;
var lastShipPowerupIntersect = false;
// Music
LK.playMusic('bgmusic');
// Move handler (drag ship)
function handleMove(x, y, obj) {
	if (dragNode === ship) {
		// Clamp ship inside game area (with margin)
		var margin = 80;
		var nx = Math.max(margin, Math.min(GAME_W - margin, x));
		var ny = Math.max(margin, Math.min(GAME_H - margin, y));
		ship.x = nx;
		ship.y = ny;
		// Touch feedback: scale ship up slightly while dragging, then back
		ship.scale.set(1.15, 1.15);
		tween(ship.scale, {
			x: 1,
			y: 1
		}, {
			duration: 120
		});
	}
}
game.move = handleMove;
var dragAnywhereHintShown = false;
game.down = function (x, y, obj) {
	// User-friendly: allow drag to start if touch is on ship OR anywhere in lower half of screen
	var dx = x - ship.x,
		dy = y - ship.y;
	var onShip = dx * dx + dy * dy < ship.radius * ship.radius * 1.2;
	var inLowerHalf = y > GAME_H / 2;
	if (onShip || inLowerHalf) {
		dragNode = ship;
		handleMove(x, y, obj);
		// Visual feedback: flash ship blue for 120ms on drag start
		LK.effects.flashObject(ship, 0x33c1ff, 120);
		// Show floating helper text only the first time user drags from lower half (not on ship)
		if (!onShip && inLowerHalf && !dragAnywhereHintShown) {
			showFloatingText("Tip: Drag anywhere below to move!", ship.x, ship.y - 180, 0x33c1ff);
			dragAnywhereHintShown = true;
		}
	}
};
game.up = function (x, y, obj) {
	dragNode = null;
};
// Main update loop
game.update = function () {
	// Update ship
	ship.update();
	// --- Player shooting ---
	ship.shootCooldown--;
	var shootRate = ship.rapidFire ? 6 : 18;
	if (ship.shootCooldown <= 0) {
		// Auto-fire
		var pb = new PlayerBullet();
		pb.x = ship.x;
		pb.y = ship.y - ship.radius - 30;
		playerBullets.push(pb);
		game.addChild(pb);
		ship.shootCooldown = shootRate;
		LK.getSound('shoot').play();
	}
	// --- Update player bullets ---
	for (var i = playerBullets.length - 1; i >= 0; i--) {
		var b = playerBullets[i];
		b.update();
		// Remove if off screen
		if (b.y < -80) {
			b.destroy();
			playerBullets.splice(i, 1);
		}
	}
	// --- Update enemies ---
	for (var i = enemies.length - 1; i >= 0; i--) {
		var e = enemies[i];
		// --- Enemy AI: dodge if player is close horizontally ---
		if (Math.abs(ship.x - e.x) < 180 && Math.abs(ship.y - e.y) < 600) {
			// Try to dodge left or right
			if (ship.x < e.x) e.x += 10 + Math.random() * 6;else e.x -= 10 + Math.random() * 6;
		}
		e.update();
		// Remove if off screen
		if (e.y > GAME_H + 120) {
			e.destroy();
			enemies.splice(i, 1);
			continue;
		}
		// Enemy shooting
		if (e.shootCooldown <= 0) {
			var eb = new EnemyBullet();
			eb.x = e.x;
			eb.y = e.y + e.radius + 10;
			// Aim at ship
			var dx = ship.x - e.x,
				dy = ship.y - e.y;
			var len = Math.sqrt(dx * dx + dy * dy);
			if (len > 0) {
				eb.dirX = dx / len;
				eb.dirY = dy / len;
			}
			enemyBullets.push(eb);
			game.addChild(eb);
			e.shootCooldown = 90 + Math.floor(Math.random() * 60);
		}
	}
	// --- Update enemy bullets ---
	for (var i = enemyBullets.length - 1; i >= 0; i--) {
		var eb = enemyBullets[i];
		eb.update();
		if (eb.x < -100 || eb.x > GAME_W + 100 || eb.y < -100 || eb.y > GAME_H + 100) {
			eb.destroy();
			enemyBullets.splice(i, 1);
		}
	}
	// --- Update powerups ---
	for (var i = powerups.length - 1; i >= 0; i--) {
		var p = powerups[i];
		p.update();
		if (p.y > GAME_H + 100) {
			p.destroy();
			powerups.splice(i, 1);
		}
	}
	// --- Collision: Player bullets vs Enemies ---
	for (var i = playerBullets.length - 1; i >= 0; i--) {
		var b = playerBullets[i];
		for (var j = enemies.length - 1; j >= 0; j--) {
			var e = enemies[j];
			if (b.intersects(e)) {
				// Hit enemy
				e.takeDamage(1);
				// Recoil effect for enemy
				tween(e, {
					y: e.y - 30
				}, {
					duration: 60,
					yoyo: true,
					repeat: 1
				});
				// Camera shake on hit (simulate with quick flash)
				LK.effects.flashScreen(0xffffff, 80);
				LK.getSound('enemyDown').play();
				// Score only if enemy dies
				if (e.health <= 0) {
					score += 10;
					// Animate score text for feedback
					scoreTxt.setText(score);
					scoreTxt.scale.set(1.25, 1.25);
					tween(scoreTxt.scale, {
						x: 1,
						y: 1
					}, {
						duration: 200
					});
					e.destroy();
					enemies.splice(j, 1);
				}
				b.destroy();
				playerBullets.splice(i, 1);
				break;
			}
		}
	}
	// --- Collision: Ship vs Enemies ---
	var shipEnemyIntersect = false;
	for (var i = 0; i < enemies.length; i++) {
		var e = enemies[i];
		if (ship.intersects(e)) {
			shipEnemyIntersect = true;
			break;
		}
	}
	if (!lastShipEnemyIntersect && shipEnemyIntersect) {
		if (ship.shield) {
			// Absorb hit, destroy enemy
			LK.effects.flashObject(ship, 0x00ffff, 400);
			for (var i = 0; i < enemies.length; i++) {
				if (ship.intersects(enemies[i])) {
					enemies[i].destroy();
					enemies.splice(i, 1);
					break;
				}
			}
			ship.shield = false;
			ship.shieldTimer = 0;
			ship.children[1].visible = false;
		} else {
			// Take damage
			ship.takeDamage(2);
			// Camera shake (simulate with quick flash)
			LK.effects.flashScreen(0xffffff, 180);
			LK.getSound('hit').play();
			if (ship.health <= 0) {
				LK.effects.flashScreen(0xff0000, 1000);
				LK.showGameOver();
				return;
			}
		}
	}
	lastShipEnemyIntersect = shipEnemyIntersect;
	// --- Collision: Ship vs Enemy Bullets ---
	var shipEnemyBulletIntersect = false;
	for (var i = 0; i < enemyBullets.length; i++) {
		var eb = enemyBullets[i];
		if (ship.intersects(eb)) {
			shipEnemyBulletIntersect = true;
			break;
		}
	}
	if (!lastShipEnemyBulletIntersect && shipEnemyBulletIntersect) {
		if (ship.shield) {
			LK.effects.flashObject(ship, 0x00ffff, 400);
			// Remove bullet
			for (var i = 0; i < enemyBullets.length; i++) {
				if (ship.intersects(enemyBullets[i])) {
					enemyBullets[i].destroy();
					enemyBullets.splice(i, 1);
					break;
				}
			}
			ship.shield = false;
			ship.shieldTimer = 0;
			ship.children[1].visible = false;
		} else {
			// Take damage
			ship.takeDamage(1);
			// Camera shake (simulate with quick flash)
			LK.effects.flashScreen(0xffffff, 120);
			LK.getSound('hit').play();
			if (ship.health <= 0) {
				LK.effects.flashScreen(0xff0000, 1000);
				LK.showGameOver();
				return;
			}
		}
	}
	lastShipEnemyBulletIntersect = shipEnemyBulletIntersect;
	// --- Collision: Ship vs Powerups ---
	var shipPowerupIntersect = false;
	for (var i = powerups.length - 1; i >= 0; i--) {
		var p = powerups[i];
		if (ship.intersects(p)) {
			shipPowerupIntersect = true;
			// Apply powerup
			LK.getSound('powerup').play();
			if (p.type === 'rapid') {
				ship.activateRapidFire(360);
				showFloatingText("Rapid Fire!", ship.x, ship.y - 120, 0xffe100);
			} else if (p.type === 'shield') {
				ship.activateShield(480);
				showFloatingText("Shield!", ship.x, ship.y - 120, 0x00ffff);
			} else if (p.type === 'heal') {
				ship.heal(2);
				showFloatingText("+2 Health", ship.x, ship.y - 120, 0x44ff44);
			}
			p.destroy();
			powerups.splice(i, 1);
		}
	}
	lastShipPowerupIntersect = shipPowerupIntersect;
	// --- Mission system: show floating text for milestones ---
	if (score > 0 && score % 100 === 0 && !game['milestone_' + score]) {
		showFloatingText("Milestone: " + score + "!", GAME_W / 2, 320, 0xffe100);
		game['milestone_' + score] = true;
	}
	// --- Enemy spawn ---
	enemySpawnTimer--;
	if (enemySpawnTimer <= 0) {
		// Spawn enemy at random x
		var e = new Enemy();
		e.x = 180 + Math.random() * (GAME_W - 360);
		e.y = -100;
		// Increase speed as score increases
		e.speed += Math.floor(score / 200) * 2;
		enemies.push(e);
		game.addChild(e);
		// Decrease interval as score increases
		enemySpawnInterval = Math.max(minEnemyInterval, 60 - Math.floor(score / 100) * 4);
		enemySpawnTimer = enemySpawnInterval;
	}
	// --- Powerup spawn ---
	powerupTimer--;
	if (powerupTimer <= 0) {
		var p = new Powerup();
		p.x = 180 + Math.random() * (GAME_W - 360);
		p.y = -80;
		powerups.push(p);
		game.addChild(p);
		powerupInterval = 600 + Math.floor(Math.random() * 600);
		powerupTimer = powerupInterval;
	}
};
// Floating text helper for feedback
function showFloatingText(txt, x, y, color) {
	var t = new Text2(txt, {
		size: 90,
		fill: color || 0xffffff,
		stroke: 0x000000,
		strokeThickness: 8
	});
	t.anchor.set(0.5, 1);
	t.x = x;
	t.y = y;
	game.addChild(t);
	tween(t, {
		y: y - 120,
		alpha: 0
	}, {
		duration: 700,
		onFinish: function onFinish() {
			t.destroy();
		}
	});
}
// Show instructions at game start
var instructionTxt = new Text2("Drag the ship to move\nAuto-fire enabled\nCollect powerups!", {
	size: 90,
	fill: 0xffffff,
	stroke: 0x000000,
	strokeThickness: 8,
	align: "center"
});
instructionTxt.anchor.set(0.5, 0.5);
instructionTxt.x = GAME_W / 2;
instructionTxt.y = GAME_H / 2 - 200;
game.addChild(instructionTxt);
tween(instructionTxt, {
	alpha: 0
}, {
	duration: 1800,
	onFinish: function onFinish() {
		instructionTxt.destroy();
	}
});