/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
/**** 
* Classes
****/ 
var AlienLaser = Container.expand(function () {
	var self = Container.call(this);
	var laserGraphics = self.attachAsset('beat_marker', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	laserGraphics.tint = 0xFF0000; // Red lasers
	self.speed = 10;
	self.update = function () {
		self.y += self.speed;
	};
	return self;
});
var AlienShip = Container.expand(function () {
	var self = Container.call(this);
	var alienGraphics = self.attachAsset('ship', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	alienGraphics.tint = 0xFF0000; // Red tint for alien ship
	self.health = 5;
	self.fireTimer = 0;
	self.fireInterval = 60; // Fire every second
	self.moveDirection = 1;
	self.speed = 2;
	self.update = function () {
		// Move side to side
		self.x += self.moveDirection * self.speed;
		if (self.x <= 200 || self.x >= 1848) {
			self.moveDirection *= -1;
		}
		// Fire lasers
		self.fireTimer++;
		if (self.fireTimer >= self.fireInterval) {
			self.fireTimer = 0;
			createAlienLaser(self.x, self.y + 100);
		}
	};
	return self;
});
var BeatMarker = Container.expand(function () {
	var self = Container.call(this);
	var markerGraphics = self.attachAsset('beat_marker', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 8;
	self.intensity = 1.0;
	self.update = function () {
		self.y += self.speed;
		// Fade out as it moves
		markerGraphics.alpha = Math.max(0, 1 - self.y / 2732);
	};
	return self;
});
var Note = Container.expand(function () {
	var self = Container.call(this);
	var noteGraphics = self.attachAsset('note', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 8;
	self.collected = false;
	self.beatTime = 0;
	self.update = function () {
		self.y += self.speed;
		// Pulsing effect
		var pulse = 0.8 + Math.sin(LK.ticks * 0.2) * 0.2;
		noteGraphics.scaleX = pulse;
		noteGraphics.scaleY = pulse;
	};
	return self;
});
var Obstacle = Container.expand(function () {
	var self = Container.call(this);
	var obstacleGraphics = self.attachAsset('obstacle', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 8;
	self.wasHit = false;
	self.update = function () {
		self.y += self.speed;
	};
	return self;
});
var PlayerBullet = Container.expand(function () {
	var self = Container.call(this);
	var bulletGraphics = self.attachAsset('beat_marker', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	bulletGraphics.tint = 0x00FF00; // Green bullets
	bulletGraphics.rotation = Math.PI;
	self.speed = 15;
	self.update = function () {
		self.y -= self.speed;
	};
	return self;
});
var Ship = Container.expand(function () {
	var self = Container.call(this);
	var shipGraphics = self.attachAsset('ship', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = shipSpeed;
	self.targetX = 1024;
	self.isAlive = true;
	self.update = function () {
		if (!self.isAlive) return;
		// Smooth movement towards target
		var diff = self.targetX - self.x;
		self.x += diff * 0.15;
		// Keep ship in bounds
		if (self.x < 100) self.x = 100;
		if (self.x > 1948) self.x = 1948;
	};
	return self;
});
var TunnelSegment = Container.expand(function () {
	var self = Container.call(this);
	var tunnelGraphics = self.attachAsset('tunnel', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 8;
	self.update = function () {
		self.y += self.speed;
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x0a0a0a
});
/**** 
* Game Code
****/ 
// Game variables
var ship;
var tunnelSegments = [];
var obstacles = [];
var notes = [];
var beatMarkers = [];
var combo = 0;
var beatTimer = 0;
var beatInterval = 30; // frames between beats (60fps / 2 = 30 frames = 0.5 seconds)
var gameSpeed = 8;
var shipSpeed = 8; // Initial ship speed
var shipLane = 1; // 0 = left, 1 = center, 2 = right
var lanes = [512, 1024, 1536];
var obstacleHits = 0; // Counter for obstacle hits
var immunityActive = false; // Immunity power state
var immunityTimer = 0; // Timer for immunity duration
var immunityDuration = 600; // 10 seconds at 60fps
var alienShip = null; // Alien boss ship
var playerBullets = []; // Player bullets
var alienLasers = []; // Alien lasers
var alienSpawned = false; // Track if alien has been spawned
// UI Elements
var scoreTxt = new Text2('Score: 0', {
	size: 60,
	fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var comboTxt = new Text2('Combo: 0', {
	size: 50,
	fill: 0xFFA502
});
comboTxt.anchor.set(0, 0);
comboTxt.x = 50;
comboTxt.y = 150;
LK.gui.addChild(comboTxt);
var immunityTxt = new Text2('', {
	size: 45,
	fill: 0x00D2FF
});
immunityTxt.anchor.set(0, 0);
immunityTxt.x = 50;
immunityTxt.y = 220;
LK.gui.addChild(immunityTxt);
// Initialize ship
ship = game.addChild(new Ship());
ship.x = lanes[shipLane];
ship.y = 2400;
// Create initial tunnel segments
function createTunnelSegment(y) {
	var segment = new TunnelSegment();
	segment.x = 1024;
	segment.y = y;
	segment.alpha = 0.3;
	return game.addChild(segment);
}
// Initialize tunnel
for (var i = 0; i < 30; i++) {
	tunnelSegments.push(createTunnelSegment(i * 100 - 500));
}
// Create obstacle
function createObstacle(lane, y) {
	var obstacle = new Obstacle();
	obstacle.x = lanes[lane];
	obstacle.y = y;
	obstacles.push(obstacle);
	return game.addChild(obstacle);
}
// Create note
function createNote(lane, y, beatTime) {
	var note = new Note();
	note.x = lanes[lane];
	note.y = y;
	note.beatTime = beatTime;
	notes.push(note);
	return game.addChild(note);
}
// Create beat marker
function createBeatMarker() {
	var marker = new BeatMarker();
	marker.x = ship.x;
	marker.y = ship.y + 100; // Spawn from back of ship instead of front
	beatMarkers.push(marker);
	return game.addChild(marker);
}
// Create player bullet
function createPlayerBullet(x, y) {
	var bullet = new PlayerBullet();
	bullet.x = x;
	bullet.y = y;
	playerBullets.push(bullet);
	return game.addChild(bullet);
}
// Create alien laser
function createAlienLaser(x, y) {
	var laser = new AlienLaser();
	laser.x = x;
	laser.y = y;
	alienLasers.push(laser);
	return game.addChild(laser);
}
// Create alien ship
function createAlienShip() {
	alienShip = new AlienShip();
	alienShip.x = 1024;
	alienShip.y = 400;
	return game.addChild(alienShip);
}
// Handle input for lane switching
function handleInput(targetLane) {
	if (targetLane >= 0 && targetLane <= 2) {
		shipLane = targetLane;
		ship.targetX = lanes[shipLane];
	}
}
// Touch controls
game.down = function (x, y, obj) {
	// Divide screen into three lanes for touch control
	if (x < 683) {
		handleInput(0); // Left lane
	} else if (x < 1365) {
		handleInput(1); // Center lane
	} else {
		handleInput(2); // Right lane
	}
	// Check if touching on beat
	checkBeatTiming();
	// Fire bullet if alien ship exists
	if (alienShip && ship.isAlive) {
		createPlayerBullet(ship.x, ship.y - 50);
	}
};
function checkBeatTiming() {
	var beatAccuracy = Math.abs(beatTimer % beatInterval - beatInterval / 2);
	var maxAccuracy = beatInterval * 0.3; // 30% tolerance
	if (beatAccuracy <= maxAccuracy) {
		// Good timing
		tween(ship, {
			scaleX: 1.2,
			scaleY: 1.2
		}, {
			duration: 100
		});
		tween(ship, {
			scaleX: 1.0,
			scaleY: 1.0
		}, {
			duration: 100
		});
	} else {
		// Bad timing
		LK.getSound('miss').play();
	}
	updateUI();
}
function updateUI() {
	scoreTxt.setText('Score: ' + LK.getScore());
	comboTxt.setText('Combo: ' + combo);
	if (immunityActive) {
		var remainingSeconds = Math.ceil(immunityTimer / 60);
		immunityTxt.setText('IMMUNITY: ' + remainingSeconds + 's');
	} else {
		immunityTxt.setText('');
	}
}
// Spawn content based on beat
function spawnContent() {
	if (beatTimer % beatInterval === 0) {
		// Create beat marker
		createBeatMarker();
		// Randomly spawn obstacles and notes
		var spawnChance = Math.random();
		// Check if there's enough space before spawning obstacle
		var canSpawnObstacle = true;
		for (var i = 0; i < obstacles.length; i++) {
			if (obstacles[i].y < 1000) {
				// Check if any obstacle is too close to top - increased distance
				canSpawnObstacle = false;
				break;
			}
		}
		if (spawnChance < 0.15 && canSpawnObstacle && LK.getScore() < 10000) {
			// Reduced from 0.3 to 0.15
			// Spawn obstacle (only if score is below 10000)
			var obstacleLane = Math.floor(Math.random() * 3);
			createObstacle(obstacleLane, -100);
		}
		// Check if there's enough space before spawning note
		var canSpawnNote = true;
		for (var i = 0; i < notes.length; i++) {
			if (notes[i].y < 800) {
				// Check if any note is too close to top
				canSpawnNote = false;
				break;
			}
		}
		if (spawnChance > 0.6 && canSpawnNote) {
			// Spawn note
			var noteLane = Math.floor(Math.random() * 3);
			createNote(noteLane, -100, LK.ticks + 300);
		}
	}
}
// Game update loop
game.update = function () {
	if (!ship.isAlive) return;
	beatTimer++;
	// Spawn new content
	spawnContent();
	// Manage tunnel segments
	for (var i = tunnelSegments.length - 1; i >= 0; i--) {
		var segment = tunnelSegments[i];
		if (segment.y > 2800) {
			segment.destroy();
			tunnelSegments.splice(i, 1);
			// Add new segment at the top
			tunnelSegments.push(createTunnelSegment(-200));
		}
	}
	// Check obstacle collisions
	for (var j = obstacles.length - 1; j >= 0; j--) {
		var obstacle = obstacles[j];
		if (obstacle.y > 2800) {
			obstacle.destroy();
			obstacles.splice(j, 1);
			continue;
		}
		if (!obstacle.wasHit && obstacle.intersects(ship)) {
			obstacle.wasHit = true;
			// Check if immunity is active
			if (!immunityActive) {
				obstacleHits++; // Increment obstacle hit counter
				combo = 0;
				LK.effects.flashScreen(0xff4757, 500);
				LK.getSound('miss').play();
				// Reduce score
				LK.setScore(Math.max(0, LK.getScore() - 50));
			} else {
				// Immunity protects from damage - just visual feedback
				LK.effects.flashScreen(0x00D2FF, 200);
			}
			updateUI();
			// Check if hit 3 obstacles - game over with explosion
			if (obstacleHits >= 3) {
				ship.isAlive = false;
				// Ship explosion effect
				tween(ship, {
					scaleX: 2,
					scaleY: 2,
					alpha: 0,
					rotation: Math.PI * 2
				}, {
					duration: 1000,
					onFinish: function onFinish() {
						LK.showGameOver();
					}
				});
			}
			// Check game over condition
			if (LK.getScore() <= -100) {
				ship.isAlive = false;
				LK.showGameOver();
			}
		}
	}
	// Check note collections
	for (var k = notes.length - 1; k >= 0; k--) {
		var note = notes[k];
		if (note.y > 2800) {
			// Reset combo when note is missed (not collected)
			if (!note.collected) {
				combo = 0;
				updateUI();
			}
			note.destroy();
			notes.splice(k, 1);
			continue;
		}
		if (!note.collected && note.intersects(ship)) {
			note.collected = true;
			// Check timing accuracy
			var timingAccuracy = Math.abs(beatTimer % beatInterval - beatInterval / 2);
			var maxAccuracy = beatInterval * 0.4;
			if (timingAccuracy <= maxAccuracy) {
				// Perfect timing - only time combo increases
				combo++;
				LK.setScore(LK.getScore() + 20 * combo);
				LK.getSound('notamusical').play();
				// Increase ship speed
				shipSpeed += 0.1;
				ship.speed = shipSpeed;
				// Activate immunity power every 20 combo points
				if (combo % 20 === 0 && combo > 0) {
					immunityActive = true;
					immunityTimer = immunityDuration;
					// Visual feedback for immunity activation
					tween(ship, {
						tint: 0x00D2FF
					}, {
						duration: 300
					});
				}
				// Visual feedback
				tween(note, {
					scaleX: 2,
					scaleY: 2,
					alpha: 0
				}, {
					duration: 200
				});
			} else {
				// Poor timing - reset combo when missing note timing
				combo = 0;
			}
			note.destroy();
			notes.splice(k, 1);
			updateUI();
		}
	}
	// Update beat markers to follow ship and clean up
	for (var l = beatMarkers.length - 1; l >= 0; l--) {
		var marker = beatMarkers[l];
		// Make beat marker follow ship's X position
		marker.x = ship.x;
		if (marker.y > 2800 || marker.alpha <= 0) {
			marker.destroy();
			beatMarkers.splice(l, 1);
		}
	}
	// Increase difficulty over time
	if (LK.ticks % 1800 === 0) {
		// Every 30 seconds
		gameSpeed += 0.5;
		beatInterval = Math.max(20, beatInterval - 1);
		// Update speeds for all moving objects
		for (var m = 0; m < tunnelSegments.length; m++) {
			tunnelSegments[m].speed = gameSpeed;
		}
		for (var n = 0; n < obstacles.length; n++) {
			obstacles[n].speed = gameSpeed;
		}
		for (var o = 0; o < notes.length; o++) {
			notes[o].speed = gameSpeed;
		}
		for (var p = 0; p < beatMarkers.length; p++) {
			beatMarkers[p].speed = gameSpeed;
		}
	}
	// Tunnel pulsing effect based on beat
	var beatPulse = Math.sin(beatTimer % beatInterval / beatInterval * Math.PI * 2);
	for (var q = 0; q < tunnelSegments.length; q++) {
		tunnelSegments[q].alpha = 0.2 + Math.abs(beatPulse) * 0.3;
	}
	// Manage immunity timer
	if (immunityActive) {
		immunityTimer--;
		if (immunityTimer <= 0) {
			immunityActive = false;
			// Remove immunity visual effect
			tween(ship, {
				tint: 0xFFFFFF
			}, {
				duration: 300
			});
		}
	}
	// Spawn alien ship at 10000 points
	if (LK.getScore() >= 10000 && !alienSpawned) {
		alienSpawned = true;
		createAlienShip();
	}
	// Manage player bullets
	for (var r = playerBullets.length - 1; r >= 0; r--) {
		var bullet = playerBullets[r];
		if (bullet.y < -100) {
			bullet.destroy();
			playerBullets.splice(r, 1);
			continue;
		}
		// Check collision with alien ship
		if (alienShip && bullet.intersects(alienShip)) {
			bullet.destroy();
			playerBullets.splice(r, 1);
			alienShip.health--;
			// Flash alien ship when hit
			tween(alienShip, {
				tint: 0xFFFFFF
			}, {
				duration: 100
			});
			tween(alienShip, {
				tint: 0xFF0000
			}, {
				duration: 100
			});
			// Destroy alien ship when health reaches 0
			if (alienShip.health <= 0) {
				tween(alienShip, {
					scaleX: 2,
					scaleY: 2,
					alpha: 0,
					rotation: Math.PI * 2
				}, {
					duration: 1000,
					onFinish: function onFinish() {
						if (alienShip) {
							alienShip.destroy();
							alienShip = null;
						}
						// Show victory when alien ship is destroyed
						LK.showYouWin();
					}
				});
				LK.setScore(LK.getScore() + 1000);
				updateUI();
			}
		}
	}
	// Manage alien lasers
	for (var s = alienLasers.length - 1; s >= 0; s--) {
		var laser = alienLasers[s];
		if (laser.y > 2800) {
			laser.destroy();
			alienLasers.splice(s, 1);
			continue;
		}
		// Check collision with player ship
		if (laser.intersects(ship) && ship.isAlive) {
			laser.destroy();
			alienLasers.splice(s, 1);
			if (!immunityActive) {
				obstacleHits++;
				combo = 0;
				LK.effects.flashScreen(0xff4757, 500);
				LK.getSound('miss').play();
				LK.setScore(Math.max(0, LK.getScore() - 50));
				// Check if hit 3 times - game over
				if (obstacleHits >= 3) {
					ship.isAlive = false;
					tween(ship, {
						scaleX: 2,
						scaleY: 2,
						alpha: 0,
						rotation: Math.PI * 2
					}, {
						duration: 1000,
						onFinish: function onFinish() {
							LK.showGameOver();
						}
					});
				}
			} else {
				LK.effects.flashScreen(0x00D2FF, 200);
			}
			updateUI();
		}
	}
};
// Start background music
LK.playMusic('background'); /**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
/**** 
* Classes
****/ 
var AlienLaser = Container.expand(function () {
	var self = Container.call(this);
	var laserGraphics = self.attachAsset('beat_marker', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	laserGraphics.tint = 0xFF0000; // Red lasers
	self.speed = 10;
	self.update = function () {
		self.y += self.speed;
	};
	return self;
});
var AlienShip = Container.expand(function () {
	var self = Container.call(this);
	var alienGraphics = self.attachAsset('ship', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	alienGraphics.tint = 0xFF0000; // Red tint for alien ship
	self.health = 5;
	self.fireTimer = 0;
	self.fireInterval = 60; // Fire every second
	self.moveDirection = 1;
	self.speed = 2;
	self.update = function () {
		// Move side to side
		self.x += self.moveDirection * self.speed;
		if (self.x <= 200 || self.x >= 1848) {
			self.moveDirection *= -1;
		}
		// Fire lasers
		self.fireTimer++;
		if (self.fireTimer >= self.fireInterval) {
			self.fireTimer = 0;
			createAlienLaser(self.x, self.y + 100);
		}
	};
	return self;
});
var BeatMarker = Container.expand(function () {
	var self = Container.call(this);
	var markerGraphics = self.attachAsset('beat_marker', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 8;
	self.intensity = 1.0;
	self.update = function () {
		self.y += self.speed;
		// Fade out as it moves
		markerGraphics.alpha = Math.max(0, 1 - self.y / 2732);
	};
	return self;
});
var Note = Container.expand(function () {
	var self = Container.call(this);
	var noteGraphics = self.attachAsset('note', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 8;
	self.collected = false;
	self.beatTime = 0;
	self.update = function () {
		self.y += self.speed;
		// Pulsing effect
		var pulse = 0.8 + Math.sin(LK.ticks * 0.2) * 0.2;
		noteGraphics.scaleX = pulse;
		noteGraphics.scaleY = pulse;
	};
	return self;
});
var Obstacle = Container.expand(function () {
	var self = Container.call(this);
	var obstacleGraphics = self.attachAsset('obstacle', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 8;
	self.wasHit = false;
	self.update = function () {
		self.y += self.speed;
	};
	return self;
});
var PlayerBullet = Container.expand(function () {
	var self = Container.call(this);
	var bulletGraphics = self.attachAsset('beat_marker', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	bulletGraphics.tint = 0x00FF00; // Green bullets
	bulletGraphics.rotation = Math.PI;
	self.speed = 15;
	self.update = function () {
		self.y -= self.speed;
	};
	return self;
});
var Ship = Container.expand(function () {
	var self = Container.call(this);
	var shipGraphics = self.attachAsset('ship', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = shipSpeed;
	self.targetX = 1024;
	self.isAlive = true;
	self.update = function () {
		if (!self.isAlive) return;
		// Smooth movement towards target
		var diff = self.targetX - self.x;
		self.x += diff * 0.15;
		// Keep ship in bounds
		if (self.x < 100) self.x = 100;
		if (self.x > 1948) self.x = 1948;
	};
	return self;
});
var TunnelSegment = Container.expand(function () {
	var self = Container.call(this);
	var tunnelGraphics = self.attachAsset('tunnel', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 8;
	self.update = function () {
		self.y += self.speed;
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x0a0a0a
});
/**** 
* Game Code
****/ 
// Game variables
var ship;
var tunnelSegments = [];
var obstacles = [];
var notes = [];
var beatMarkers = [];
var combo = 0;
var beatTimer = 0;
var beatInterval = 30; // frames between beats (60fps / 2 = 30 frames = 0.5 seconds)
var gameSpeed = 8;
var shipSpeed = 8; // Initial ship speed
var shipLane = 1; // 0 = left, 1 = center, 2 = right
var lanes = [512, 1024, 1536];
var obstacleHits = 0; // Counter for obstacle hits
var immunityActive = false; // Immunity power state
var immunityTimer = 0; // Timer for immunity duration
var immunityDuration = 600; // 10 seconds at 60fps
var alienShip = null; // Alien boss ship
var playerBullets = []; // Player bullets
var alienLasers = []; // Alien lasers
var alienSpawned = false; // Track if alien has been spawned
// UI Elements
var scoreTxt = new Text2('Score: 0', {
	size: 60,
	fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var comboTxt = new Text2('Combo: 0', {
	size: 50,
	fill: 0xFFA502
});
comboTxt.anchor.set(0, 0);
comboTxt.x = 50;
comboTxt.y = 150;
LK.gui.addChild(comboTxt);
var immunityTxt = new Text2('', {
	size: 45,
	fill: 0x00D2FF
});
immunityTxt.anchor.set(0, 0);
immunityTxt.x = 50;
immunityTxt.y = 220;
LK.gui.addChild(immunityTxt);
// Initialize ship
ship = game.addChild(new Ship());
ship.x = lanes[shipLane];
ship.y = 2400;
// Create initial tunnel segments
function createTunnelSegment(y) {
	var segment = new TunnelSegment();
	segment.x = 1024;
	segment.y = y;
	segment.alpha = 0.3;
	return game.addChild(segment);
}
// Initialize tunnel
for (var i = 0; i < 30; i++) {
	tunnelSegments.push(createTunnelSegment(i * 100 - 500));
}
// Create obstacle
function createObstacle(lane, y) {
	var obstacle = new Obstacle();
	obstacle.x = lanes[lane];
	obstacle.y = y;
	obstacles.push(obstacle);
	return game.addChild(obstacle);
}
// Create note
function createNote(lane, y, beatTime) {
	var note = new Note();
	note.x = lanes[lane];
	note.y = y;
	note.beatTime = beatTime;
	notes.push(note);
	return game.addChild(note);
}
// Create beat marker
function createBeatMarker() {
	var marker = new BeatMarker();
	marker.x = ship.x;
	marker.y = ship.y + 100; // Spawn from back of ship instead of front
	beatMarkers.push(marker);
	return game.addChild(marker);
}
// Create player bullet
function createPlayerBullet(x, y) {
	var bullet = new PlayerBullet();
	bullet.x = x;
	bullet.y = y;
	playerBullets.push(bullet);
	return game.addChild(bullet);
}
// Create alien laser
function createAlienLaser(x, y) {
	var laser = new AlienLaser();
	laser.x = x;
	laser.y = y;
	alienLasers.push(laser);
	return game.addChild(laser);
}
// Create alien ship
function createAlienShip() {
	alienShip = new AlienShip();
	alienShip.x = 1024;
	alienShip.y = 400;
	return game.addChild(alienShip);
}
// Handle input for lane switching
function handleInput(targetLane) {
	if (targetLane >= 0 && targetLane <= 2) {
		shipLane = targetLane;
		ship.targetX = lanes[shipLane];
	}
}
// Touch controls
game.down = function (x, y, obj) {
	// Divide screen into three lanes for touch control
	if (x < 683) {
		handleInput(0); // Left lane
	} else if (x < 1365) {
		handleInput(1); // Center lane
	} else {
		handleInput(2); // Right lane
	}
	// Check if touching on beat
	checkBeatTiming();
	// Fire bullet if alien ship exists
	if (alienShip && ship.isAlive) {
		createPlayerBullet(ship.x, ship.y - 50);
	}
};
function checkBeatTiming() {
	var beatAccuracy = Math.abs(beatTimer % beatInterval - beatInterval / 2);
	var maxAccuracy = beatInterval * 0.3; // 30% tolerance
	if (beatAccuracy <= maxAccuracy) {
		// Good timing
		tween(ship, {
			scaleX: 1.2,
			scaleY: 1.2
		}, {
			duration: 100
		});
		tween(ship, {
			scaleX: 1.0,
			scaleY: 1.0
		}, {
			duration: 100
		});
	} else {
		// Bad timing
		LK.getSound('miss').play();
	}
	updateUI();
}
function updateUI() {
	scoreTxt.setText('Score: ' + LK.getScore());
	comboTxt.setText('Combo: ' + combo);
	if (immunityActive) {
		var remainingSeconds = Math.ceil(immunityTimer / 60);
		immunityTxt.setText('IMMUNITY: ' + remainingSeconds + 's');
	} else {
		immunityTxt.setText('');
	}
}
// Spawn content based on beat
function spawnContent() {
	if (beatTimer % beatInterval === 0) {
		// Create beat marker
		createBeatMarker();
		// Randomly spawn obstacles and notes
		var spawnChance = Math.random();
		// Check if there's enough space before spawning obstacle
		var canSpawnObstacle = true;
		for (var i = 0; i < obstacles.length; i++) {
			if (obstacles[i].y < 1000) {
				// Check if any obstacle is too close to top - increased distance
				canSpawnObstacle = false;
				break;
			}
		}
		if (spawnChance < 0.15 && canSpawnObstacle && LK.getScore() < 10000) {
			// Reduced from 0.3 to 0.15
			// Spawn obstacle (only if score is below 10000)
			var obstacleLane = Math.floor(Math.random() * 3);
			createObstacle(obstacleLane, -100);
		}
		// Check if there's enough space before spawning note
		var canSpawnNote = true;
		for (var i = 0; i < notes.length; i++) {
			if (notes[i].y < 800) {
				// Check if any note is too close to top
				canSpawnNote = false;
				break;
			}
		}
		if (spawnChance > 0.6 && canSpawnNote) {
			// Spawn note
			var noteLane = Math.floor(Math.random() * 3);
			createNote(noteLane, -100, LK.ticks + 300);
		}
	}
}
// Game update loop
game.update = function () {
	if (!ship.isAlive) return;
	beatTimer++;
	// Spawn new content
	spawnContent();
	// Manage tunnel segments
	for (var i = tunnelSegments.length - 1; i >= 0; i--) {
		var segment = tunnelSegments[i];
		if (segment.y > 2800) {
			segment.destroy();
			tunnelSegments.splice(i, 1);
			// Add new segment at the top
			tunnelSegments.push(createTunnelSegment(-200));
		}
	}
	// Check obstacle collisions
	for (var j = obstacles.length - 1; j >= 0; j--) {
		var obstacle = obstacles[j];
		if (obstacle.y > 2800) {
			obstacle.destroy();
			obstacles.splice(j, 1);
			continue;
		}
		if (!obstacle.wasHit && obstacle.intersects(ship)) {
			obstacle.wasHit = true;
			// Check if immunity is active
			if (!immunityActive) {
				obstacleHits++; // Increment obstacle hit counter
				combo = 0;
				LK.effects.flashScreen(0xff4757, 500);
				LK.getSound('miss').play();
				// Reduce score
				LK.setScore(Math.max(0, LK.getScore() - 50));
			} else {
				// Immunity protects from damage - just visual feedback
				LK.effects.flashScreen(0x00D2FF, 200);
			}
			updateUI();
			// Check if hit 3 obstacles - game over with explosion
			if (obstacleHits >= 3) {
				ship.isAlive = false;
				// Ship explosion effect
				tween(ship, {
					scaleX: 2,
					scaleY: 2,
					alpha: 0,
					rotation: Math.PI * 2
				}, {
					duration: 1000,
					onFinish: function onFinish() {
						LK.showGameOver();
					}
				});
			}
			// Check game over condition
			if (LK.getScore() <= -100) {
				ship.isAlive = false;
				LK.showGameOver();
			}
		}
	}
	// Check note collections
	for (var k = notes.length - 1; k >= 0; k--) {
		var note = notes[k];
		if (note.y > 2800) {
			// Reset combo when note is missed (not collected)
			if (!note.collected) {
				combo = 0;
				updateUI();
			}
			note.destroy();
			notes.splice(k, 1);
			continue;
		}
		if (!note.collected && note.intersects(ship)) {
			note.collected = true;
			// Check timing accuracy
			var timingAccuracy = Math.abs(beatTimer % beatInterval - beatInterval / 2);
			var maxAccuracy = beatInterval * 0.4;
			if (timingAccuracy <= maxAccuracy) {
				// Perfect timing - only time combo increases
				combo++;
				LK.setScore(LK.getScore() + 20 * combo);
				LK.getSound('notamusical').play();
				// Increase ship speed
				shipSpeed += 0.1;
				ship.speed = shipSpeed;
				// Activate immunity power every 20 combo points
				if (combo % 20 === 0 && combo > 0) {
					immunityActive = true;
					immunityTimer = immunityDuration;
					// Visual feedback for immunity activation
					tween(ship, {
						tint: 0x00D2FF
					}, {
						duration: 300
					});
				}
				// Visual feedback
				tween(note, {
					scaleX: 2,
					scaleY: 2,
					alpha: 0
				}, {
					duration: 200
				});
			} else {
				// Poor timing - reset combo when missing note timing
				combo = 0;
			}
			note.destroy();
			notes.splice(k, 1);
			updateUI();
		}
	}
	// Update beat markers to follow ship and clean up
	for (var l = beatMarkers.length - 1; l >= 0; l--) {
		var marker = beatMarkers[l];
		// Make beat marker follow ship's X position
		marker.x = ship.x;
		if (marker.y > 2800 || marker.alpha <= 0) {
			marker.destroy();
			beatMarkers.splice(l, 1);
		}
	}
	// Increase difficulty over time
	if (LK.ticks % 1800 === 0) {
		// Every 30 seconds
		gameSpeed += 0.5;
		beatInterval = Math.max(20, beatInterval - 1);
		// Update speeds for all moving objects
		for (var m = 0; m < tunnelSegments.length; m++) {
			tunnelSegments[m].speed = gameSpeed;
		}
		for (var n = 0; n < obstacles.length; n++) {
			obstacles[n].speed = gameSpeed;
		}
		for (var o = 0; o < notes.length; o++) {
			notes[o].speed = gameSpeed;
		}
		for (var p = 0; p < beatMarkers.length; p++) {
			beatMarkers[p].speed = gameSpeed;
		}
	}
	// Tunnel pulsing effect based on beat
	var beatPulse = Math.sin(beatTimer % beatInterval / beatInterval * Math.PI * 2);
	for (var q = 0; q < tunnelSegments.length; q++) {
		tunnelSegments[q].alpha = 0.2 + Math.abs(beatPulse) * 0.3;
	}
	// Manage immunity timer
	if (immunityActive) {
		immunityTimer--;
		if (immunityTimer <= 0) {
			immunityActive = false;
			// Remove immunity visual effect
			tween(ship, {
				tint: 0xFFFFFF
			}, {
				duration: 300
			});
		}
	}
	// Spawn alien ship at 10000 points
	if (LK.getScore() >= 10000 && !alienSpawned) {
		alienSpawned = true;
		createAlienShip();
	}
	// Manage player bullets
	for (var r = playerBullets.length - 1; r >= 0; r--) {
		var bullet = playerBullets[r];
		if (bullet.y < -100) {
			bullet.destroy();
			playerBullets.splice(r, 1);
			continue;
		}
		// Check collision with alien ship
		if (alienShip && bullet.intersects(alienShip)) {
			bullet.destroy();
			playerBullets.splice(r, 1);
			alienShip.health--;
			// Flash alien ship when hit
			tween(alienShip, {
				tint: 0xFFFFFF
			}, {
				duration: 100
			});
			tween(alienShip, {
				tint: 0xFF0000
			}, {
				duration: 100
			});
			// Destroy alien ship when health reaches 0
			if (alienShip.health <= 0) {
				tween(alienShip, {
					scaleX: 2,
					scaleY: 2,
					alpha: 0,
					rotation: Math.PI * 2
				}, {
					duration: 1000,
					onFinish: function onFinish() {
						if (alienShip) {
							alienShip.destroy();
							alienShip = null;
						}
						// Show victory when alien ship is destroyed
						LK.showYouWin();
					}
				});
				LK.setScore(LK.getScore() + 1000);
				updateUI();
			}
		}
	}
	// Manage alien lasers
	for (var s = alienLasers.length - 1; s >= 0; s--) {
		var laser = alienLasers[s];
		if (laser.y > 2800) {
			laser.destroy();
			alienLasers.splice(s, 1);
			continue;
		}
		// Check collision with player ship
		if (laser.intersects(ship) && ship.isAlive) {
			laser.destroy();
			alienLasers.splice(s, 1);
			if (!immunityActive) {
				obstacleHits++;
				combo = 0;
				LK.effects.flashScreen(0xff4757, 500);
				LK.getSound('miss').play();
				LK.setScore(Math.max(0, LK.getScore() - 50));
				// Check if hit 3 times - game over
				if (obstacleHits >= 3) {
					ship.isAlive = false;
					tween(ship, {
						scaleX: 2,
						scaleY: 2,
						alpha: 0,
						rotation: Math.PI * 2
					}, {
						duration: 1000,
						onFinish: function onFinish() {
							LK.showGameOver();
						}
					});
				}
			} else {
				LK.effects.flashScreen(0x00D2FF, 200);
			}
			updateUI();
		}
	}
};
// Start background music
LK.playMusic('background');