/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/**** 
* Classes
****/ 
var EnemySubmarine = Container.expand(function () {
	var self = Container.call(this);
	var enemyGraphics = self.attachAsset('enemySubmarine', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 3;
	self.points = 10;
	self.shootTimer = 0;
	self.shootInterval = 300; // Shoot every 5 seconds
	self.update = function () {
		self.y += self.speed;
		self.shootTimer++;
	};
	return self;
});
var EnemyTorpedo = Container.expand(function () {
	var self = Container.call(this);
	var torpedoGraphics = self.attachAsset('enemyTorpedo', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speedX = 0;
	self.speedY = 0;
	self.update = function () {
		self.x += self.speedX;
		self.y += self.speedY;
	};
	return self;
});
var Explosion = Container.expand(function () {
	var self = Container.call(this);
	var explosionGraphics = self.attachAsset('explosion', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.lifetime = 0;
	self.maxLifetime = 30; // 30 frames = 0.5 seconds
	self.update = function () {
		self.lifetime++;
		// Scale up and fade out over time
		var progress = self.lifetime / self.maxLifetime;
		explosionGraphics.scaleX = 1 + progress * 2;
		explosionGraphics.scaleY = 1 + progress * 2;
		explosionGraphics.alpha = 1 - progress;
		// Change color from orange to red to dark red
		if (progress < 0.3) {
			explosionGraphics.tint = 0xFF4500; // Orange
		} else if (progress < 0.7) {
			explosionGraphics.tint = 0xFF0000; // Red
		} else {
			explosionGraphics.tint = 0x8B0000; // Dark red
		}
	};
	return self;
});
var SeaCreature = Container.expand(function () {
	var self = Container.call(this);
	var creatureGraphics = self.attachAsset('seaCreature', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 4;
	self.points = 20;
	self.update = function () {
		self.y += self.speed;
		// Add slight horizontal movement for more dynamic behavior
		self.x += Math.sin(LK.ticks * 0.05) * 0.5;
	};
	return self;
});
var Submarine = Container.expand(function () {
	var self = Container.call(this);
	var submarineGraphics = self.attachAsset('submarine', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	return self;
});
var Torpedo = Container.expand(function () {
	var self = Container.call(this);
	var torpedoGraphics = self.attachAsset('torpedo', {
		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: 0x000080
});
/**** 
* Game Code
****/ 
// Add underwater background
var background = game.addChild(LK.getAsset('underwaterBackground', {
	anchorX: 0,
	anchorY: 0,
	x: 0,
	y: 0
}));
// Game variables
var submarine;
var torpedoes = [];
var enemyTorpedoes = [];
var enemies = [];
var dragNode = null;
var spawnTimer = 0;
var difficultyLevel = 1;
var enemySpawnRate = 120; // Initial spawn rate (ticks between spawns)
// Create submarine
submarine = game.addChild(new Submarine());
submarine.x = 2048 / 2;
submarine.y = 2732 - 200;
// Create score display
var scoreTxt = new Text2('0', {
	size: 100,
	fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
scoreTxt.setText(LK.getScore());
// Create high score display
var highScore = storage.highScore || 0;
var highScoreTxt = new Text2('Best: ' + highScore, {
	size: 60,
	fill: 0xFFFF00
});
highScoreTxt.anchor.set(1, 0);
highScoreTxt.y = 120;
LK.gui.topRight.addChild(highScoreTxt);
// Handle submarine movement with soft swipe control
var targetX = submarine.x;
var targetY = submarine.y;
var swipeStartX = 0;
var swipeStartY = 0;
var isSwipping = false;
function handleMove(x, y, obj) {
	if (dragNode && isSwipping) {
		// Calculate swipe delta
		var deltaX = x - swipeStartX;
		var deltaY = y - swipeStartY;
		// Update target position based on swipe delta
		targetX = Math.max(60, Math.min(2048 - 60, targetX + deltaX * 0.5));
		targetY = Math.max(100, Math.min(2732 - 100, targetY + deltaY * 0.5));
		// Update swipe start position for continuous movement
		swipeStartX = x;
		swipeStartY = y;
	}
}
game.move = handleMove;
game.down = function (x, y, obj) {
	dragNode = submarine;
	swipeStartX = x;
	swipeStartY = y;
	isSwipping = true;
};
game.up = function (x, y, obj) {
	dragNode = null;
	isSwipping = false;
};
// Spawn enemy function
function spawnEnemy() {
	var enemyType = Math.random();
	var enemy;
	if (enemyType < 0.6) {
		enemy = new EnemySubmarine();
	} else {
		enemy = new SeaCreature();
	}
	enemy.x = Math.random() * (2048 - 100) + 50;
	enemy.y = -50;
	enemy.lastY = enemy.y;
	enemy.lastIntersecting = false;
	enemy.hitCount = 0; // Track hits taken, enemy dies after 2 hits
	enemies.push(enemy);
	game.addChild(enemy);
}
// Main game update loop
game.update = function () {
	// Smooth submarine movement toward target position
	var lerpSpeed = 0.15;
	submarine.x += (targetX - submarine.x) * lerpSpeed;
	submarine.y += (targetY - submarine.y) * lerpSpeed;
	spawnTimer++;
	// Spawn enemies based on difficulty
	if (spawnTimer >= enemySpawnRate) {
		spawnEnemy();
		spawnTimer = 0;
		// Increase difficulty over time
		if (LK.ticks % 1800 == 0) {
			// Every 30 seconds
			difficultyLevel++;
			enemySpawnRate = Math.max(30, enemySpawnRate - 10);
		}
	}
	// Fire torpedoes automatically
	if (LK.ticks % 60 == 0) {
		var torpedo = new Torpedo();
		torpedo.x = submarine.x;
		torpedo.y = submarine.y - 40;
		torpedo.lastY = torpedo.y;
		torpedo.lastIntersecting = false;
		torpedoes.push(torpedo);
		game.addChild(torpedo);
		LK.getSound('torpedo_fire').play();
	}
	// Update and check torpedoes
	for (var t = torpedoes.length - 1; t >= 0; t--) {
		var torpedo = torpedoes[t];
		// Remove torpedoes that go off-screen
		if (torpedo.lastY >= -50 && torpedo.y < -50) {
			torpedo.destroy();
			torpedoes.splice(t, 1);
			continue;
		}
		// Check torpedo-enemy collisions
		var torpedoHit = false;
		for (var e = enemies.length - 1; e >= 0; e--) {
			var enemy = enemies[e];
			var currentIntersecting = torpedo.intersects(enemy);
			if (!torpedo.lastIntersecting && currentIntersecting) {
				// Torpedo hit enemy
				enemy.hitCount++;
				// Create explosion effect
				var explosion = new Explosion();
				explosion.x = enemy.x;
				explosion.y = enemy.y;
				explosion.lastLifetime = 0;
				game.addChild(explosion);
				LK.getSound('explosion').play();
				// Remove torpedo immediately
				torpedo.destroy();
				torpedoes.splice(t, 1);
				// Check if enemy should die (after 2 hits)
				if (enemy.hitCount >= 2) {
					LK.setScore(LK.getScore() + enemy.points);
					scoreTxt.setText(LK.getScore());
					enemy.destroy();
					enemies.splice(e, 1);
				}
				torpedoHit = true;
				break;
			}
		}
		if (!torpedoHit) {
			torpedo.lastY = torpedo.y;
			torpedo.lastIntersecting = false;
		}
	}
	// Update and check enemies
	for (var e = enemies.length - 1; e >= 0; e--) {
		var enemy = enemies[e];
		// Remove enemies that go off-screen
		if (enemy.lastY <= 2732 + 50 && enemy.y > 2732 + 50) {
			enemy.destroy();
			enemies.splice(e, 1);
			continue;
		}
		// Enemy shooting logic (only for EnemySubmarine) - limit to max 8 enemy torpedoes
		if (enemy.shootTimer && enemy.shootTimer >= enemy.shootInterval && enemyTorpedoes.length < 8) {
			var enemyTorpedo = new EnemyTorpedo();
			enemyTorpedo.x = enemy.x;
			enemyTorpedo.y = enemy.y + 40;
			// Calculate direction toward submarine
			var deltaX = submarine.x - enemyTorpedo.x;
			var deltaY = submarine.y - enemyTorpedo.y;
			var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
			var speed = 15;
			enemyTorpedo.speedX = deltaX / distance * speed;
			enemyTorpedo.speedY = deltaY / distance * speed;
			enemyTorpedo.lastY = enemyTorpedo.y;
			enemyTorpedo.lastIntersecting = false;
			enemyTorpedoes.push(enemyTorpedo);
			game.addChild(enemyTorpedo);
			enemy.shootTimer = 0;
		}
		// Check submarine-enemy collision
		var currentIntersecting = submarine.intersects(enemy);
		if (!enemy.lastIntersecting && currentIntersecting) {
			// Game Over
			LK.effects.flashScreen(0xFF0000, 1000);
			// Update high score
			if (LK.getScore() > highScore) {
				storage.highScore = LK.getScore();
			}
			LK.showGameOver();
			return;
		}
		enemy.lastY = enemy.y;
		enemy.lastIntersecting = currentIntersecting;
	}
	// Update and check enemy torpedoes
	for (var et = enemyTorpedoes.length - 1; et >= 0; et--) {
		var enemyTorpedo = enemyTorpedoes[et];
		// Remove enemy torpedoes that go off-screen
		if (enemyTorpedo.x < -50 || enemyTorpedo.x > 2098 || enemyTorpedo.y < -50 || enemyTorpedo.y > 2782) {
			enemyTorpedo.destroy();
			enemyTorpedoes.splice(et, 1);
			continue;
		}
		// Check enemy torpedo-submarine collision
		var currentIntersecting = submarine.intersects(enemyTorpedo);
		if (!enemyTorpedo.lastIntersecting && currentIntersecting) {
			// Game Over
			LK.effects.flashScreen(0xFF0000, 1000);
			// Update high score
			if (LK.getScore() > highScore) {
				storage.highScore = LK.getScore();
			}
			LK.showGameOver();
			return;
		}
		enemyTorpedo.lastY = enemyTorpedo.y;
		enemyTorpedo.lastIntersecting = currentIntersecting;
	}
	// Update and cleanup explosions
	for (var ex = game.children.length - 1; ex >= 0; ex--) {
		var child = game.children[ex];
		if (child instanceof Explosion) {
			if (child.lifetime >= child.maxLifetime) {
				child.destroy();
			}
		}
	}
};
// Start background music
LK.playMusic('underwater_ambient'); /**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/**** 
* Classes
****/ 
var EnemySubmarine = Container.expand(function () {
	var self = Container.call(this);
	var enemyGraphics = self.attachAsset('enemySubmarine', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 3;
	self.points = 10;
	self.shootTimer = 0;
	self.shootInterval = 300; // Shoot every 5 seconds
	self.update = function () {
		self.y += self.speed;
		self.shootTimer++;
	};
	return self;
});
var EnemyTorpedo = Container.expand(function () {
	var self = Container.call(this);
	var torpedoGraphics = self.attachAsset('enemyTorpedo', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speedX = 0;
	self.speedY = 0;
	self.update = function () {
		self.x += self.speedX;
		self.y += self.speedY;
	};
	return self;
});
var Explosion = Container.expand(function () {
	var self = Container.call(this);
	var explosionGraphics = self.attachAsset('explosion', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.lifetime = 0;
	self.maxLifetime = 30; // 30 frames = 0.5 seconds
	self.update = function () {
		self.lifetime++;
		// Scale up and fade out over time
		var progress = self.lifetime / self.maxLifetime;
		explosionGraphics.scaleX = 1 + progress * 2;
		explosionGraphics.scaleY = 1 + progress * 2;
		explosionGraphics.alpha = 1 - progress;
		// Change color from orange to red to dark red
		if (progress < 0.3) {
			explosionGraphics.tint = 0xFF4500; // Orange
		} else if (progress < 0.7) {
			explosionGraphics.tint = 0xFF0000; // Red
		} else {
			explosionGraphics.tint = 0x8B0000; // Dark red
		}
	};
	return self;
});
var SeaCreature = Container.expand(function () {
	var self = Container.call(this);
	var creatureGraphics = self.attachAsset('seaCreature', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 4;
	self.points = 20;
	self.update = function () {
		self.y += self.speed;
		// Add slight horizontal movement for more dynamic behavior
		self.x += Math.sin(LK.ticks * 0.05) * 0.5;
	};
	return self;
});
var Submarine = Container.expand(function () {
	var self = Container.call(this);
	var submarineGraphics = self.attachAsset('submarine', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	return self;
});
var Torpedo = Container.expand(function () {
	var self = Container.call(this);
	var torpedoGraphics = self.attachAsset('torpedo', {
		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: 0x000080
});
/**** 
* Game Code
****/ 
// Add underwater background
var background = game.addChild(LK.getAsset('underwaterBackground', {
	anchorX: 0,
	anchorY: 0,
	x: 0,
	y: 0
}));
// Game variables
var submarine;
var torpedoes = [];
var enemyTorpedoes = [];
var enemies = [];
var dragNode = null;
var spawnTimer = 0;
var difficultyLevel = 1;
var enemySpawnRate = 120; // Initial spawn rate (ticks between spawns)
// Create submarine
submarine = game.addChild(new Submarine());
submarine.x = 2048 / 2;
submarine.y = 2732 - 200;
// Create score display
var scoreTxt = new Text2('0', {
	size: 100,
	fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
scoreTxt.setText(LK.getScore());
// Create high score display
var highScore = storage.highScore || 0;
var highScoreTxt = new Text2('Best: ' + highScore, {
	size: 60,
	fill: 0xFFFF00
});
highScoreTxt.anchor.set(1, 0);
highScoreTxt.y = 120;
LK.gui.topRight.addChild(highScoreTxt);
// Handle submarine movement with soft swipe control
var targetX = submarine.x;
var targetY = submarine.y;
var swipeStartX = 0;
var swipeStartY = 0;
var isSwipping = false;
function handleMove(x, y, obj) {
	if (dragNode && isSwipping) {
		// Calculate swipe delta
		var deltaX = x - swipeStartX;
		var deltaY = y - swipeStartY;
		// Update target position based on swipe delta
		targetX = Math.max(60, Math.min(2048 - 60, targetX + deltaX * 0.5));
		targetY = Math.max(100, Math.min(2732 - 100, targetY + deltaY * 0.5));
		// Update swipe start position for continuous movement
		swipeStartX = x;
		swipeStartY = y;
	}
}
game.move = handleMove;
game.down = function (x, y, obj) {
	dragNode = submarine;
	swipeStartX = x;
	swipeStartY = y;
	isSwipping = true;
};
game.up = function (x, y, obj) {
	dragNode = null;
	isSwipping = false;
};
// Spawn enemy function
function spawnEnemy() {
	var enemyType = Math.random();
	var enemy;
	if (enemyType < 0.6) {
		enemy = new EnemySubmarine();
	} else {
		enemy = new SeaCreature();
	}
	enemy.x = Math.random() * (2048 - 100) + 50;
	enemy.y = -50;
	enemy.lastY = enemy.y;
	enemy.lastIntersecting = false;
	enemy.hitCount = 0; // Track hits taken, enemy dies after 2 hits
	enemies.push(enemy);
	game.addChild(enemy);
}
// Main game update loop
game.update = function () {
	// Smooth submarine movement toward target position
	var lerpSpeed = 0.15;
	submarine.x += (targetX - submarine.x) * lerpSpeed;
	submarine.y += (targetY - submarine.y) * lerpSpeed;
	spawnTimer++;
	// Spawn enemies based on difficulty
	if (spawnTimer >= enemySpawnRate) {
		spawnEnemy();
		spawnTimer = 0;
		// Increase difficulty over time
		if (LK.ticks % 1800 == 0) {
			// Every 30 seconds
			difficultyLevel++;
			enemySpawnRate = Math.max(30, enemySpawnRate - 10);
		}
	}
	// Fire torpedoes automatically
	if (LK.ticks % 60 == 0) {
		var torpedo = new Torpedo();
		torpedo.x = submarine.x;
		torpedo.y = submarine.y - 40;
		torpedo.lastY = torpedo.y;
		torpedo.lastIntersecting = false;
		torpedoes.push(torpedo);
		game.addChild(torpedo);
		LK.getSound('torpedo_fire').play();
	}
	// Update and check torpedoes
	for (var t = torpedoes.length - 1; t >= 0; t--) {
		var torpedo = torpedoes[t];
		// Remove torpedoes that go off-screen
		if (torpedo.lastY >= -50 && torpedo.y < -50) {
			torpedo.destroy();
			torpedoes.splice(t, 1);
			continue;
		}
		// Check torpedo-enemy collisions
		var torpedoHit = false;
		for (var e = enemies.length - 1; e >= 0; e--) {
			var enemy = enemies[e];
			var currentIntersecting = torpedo.intersects(enemy);
			if (!torpedo.lastIntersecting && currentIntersecting) {
				// Torpedo hit enemy
				enemy.hitCount++;
				// Create explosion effect
				var explosion = new Explosion();
				explosion.x = enemy.x;
				explosion.y = enemy.y;
				explosion.lastLifetime = 0;
				game.addChild(explosion);
				LK.getSound('explosion').play();
				// Remove torpedo immediately
				torpedo.destroy();
				torpedoes.splice(t, 1);
				// Check if enemy should die (after 2 hits)
				if (enemy.hitCount >= 2) {
					LK.setScore(LK.getScore() + enemy.points);
					scoreTxt.setText(LK.getScore());
					enemy.destroy();
					enemies.splice(e, 1);
				}
				torpedoHit = true;
				break;
			}
		}
		if (!torpedoHit) {
			torpedo.lastY = torpedo.y;
			torpedo.lastIntersecting = false;
		}
	}
	// Update and check enemies
	for (var e = enemies.length - 1; e >= 0; e--) {
		var enemy = enemies[e];
		// Remove enemies that go off-screen
		if (enemy.lastY <= 2732 + 50 && enemy.y > 2732 + 50) {
			enemy.destroy();
			enemies.splice(e, 1);
			continue;
		}
		// Enemy shooting logic (only for EnemySubmarine) - limit to max 8 enemy torpedoes
		if (enemy.shootTimer && enemy.shootTimer >= enemy.shootInterval && enemyTorpedoes.length < 8) {
			var enemyTorpedo = new EnemyTorpedo();
			enemyTorpedo.x = enemy.x;
			enemyTorpedo.y = enemy.y + 40;
			// Calculate direction toward submarine
			var deltaX = submarine.x - enemyTorpedo.x;
			var deltaY = submarine.y - enemyTorpedo.y;
			var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
			var speed = 15;
			enemyTorpedo.speedX = deltaX / distance * speed;
			enemyTorpedo.speedY = deltaY / distance * speed;
			enemyTorpedo.lastY = enemyTorpedo.y;
			enemyTorpedo.lastIntersecting = false;
			enemyTorpedoes.push(enemyTorpedo);
			game.addChild(enemyTorpedo);
			enemy.shootTimer = 0;
		}
		// Check submarine-enemy collision
		var currentIntersecting = submarine.intersects(enemy);
		if (!enemy.lastIntersecting && currentIntersecting) {
			// Game Over
			LK.effects.flashScreen(0xFF0000, 1000);
			// Update high score
			if (LK.getScore() > highScore) {
				storage.highScore = LK.getScore();
			}
			LK.showGameOver();
			return;
		}
		enemy.lastY = enemy.y;
		enemy.lastIntersecting = currentIntersecting;
	}
	// Update and check enemy torpedoes
	for (var et = enemyTorpedoes.length - 1; et >= 0; et--) {
		var enemyTorpedo = enemyTorpedoes[et];
		// Remove enemy torpedoes that go off-screen
		if (enemyTorpedo.x < -50 || enemyTorpedo.x > 2098 || enemyTorpedo.y < -50 || enemyTorpedo.y > 2782) {
			enemyTorpedo.destroy();
			enemyTorpedoes.splice(et, 1);
			continue;
		}
		// Check enemy torpedo-submarine collision
		var currentIntersecting = submarine.intersects(enemyTorpedo);
		if (!enemyTorpedo.lastIntersecting && currentIntersecting) {
			// Game Over
			LK.effects.flashScreen(0xFF0000, 1000);
			// Update high score
			if (LK.getScore() > highScore) {
				storage.highScore = LK.getScore();
			}
			LK.showGameOver();
			return;
		}
		enemyTorpedo.lastY = enemyTorpedo.y;
		enemyTorpedo.lastIntersecting = currentIntersecting;
	}
	// Update and cleanup explosions
	for (var ex = game.children.length - 1; ex >= 0; ex--) {
		var child = game.children[ex];
		if (child instanceof Explosion) {
			if (child.lifetime >= child.maxLifetime) {
				child.destroy();
			}
		}
	}
};
// Start background music
LK.playMusic('underwater_ambient');
 vertical top down blue king crab scifi submarine. In-Game asset. 2d. High contrast. No shadows
 vertical top down red burn robotic octopus scifi war submarine. In-Game asset. 2d. High contrast. No shadows
 vertical top down gray burn robotic turtle scifi war submarine. In-Game asset. 2d. High contrast. No shadows
 top down image of gray sandy seabed. In-Game asset. 2d. High contrast. No shadows
 blue electricity. In-Game asset. 2d. High contrast. No shadows
 red electricity. In-Game asset. 2d. High contrast. No shadows