/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { highScore: 0, money: 0, weaponLevel: 1, shieldLevel: 0 }); /**** * Classes ****/ var Bullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5, alpha: 0.9 }); self.speed = -15; self.damage = 1; self.active = true; self.update = function () { if (!self.active) return; self.y += self.speed; }; self.hit = function () { self.active = false; LK.getSound('explosion').play(); // Flash effect tween(bulletGraphics, { alpha: 0 }, { duration: 200, onFinish: function onFinish() { self.destroy(); } }); }; return self; }); var CargoShip = Container.expand(function () { var self = Container.call(this); var shipGraphics = self.attachAsset('cargoShip', { anchorX: 0.5, anchorY: 0.5 }); self.health = 100; self.maxHealth = 100; self.shootCooldown = 0; self.weaponLevel = storage.weaponLevel; self.shieldLevel = storage.shieldLevel; self.shield = null; self.shieldHealth = 0; self.maxShieldHealth = 0; self.active = true; if (self.shieldLevel > 0) { self.shield = self.attachAsset('shield', { anchorX: 0.5, anchorY: 0.5, alpha: 0.4 }); self.shieldHealth = self.shieldLevel * 20; self.maxShieldHealth = self.shieldHealth; } self.shoot = function () { if (self.shootCooldown <= 0 && self.active) { LK.getSound('playerShoot').play(); // Create main bullet var bullet = new Bullet(); bullet.x = self.x; bullet.y = self.y - 80; bullet.damage = self.weaponLevel; bullets.push(bullet); game.addChild(bullet); // Add side bullets based on weapon level if (self.weaponLevel >= 2) { var bulletLeft = new Bullet(); bulletLeft.x = self.x - 100; bulletLeft.y = self.y - 50; bulletLeft.damage = Math.ceil(self.weaponLevel / 2); bullets.push(bulletLeft); game.addChild(bulletLeft); var bulletRight = new Bullet(); bulletRight.x = self.x + 100; bulletRight.y = self.y - 50; bulletRight.damage = Math.ceil(self.weaponLevel / 2); bullets.push(bulletRight); game.addChild(bulletRight); } // Add more bullets for higher weapon levels if (self.weaponLevel >= 4) { var bulletFarLeft = new Bullet(); bulletFarLeft.x = self.x - 180; bulletFarLeft.y = self.y - 20; bulletFarLeft.damage = Math.ceil(self.weaponLevel / 3); bullets.push(bulletFarLeft); game.addChild(bulletFarLeft); var bulletFarRight = new Bullet(); bulletFarRight.x = self.x + 180; bulletFarRight.y = self.y - 20; bulletFarRight.damage = Math.ceil(self.weaponLevel / 3); bullets.push(bulletFarRight); game.addChild(bulletFarRight); } // Set cooldown based on weapon level (higher level = faster shooting) self.shootCooldown = 30 - self.weaponLevel * 2; if (self.shootCooldown < 10) self.shootCooldown = 10; // Minimum cooldown } }; self.takeDamage = function (amount) { if (!self.active) return; // Shield absorbs damage first if (self.shield && self.shieldHealth > 0 || self.shieldLevel > 0 && self.shieldHealth > 0) { // Recreate shield if it was destroyed but player has shield level if (self.shieldLevel > 0 && !self.shield) { self.shield = self.attachAsset('shield', { anchorX: 0.5, anchorY: 0.5, alpha: 0.4 }); } self.shieldHealth -= amount * 3; // Shield takes triple damage // Flash shield tween(self.shield, { alpha: 0.8 }, { duration: 100, onFinish: function onFinish() { tween(self.shield, { alpha: 0.4 }, { duration: 200 }); } }); if (self.shieldHealth <= 0) { self.shield.visible = false; } LK.getSound('damage').play(); return; } self.health -= amount * 5; // Player takes 5x more damage LK.getSound('damage').play(); // Flash ship red tween(shipGraphics, { tint: 0xff0000 }, { duration: 100, onFinish: function onFinish() { tween(shipGraphics, { tint: 0xffffff }, { duration: 200 }); } }); // Shake effect var originalX = self.x; var originalY = self.y; tween(self, { x: originalX + 20 }, { duration: 50, onFinish: function onFinish() { tween(self, { x: originalX - 20 }, { duration: 100, onFinish: function onFinish() { tween(self, { x: originalX }, { duration: 50 }); } }); } }); if (self.health <= 0) { self.destroy(); self.active = false; gameOver = true; // Save high score if (score > storage.highScore) { storage.highScore = score; } LK.setTimeout(function () { LK.showGameOver(); }, 1000); } }; self.update = function () { if (self.shootCooldown > 0) { self.shootCooldown--; } // Auto-shoot if (autoShoot) { self.shoot(); } }; return self; }); var Cloud = Container.expand(function () { var self = Container.call(this); // Random size between 0.6 and 2.5 var scale = 0.6 + Math.random() * 1.9; var cloudGraphics = self.attachAsset('cloud', { anchorX: 0.5, anchorY: 0.5, scaleX: scale, scaleY: scale, alpha: 0.7 + Math.random() * 0.3 // Random transparency }); // Random speed between 1 and 3 self.speed = 1 + Math.random() * 2; self.active = true; self.update = function () { if (!self.active) return; // Move from top to bottom self.y += self.speed; // Remove if below screen if (self.y > 2732 + 200) { self.destroy(); // Remove from clouds array for (var i = 0; i < clouds.length; i++) { if (clouds[i] === self) { clouds.splice(i, 1); break; } } } }; return self; }); var PirateBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('pirateBullet', { anchorX: 0.5, anchorY: 0.5, alpha: 0.9 }); self.speed = 8; self.damage = 1; self.active = true; self.update = function () { if (!self.active) return; self.y += self.speed; }; self.hit = function () { self.active = false; // Flash effect tween(bulletGraphics, { alpha: 0 }, { duration: 200, onFinish: function onFinish() { self.destroy(); } }); }; return self; }); var PirateShip = Container.expand(function () { var self = Container.call(this); var shipGraphics = self.attachAsset('pirateShip', { anchorX: 0.5, anchorY: 0.5 }); self.health = 3; self.speed = 3; self.shootCooldown = Math.floor(Math.random() * 60) + 30; self.moveDirection = Math.random() > 0.5 ? 1 : -1; self.movementChangeTimer = Math.floor(Math.random() * 60) + 60; self.active = true; self.update = function () { if (!self.active) return; // Move downward self.y += self.speed; // Horizontal movement self.x += self.moveDirection * 2; // Change direction occasionally self.movementChangeTimer--; if (self.movementChangeTimer <= 0) { self.moveDirection *= -1; self.movementChangeTimer = Math.floor(Math.random() * 60) + 60; } // Keep within screen bounds if (self.x < 150) { self.x = 150; self.moveDirection = 1; } else if (self.x > 2048 - 150) { self.x = 2048 - 150; self.moveDirection = -1; } // Shooting logic self.shootCooldown--; if (self.shootCooldown <= 0 && self.y > 0 && self.y < 2000) { self.shoot(); self.shootCooldown = Math.floor(Math.random() * 120) + 60; } // Destroy if off screen if (self.y > 2732 + 100) { self.destroy(); // Find and remove from pirates array for (var i = 0; i < pirates.length; i++) { if (pirates[i] === self) { pirates.splice(i, 1); break; } } } }; self.shoot = function () { if (!self.active) return; LK.getSound('pirateShoot').play(); var bullet = new PirateBullet(); bullet.x = self.x; bullet.y = self.y + 50; pirateBullets.push(bullet); game.addChild(bullet); }; self.takeDamage = function (amount) { if (!self.active) return; self.health = 0; // Set health to 0 immediately for one-hit kill // Flash red tween(shipGraphics, { tint: 0xff0000 }, { duration: 100, onFinish: function onFinish() { tween(shipGraphics, { tint: 0xffffff }, { duration: 200 }); } }); if (self.health <= 0) { self.active = false; // Create explosion effect var explosion = LK.getAsset('explosion', { anchorX: 0.5, anchorY: 0.5, x: self.x, y: self.y, alpha: 0.9, scaleX: 1.5, scaleY: 1.5 }); game.addChild(explosion); // Animate explosion tween(explosion, { alpha: 0, scaleX: 3, scaleY: 3 }, { duration: 500, onFinish: function onFinish() { explosion.destroy(); } }); LK.getSound('explosion').play(); // Always drop coins (100% chance) with double amount var coinCount = Math.floor(Math.random() * 3) + 3; // Drop 3-5 coins for (var c = 0; c < coinCount; c++) { var coin = LK.getAsset('coin', { anchorX: 0.5, anchorY: 0.5, x: self.x + (Math.random() - 0.5) * 40, y: self.y + (Math.random() - 0.5) * 40 }); coins.push({ sprite: coin, x: self.x + (Math.random() - 0.5) * 40, y: self.y + (Math.random() - 0.5) * 40, vx: (Math.random() - 0.5) * 3, vy: Math.random() * 2 + 3 }); game.addChild(coin); } // Remove from array for (var i = 0; i < pirates.length; i++) { if (pirates[i] === self) { pirates.splice(i, 1); break; } } // Increase score score += 10; updateScore(); self.destroy(); } }; return self; }); var LargePirateShip = PirateShip.expand(function () { var self = PirateShip.call(this); // Get the pirateShip asset that was attached in the parent class var shipGraphics = self.children[0]; shipGraphics.scaleX = 1.8; shipGraphics.scaleY = 1.5; self.health = 8; self.speed = 2; self.shoot = function () { if (!self.active) return; LK.getSound('pirateShoot').play(); // Shoot 3 bullets in a spread pattern for (var i = -1; i <= 1; i++) { var bullet = new PirateBullet(); bullet.x = self.x + i * 60; bullet.y = self.y + 60; pirateBullets.push(bullet); game.addChild(bullet); } }; self.takeDamage = function (amount) { if (!self.active) return; self.health -= amount; // Flash red tween(shipGraphics, { tint: 0xff0000 }, { duration: 100, onFinish: function onFinish() { tween(shipGraphics, { tint: 0xffffff }, { duration: 200 }); } }); if (self.health <= 0) { self.active = false; // Create explosion effect var explosion = LK.getAsset('explosion', { anchorX: 0.5, anchorY: 0.5, x: self.x, y: self.y, alpha: 0.9, scaleX: 2.5, scaleY: 2.5 }); game.addChild(explosion); // Animate explosion tween(explosion, { alpha: 0, scaleX: 4, scaleY: 4 }, { duration: 700, onFinish: function onFinish() { explosion.destroy(); } }); LK.getSound('explosion').play(); // Always drop a coin var coin = LK.getAsset('coin', { anchorX: 0.5, anchorY: 0.5, x: self.x, y: self.y }); coins.push({ sprite: coin, x: self.x, y: self.y, vx: (Math.random() - 0.5) * 3, vy: Math.random() * 2 + 3 }); game.addChild(coin); // Drop another coin var coin2 = LK.getAsset('coin', { anchorX: 0.5, anchorY: 0.5, x: self.x + 30, y: self.y - 20 }); coins.push({ sprite: coin2, x: self.x + 30, y: self.y - 20, vx: (Math.random() - 0.5) * 3, vy: Math.random() * 2 + 3 }); game.addChild(coin2); // Remove from array for (var i = 0; i < pirates.length; i++) { if (pirates[i] === self) { pirates.splice(i, 1); break; } } // Increase score score += 30; updateScore(); self.destroy(); } }; return self; }); var BossShip = PirateShip.expand(function () { var self = PirateShip.call(this); // Get the pirateShip asset that was attached in the parent class var shipGraphics = self.children[0]; shipGraphics.scaleX = 2.5; shipGraphics.scaleY = 2.5; shipGraphics.tint = 0xff5500; // Orange tint for the boss self.health = 100; self.maxHealth = 100; self.speed = 1; self.movementChangeTimer = 120; self.shotPattern = 0; self.patternTimer = 0; self.isBoss = true; // Boss healthbar self.healthBarBg = LK.getAsset('healthBarBg', { anchorX: 0.5, anchorY: 0.5, width: 600, height: 30 }); self.healthBar = LK.getAsset('healthBar', { anchorX: 0, anchorY: 0.5, width: 600, height: 30 }); self.addChild(self.healthBarBg); self.addChild(self.healthBar); self.healthBarBg.y = -150; self.healthBar.y = -150; self.healthBar.x = self.healthBarBg.x - 300; self.update = function () { if (!self.active) return; // Different movement pattern for boss if (self.y < 300) { self.y += self.speed; } else { // Horizontal movement only after reaching position self.x += self.moveDirection * 1.5; // Change direction when reaching screen edges if (self.x < 400) { self.x = 400; self.moveDirection = 1; } else if (self.x > 2048 - 400) { self.x = 2048 - 400; self.moveDirection = -1; } } // Update boss healthbar self.healthBar.width = self.health / self.maxHealth * 600; // Shot pattern timing self.patternTimer--; if (self.patternTimer <= 0) { self.shoot(); // Cycle through different shot patterns self.shotPattern = (self.shotPattern + 1) % 3; // Set different cooldowns based on pattern if (self.shotPattern === 0) { self.patternTimer = 90; // Spread shot } else if (self.shotPattern === 1) { self.patternTimer = 120; // Circle shot } else { self.patternTimer = 60; // Fast shot } } }; self.shoot = function () { if (!self.active) return; LK.getSound('pirateShoot').play(); if (self.shotPattern === 0) { // Wide spread shot for (var i = -4; i <= 4; i++) { var bullet = new PirateBullet(); bullet.x = self.x + i * 60; bullet.y = self.y + 80; pirateBullets.push(bullet); game.addChild(bullet); } } else if (self.shotPattern === 1) { // Circle shot var bulletCount = 12; for (var i = 0; i < bulletCount; i++) { var angle = i / bulletCount * Math.PI * 2; var bullet = new PirateBullet(); bullet.x = self.x + Math.cos(angle) * 60; bullet.y = self.y + Math.sin(angle) * 60 + 80; bullet.speed = 5; // Slower bullets pirateBullets.push(bullet); game.addChild(bullet); } } else { // Fast triple shot for (var i = -1; i <= 1; i++) { var bullet = new PirateBullet(); bullet.x = self.x + i * 120; bullet.y = self.y + 80; bullet.speed = 12; // Faster bullets pirateBullets.push(bullet); game.addChild(bullet); } } }; self.takeDamage = function (amount) { if (!self.active) return; self.health -= amount; // Flash red tween(shipGraphics, { tint: 0xff0000 }, { duration: 100, onFinish: function onFinish() { tween(shipGraphics, { tint: 0xff5500 // Return to boss orange tint }, { duration: 200 }); } }); // Check if defeated if (self.health <= 0) { self.active = false; // Big explosion effect for (var i = 0; i < 5; i++) { LK.setTimeout(function () { var explosion = LK.getAsset('explosion', { anchorX: 0.5, anchorY: 0.5, x: self.x + (Math.random() - 0.5) * 200, y: self.y + (Math.random() - 0.5) * 200, alpha: 0.9, scaleX: 2 + Math.random() * 2, scaleY: 2 + Math.random() * 2 }); game.addChild(explosion); // Animate explosion tween(explosion, { alpha: 0, scaleX: 4, scaleY: 4 }, { duration: 700, onFinish: function onFinish() { explosion.destroy(); } }); LK.getSound('explosion').play(); }, i * 200); } // Drop lots of coins for (var c = 0; c < 20; c++) { var coin = LK.getAsset('coin', { anchorX: 0.5, anchorY: 0.5, x: self.x + (Math.random() - 0.5) * 200, y: self.y + (Math.random() - 0.5) * 200 }); coins.push({ sprite: coin, x: self.x + (Math.random() - 0.5) * 200, y: self.y + (Math.random() - 0.5) * 200, vx: (Math.random() - 0.5) * 5, vy: (Math.random() - 0.5) * 5 }); game.addChild(coin); } // Remove from pirates array for (var i = 0; i < pirates.length; i++) { if (pirates[i] === self) { pirates.splice(i, 1); break; } } // Increase score and add big bonus score += 200; updateScore(); // Show boss defeated message var bossDefeatedTxt = new Text2('BOSS DEFEATED!', { size: 120, fill: 0xFFDD00 }); bossDefeatedTxt.anchor.set(0.5, 0.5); bossDefeatedTxt.x = 2048 / 2; bossDefeatedTxt.y = 2732 / 2; game.addChild(bossDefeatedTxt); // Animate boss defeated text tween(bossDefeatedTxt, { scale: 1.5 }, { duration: 500, onFinish: function onFinish() { tween(bossDefeatedTxt, { scale: 1.0, alpha: 0 }, { duration: 800, onFinish: function onFinish() { bossDefeatedTxt.destroy(); } }); } }); self.destroy(); } }; return self; }); var SuperWeapon = Container.expand(function () { var self = Container.call(this); var weaponGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5, scaleX: 2, scaleY: 2, alpha: 0.9 }); self.speed = -20; self.damage = 5; self.active = true; self.rotation = 0; self.update = function () { if (!self.active) return; self.y += self.speed; self.rotation += 0.2; weaponGraphics.rotation = self.rotation; }; self.hit = function () { self.active = false; // Flash effect tween(weaponGraphics, { alpha: 0, scaleX: 3, scaleY: 3 }, { duration: 200, onFinish: function onFinish() { self.destroy(); } }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x0a2550 // Deep blue ocean color }); /**** * Game Code ****/ // Game variables var player; var bullets = []; var pirates = []; var pirateBullets = []; var coins = []; var clouds = []; // Track clouds var score = 0; var money = storage.money; var gameOver = false; var spawnTimer = 0; var waveTimer = 0; var currentWave = 1; var enemiesThisWave = 5; var enemiesSpawned = 0; var healthBar; var healthBarBg; var shieldBar; var autoShoot = true; var bossSpawned = false; var cloudSpawnTimer = 0; // Timer for spawning clouds // Swipe control variables var startX = 0; var startY = 0; var isMoving = false; var swipeSensitivity = 1.2; // Higher value = more responsive movement var swipeInertia = 0.9; // Value between 0-1, higher = more inertia var playerVelocityX = 0; // UI elements var scoreTxt; var waveTxt; var moneyTxt; var weaponUpgradeBtn; var shieldUpgradeBtn; var weaponLevelTxt; var shieldLevelTxt; var specialWeaponBtn; var specialWeaponTxt; var weaponStatusTxt; // Initialize player function initPlayer() { player = new CargoShip(); player.x = 2048 / 2; player.y = 2732 - 200; game.addChild(player); // Create health bar background healthBarBg = LK.getAsset('healthBarBg', { anchorX: 0, anchorY: 0, x: 50, y: 50 }); game.addChild(healthBarBg); // Create health bar healthBar = LK.getAsset('healthBar', { anchorX: 0, anchorY: 0, x: 50, y: 50 }); game.addChild(healthBar); // Create shield bar if player has shields if (player.shieldLevel > 0) { shieldBar = LK.getAsset('shield', { anchorX: 0, anchorY: 0, x: 50, y: 90, height: 20, width: 500, alpha: 0.6 }); game.addChild(shieldBar); } } // Initialize UI function initUI() { // Score text scoreTxt = new Text2('Score: 0', { size: 60, fill: 0xFFFFFF }); scoreTxt.anchor.set(1, 0); LK.gui.topRight.addChild(scoreTxt); // Weapon level text removed // Wave text waveTxt = new Text2('Wave: 1', { size: 60, fill: 0xFFFFFF }); waveTxt.anchor.set(0.5, 0); LK.gui.top.addChild(waveTxt); // Money text moneyTxt = new Text2('Coins: ' + money, { size: 60, fill: 0xFFCC00 }); moneyTxt.anchor.set(0, 0); moneyTxt.x = 120; LK.gui.topLeft.addChild(moneyTxt); // Weapon upgrade button weaponUpgradeBtn = LK.getAsset('upgradeButton', { anchorX: 0.5, anchorY: 0.5 }); weaponUpgradeBtn.x = 2048 / 2 - 350; weaponUpgradeBtn.y = 2732 - 80; game.addChild(weaponUpgradeBtn); // Weapon level text now removed // Shield upgrade button shieldUpgradeBtn = LK.getAsset('repairButton', { anchorX: 0.5, anchorY: 0.5 }); shieldUpgradeBtn.x = 2048 / 2 + 350; shieldUpgradeBtn.y = 2732 - 80; game.addChild(shieldUpgradeBtn); // Shield level text is removed // Special weapon button (visible only when weapon level is 3+) specialWeaponBtn = LK.getAsset('bullet', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5, alpha: 0.8 }); specialWeaponBtn.x = 2048 / 2; specialWeaponBtn.y = 2732 - 80; specialWeaponBtn.visible = player.weaponLevel >= 3; game.addChild(specialWeaponBtn); // Special weapon text var specialWeaponTxt = new Text2('SUPER\nATTACK', { size: 35, fill: 0xFFFF00 }); specialWeaponTxt.anchor.set(0.5, 0.5); specialWeaponTxt.x = specialWeaponBtn.x; specialWeaponTxt.y = specialWeaponBtn.y; specialWeaponTxt.visible = player.weaponLevel >= 3; game.addChild(specialWeaponTxt); } // Update score display function updateScore() { scoreTxt.setText('Score: ' + score); LK.setScore(score); } // Update money display function updateMoney() { moneyTxt.setText('Coins: ' + money); storage.money = money; } // Update wave display function updateWave() { waveTxt.setText('Wave: ' + currentWave); } // Get upgrade cost based on current level function getUpgradeCost(level) { return level * 50; } // Get shield upgrade cost function getShieldCost(level) { return (level + 1) * 80; } // Spawn a pirate ship function spawnPirate() { var pirateX = Math.random() * (2048 - 300) + 150; var pirateY = -100; var pirate; // Spawn large pirates occasionally, more often in higher waves if (Math.random() < 0.1 + currentWave * 0.02) { pirate = new LargePirateShip(); pirate.speed += Math.min(currentWave * 0.1, 1); // Increase speed with wave } else { pirate = new PirateShip(); pirate.speed += Math.min(currentWave * 0.2, 2); // Increase speed with wave pirate.health += Math.floor(currentWave / 3); // Increase health with wave } pirate.x = pirateX; pirate.y = pirateY; pirates.push(pirate); game.addChild(pirate); enemiesSpawned++; } // Start a new wave function startNewWave() { currentWave++; enemiesThisWave = 5 + currentWave * 2; enemiesSpawned = 0; updateWave(); // Flash wave text tween(waveTxt, { scale: 1.5 }, { duration: 300, onFinish: function onFinish() { tween(waveTxt, { scale: 1.0 }, { duration: 300 }); } }); } // Upgrade weapon function upgradeWeapon() { var cost = getUpgradeCost(player.weaponLevel); if (money >= cost) { money -= cost; player.weaponLevel++; storage.weaponLevel = player.weaponLevel; updateMoney(); // Update button text weaponLevelTxt.setText('Upgrade Weapon\n' + getUpgradeCost(player.weaponLevel) + ' coins'); // Update weapon level display weaponStatusTxt.setText('Weapon Lvl: ' + player.weaponLevel); // Show special weapon button if level 3+ if (player.weaponLevel >= 3) { specialWeaponBtn.visible = true; specialWeaponTxt.visible = true; } LK.getSound('upgrade').play(); // Show effect tween(weaponUpgradeBtn, { alpha: 0.5 }, { duration: 200, onFinish: function onFinish() { tween(weaponUpgradeBtn, { alpha: 1.0 }, { duration: 200 }); } }); } } // Activate super weapon function activateSuperWeapon() { // Create super weapon bullet var superBullet = new SuperWeapon(); superBullet.x = player.x; superBullet.y = player.y - 100; superBullet.damage = player.weaponLevel * 2; bullets.push(superBullet); game.addChild(superBullet); // Play special sound LK.getSound('playerShoot').play(); // Cool visual effect LK.effects.flashScreen(0x0099FF, 300); // Make the special weapon button temporarily unavailable specialWeaponBtn.alpha = 0.3; specialWeaponTxt.alpha = 0.3; specialWeaponBtn.interactive = false; // Reset after cooldown LK.setTimeout(function () { specialWeaponBtn.alpha = 0.8; specialWeaponTxt.alpha = 1; specialWeaponBtn.interactive = true; }, 3000); } // Upgrade shield function (disabled) function upgradeShield() { // Function is now empty as shield upgrading is disabled } // Handle touch/mouse events function handleTouchMove(x, y) { if (gameOver) return; // Move player if (player && player.active) { if (isMoving) { // Calculate swipe velocity with sensitivity multiplier var deltaX = (x - startX) * swipeSensitivity; // Apply velocity change based on swipe direction and magnitude playerVelocityX = deltaX; // Update starting position for next move startX = x; } // Constrain to screen if (player.x < 250) { player.x = 250; playerVelocityX = 0; } if (player.x > 2048 - 250) { player.x = 2048 - 250; playerVelocityX = 0; } } } // Game initialization function initGame() { // Add background var background = LK.getAsset('background', { anchorX: 0, anchorY: 0, x: 0, y: 0, width: 2048, height: 2732 }); game.addChild(background); // Initialize game state score = 0; money = storage.money || 1500; // Start with 1500 money for faster upgrades storage.money = money; // Make sure storage is updated too gameOver = false; spawnTimer = 0; waveTimer = 0; currentWave = 1; enemiesThisWave = 5; enemiesSpawned = 0; bossSpawned = false; bullets = []; pirates = []; pirateBullets = []; coins = []; clouds = []; cloudSpawnTimer = 0; // Initialize player and UI first initPlayer(); initUI(); // Now update displays after UI is initialized updateScore(); updateMoney(); // Start background music LK.playMusic('bgMusic'); } // Touch/mouse events game.move = function (x, y) { handleTouchMove(x, y); }; game.down = function (x, y, obj) { // Check if clicked on upgrade buttons if (obj === weaponUpgradeBtn) { upgradeWeapon(); return; } // Shield upgrades disabled if (obj === shieldUpgradeBtn) { return; } // Check for special weapon button if (obj === specialWeaponBtn && player.weaponLevel >= 3) { activateSuperWeapon(); return; } // Start tracking swipe startX = x; startY = y; isMoving = true; playerVelocityX = 0; // Otherwise move the player handleTouchMove(x, y); // Manual shoot on tap if (player && player.active) { player.shoot(); } }; // Handle touch/mouse up game.up = function (x, y) { // Stop tracking movement but keep momentum isMoving = false; }; // Main game update loop game.update = function () { if (gameOver) return; // Cloud spawning logic cloudSpawnTimer--; if (cloudSpawnTimer <= 0) { // Spawn a new cloud at random x position var cloud = new Cloud(); cloud.x = Math.random() * 2048; cloud.y = -200; clouds.push(cloud); game.addChild(cloud); // Reset timer (random interval between 30 and 120 frames) cloudSpawnTimer = 30 + Math.floor(Math.random() * 90); } // Update clouds for (var i = clouds.length - 1; i >= 0; i--) { clouds[i].update(); } // Update player if (player && player.active) { // Apply velocity with inertia for smooth movement player.x += playerVelocityX; playerVelocityX *= swipeInertia; // Apply inertia to slow down movement gradually // Constrain to screen boundaries if (player.x < 250) { player.x = 250; playerVelocityX = 0; } if (player.x > 2048 - 250) { player.x = 2048 - 250; playerVelocityX = 0; } player.update(); // Update health bar var healthRatio = player.health / player.maxHealth; healthBar.width = 500 * healthRatio; // Update shield bar if (player.shieldLevel > 0) { // Make sure shield bar exists if (!shieldBar) { shieldBar = LK.getAsset('shield', { anchorX: 0, anchorY: 0, x: 50, y: 90, height: 20, width: 500, alpha: 0.6 }); game.addChild(shieldBar); } // Update shield bar width var shieldRatio = player.shieldHealth / player.maxShieldHealth; shieldBar.width = 500 * shieldRatio; shieldBar.visible = player.shieldHealth > 0; // Make sure shield is visible if it should be if (player.shield) { player.shield.visible = player.shieldHealth > 0; } } } // Spawn enemies spawnTimer--; if (spawnTimer <= 0 && enemiesSpawned < enemiesThisWave) { spawnPirate(); spawnTimer = Math.max(30, 90 - currentWave * 5); // Spawn faster in higher waves } // Check if wave is complete if (enemiesSpawned >= enemiesThisWave && pirates.length === 0) { waveTimer--; if (waveTimer <= 0) { // Every 3rd wave, spawn a boss instead of starting a new wave if (currentWave > 0 && currentWave % 3 === 0 && !bossSpawned) { // Spawn boss var boss = new BossShip(); boss.x = 2048 / 2; boss.y = -200; pirates.push(boss); game.addChild(boss); // Show boss warning var bossWarningTxt = new Text2('BOSS INCOMING!', { size: 120, fill: 0xFF3300 }); bossWarningTxt.anchor.set(0.5, 0.5); bossWarningTxt.x = 2048 / 2; bossWarningTxt.y = 2732 / 2; game.addChild(bossWarningTxt); // Animate warning text tween(bossWarningTxt, { scale: 1.5 }, { duration: 500, onFinish: function onFinish() { tween(bossWarningTxt, { scale: 1.0, alpha: 0 }, { duration: 800, onFinish: function onFinish() { bossWarningTxt.destroy(); } }); } }); // Flash screen LK.effects.flashScreen(0xFF3300, 500); bossSpawned = true; } else { startNewWave(); bossSpawned = false; } waveTimer = 180; // Delay before next wave } } // Update pirates for (var i = 0; i < pirates.length; i++) { pirates[i].update(); } // Update bullets for (var i = bullets.length - 1; i >= 0; i--) { var bullet = bullets[i]; bullet.update(); // Check for off-screen if (bullet.y < -50) { bullet.destroy(); bullets.splice(i, 1); continue; } // Check for collisions with pirates for (var j = 0; j < pirates.length; j++) { var pirate = pirates[j]; if (bullet.active && pirate.active && bullet.intersects(pirate)) { pirate.takeDamage(bullet.damage); bullet.hit(); break; } } } // Update pirate bullets for (var i = pirateBullets.length - 1; i >= 0; i--) { var bullet = pirateBullets[i]; bullet.update(); // Check for off-screen if (bullet.y > 2732 + 50) { bullet.destroy(); pirateBullets.splice(i, 1); continue; } // Check for collision with player if (bullet.active && player && player.active && bullet.intersects(player)) { player.takeDamage(bullet.damage); bullet.hit(); pirateBullets.splice(i, 1); } } // Update coins for (var i = coins.length - 1; i >= 0; i--) { var coin = coins[i]; // Apply physics coin.y += coin.vy; coin.x += coin.vx; coin.vy += 0.1; // Gravity // Enhanced coin magnet effect - attract coins to player from farther with more force if (player && player.active && Math.abs(coin.x - player.x) < 1200 && Math.abs(coin.y - player.y) < 800) { var dx = player.x - coin.x; var dy = player.y - coin.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { coin.vx += dx / dist * 6; coin.vy += dy / dist * 6; } } // Update sprite position coin.sprite.x = coin.x; coin.sprite.y = coin.y; // Check if coin is collected with increased collection radius if (player && player.active && Math.abs(coin.x - player.x) < 500 && Math.abs(coin.y - player.y) < 300) { coin.sprite.destroy(); coins.splice(i, 1); money += 10; // Double coin value to 10 for faster money collection updateMoney(); LK.getSound('coinPickup').play(); continue; } // Remove if off screen if (coin.y > 2732 + 50) { coin.sprite.destroy(); coins.splice(i, 1); } } }; // Initialize the game initGame();
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highScore: 0,
money: 0,
weaponLevel: 1,
shieldLevel: 0
});
/****
* Classes
****/
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.9
});
self.speed = -15;
self.damage = 1;
self.active = true;
self.update = function () {
if (!self.active) return;
self.y += self.speed;
};
self.hit = function () {
self.active = false;
LK.getSound('explosion').play();
// Flash effect
tween(bulletGraphics, {
alpha: 0
}, {
duration: 200,
onFinish: function onFinish() {
self.destroy();
}
});
};
return self;
});
var CargoShip = Container.expand(function () {
var self = Container.call(this);
var shipGraphics = self.attachAsset('cargoShip', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 100;
self.maxHealth = 100;
self.shootCooldown = 0;
self.weaponLevel = storage.weaponLevel;
self.shieldLevel = storage.shieldLevel;
self.shield = null;
self.shieldHealth = 0;
self.maxShieldHealth = 0;
self.active = true;
if (self.shieldLevel > 0) {
self.shield = self.attachAsset('shield', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.4
});
self.shieldHealth = self.shieldLevel * 20;
self.maxShieldHealth = self.shieldHealth;
}
self.shoot = function () {
if (self.shootCooldown <= 0 && self.active) {
LK.getSound('playerShoot').play();
// Create main bullet
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y - 80;
bullet.damage = self.weaponLevel;
bullets.push(bullet);
game.addChild(bullet);
// Add side bullets based on weapon level
if (self.weaponLevel >= 2) {
var bulletLeft = new Bullet();
bulletLeft.x = self.x - 100;
bulletLeft.y = self.y - 50;
bulletLeft.damage = Math.ceil(self.weaponLevel / 2);
bullets.push(bulletLeft);
game.addChild(bulletLeft);
var bulletRight = new Bullet();
bulletRight.x = self.x + 100;
bulletRight.y = self.y - 50;
bulletRight.damage = Math.ceil(self.weaponLevel / 2);
bullets.push(bulletRight);
game.addChild(bulletRight);
}
// Add more bullets for higher weapon levels
if (self.weaponLevel >= 4) {
var bulletFarLeft = new Bullet();
bulletFarLeft.x = self.x - 180;
bulletFarLeft.y = self.y - 20;
bulletFarLeft.damage = Math.ceil(self.weaponLevel / 3);
bullets.push(bulletFarLeft);
game.addChild(bulletFarLeft);
var bulletFarRight = new Bullet();
bulletFarRight.x = self.x + 180;
bulletFarRight.y = self.y - 20;
bulletFarRight.damage = Math.ceil(self.weaponLevel / 3);
bullets.push(bulletFarRight);
game.addChild(bulletFarRight);
}
// Set cooldown based on weapon level (higher level = faster shooting)
self.shootCooldown = 30 - self.weaponLevel * 2;
if (self.shootCooldown < 10) self.shootCooldown = 10; // Minimum cooldown
}
};
self.takeDamage = function (amount) {
if (!self.active) return;
// Shield absorbs damage first
if (self.shield && self.shieldHealth > 0 || self.shieldLevel > 0 && self.shieldHealth > 0) {
// Recreate shield if it was destroyed but player has shield level
if (self.shieldLevel > 0 && !self.shield) {
self.shield = self.attachAsset('shield', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.4
});
}
self.shieldHealth -= amount * 3; // Shield takes triple damage
// Flash shield
tween(self.shield, {
alpha: 0.8
}, {
duration: 100,
onFinish: function onFinish() {
tween(self.shield, {
alpha: 0.4
}, {
duration: 200
});
}
});
if (self.shieldHealth <= 0) {
self.shield.visible = false;
}
LK.getSound('damage').play();
return;
}
self.health -= amount * 5; // Player takes 5x more damage
LK.getSound('damage').play();
// Flash ship red
tween(shipGraphics, {
tint: 0xff0000
}, {
duration: 100,
onFinish: function onFinish() {
tween(shipGraphics, {
tint: 0xffffff
}, {
duration: 200
});
}
});
// Shake effect
var originalX = self.x;
var originalY = self.y;
tween(self, {
x: originalX + 20
}, {
duration: 50,
onFinish: function onFinish() {
tween(self, {
x: originalX - 20
}, {
duration: 100,
onFinish: function onFinish() {
tween(self, {
x: originalX
}, {
duration: 50
});
}
});
}
});
if (self.health <= 0) {
self.destroy();
self.active = false;
gameOver = true;
// Save high score
if (score > storage.highScore) {
storage.highScore = score;
}
LK.setTimeout(function () {
LK.showGameOver();
}, 1000);
}
};
self.update = function () {
if (self.shootCooldown > 0) {
self.shootCooldown--;
}
// Auto-shoot
if (autoShoot) {
self.shoot();
}
};
return self;
});
var Cloud = Container.expand(function () {
var self = Container.call(this);
// Random size between 0.6 and 2.5
var scale = 0.6 + Math.random() * 1.9;
var cloudGraphics = self.attachAsset('cloud', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: scale,
scaleY: scale,
alpha: 0.7 + Math.random() * 0.3 // Random transparency
});
// Random speed between 1 and 3
self.speed = 1 + Math.random() * 2;
self.active = true;
self.update = function () {
if (!self.active) return;
// Move from top to bottom
self.y += self.speed;
// Remove if below screen
if (self.y > 2732 + 200) {
self.destroy();
// Remove from clouds array
for (var i = 0; i < clouds.length; i++) {
if (clouds[i] === self) {
clouds.splice(i, 1);
break;
}
}
}
};
return self;
});
var PirateBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('pirateBullet', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.9
});
self.speed = 8;
self.damage = 1;
self.active = true;
self.update = function () {
if (!self.active) return;
self.y += self.speed;
};
self.hit = function () {
self.active = false;
// Flash effect
tween(bulletGraphics, {
alpha: 0
}, {
duration: 200,
onFinish: function onFinish() {
self.destroy();
}
});
};
return self;
});
var PirateShip = Container.expand(function () {
var self = Container.call(this);
var shipGraphics = self.attachAsset('pirateShip', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 3;
self.speed = 3;
self.shootCooldown = Math.floor(Math.random() * 60) + 30;
self.moveDirection = Math.random() > 0.5 ? 1 : -1;
self.movementChangeTimer = Math.floor(Math.random() * 60) + 60;
self.active = true;
self.update = function () {
if (!self.active) return;
// Move downward
self.y += self.speed;
// Horizontal movement
self.x += self.moveDirection * 2;
// Change direction occasionally
self.movementChangeTimer--;
if (self.movementChangeTimer <= 0) {
self.moveDirection *= -1;
self.movementChangeTimer = Math.floor(Math.random() * 60) + 60;
}
// Keep within screen bounds
if (self.x < 150) {
self.x = 150;
self.moveDirection = 1;
} else if (self.x > 2048 - 150) {
self.x = 2048 - 150;
self.moveDirection = -1;
}
// Shooting logic
self.shootCooldown--;
if (self.shootCooldown <= 0 && self.y > 0 && self.y < 2000) {
self.shoot();
self.shootCooldown = Math.floor(Math.random() * 120) + 60;
}
// Destroy if off screen
if (self.y > 2732 + 100) {
self.destroy();
// Find and remove from pirates array
for (var i = 0; i < pirates.length; i++) {
if (pirates[i] === self) {
pirates.splice(i, 1);
break;
}
}
}
};
self.shoot = function () {
if (!self.active) return;
LK.getSound('pirateShoot').play();
var bullet = new PirateBullet();
bullet.x = self.x;
bullet.y = self.y + 50;
pirateBullets.push(bullet);
game.addChild(bullet);
};
self.takeDamage = function (amount) {
if (!self.active) return;
self.health = 0; // Set health to 0 immediately for one-hit kill
// Flash red
tween(shipGraphics, {
tint: 0xff0000
}, {
duration: 100,
onFinish: function onFinish() {
tween(shipGraphics, {
tint: 0xffffff
}, {
duration: 200
});
}
});
if (self.health <= 0) {
self.active = false;
// Create explosion effect
var explosion = LK.getAsset('explosion', {
anchorX: 0.5,
anchorY: 0.5,
x: self.x,
y: self.y,
alpha: 0.9,
scaleX: 1.5,
scaleY: 1.5
});
game.addChild(explosion);
// Animate explosion
tween(explosion, {
alpha: 0,
scaleX: 3,
scaleY: 3
}, {
duration: 500,
onFinish: function onFinish() {
explosion.destroy();
}
});
LK.getSound('explosion').play();
// Always drop coins (100% chance) with double amount
var coinCount = Math.floor(Math.random() * 3) + 3; // Drop 3-5 coins
for (var c = 0; c < coinCount; c++) {
var coin = LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
x: self.x + (Math.random() - 0.5) * 40,
y: self.y + (Math.random() - 0.5) * 40
});
coins.push({
sprite: coin,
x: self.x + (Math.random() - 0.5) * 40,
y: self.y + (Math.random() - 0.5) * 40,
vx: (Math.random() - 0.5) * 3,
vy: Math.random() * 2 + 3
});
game.addChild(coin);
}
// Remove from array
for (var i = 0; i < pirates.length; i++) {
if (pirates[i] === self) {
pirates.splice(i, 1);
break;
}
}
// Increase score
score += 10;
updateScore();
self.destroy();
}
};
return self;
});
var LargePirateShip = PirateShip.expand(function () {
var self = PirateShip.call(this);
// Get the pirateShip asset that was attached in the parent class
var shipGraphics = self.children[0];
shipGraphics.scaleX = 1.8;
shipGraphics.scaleY = 1.5;
self.health = 8;
self.speed = 2;
self.shoot = function () {
if (!self.active) return;
LK.getSound('pirateShoot').play();
// Shoot 3 bullets in a spread pattern
for (var i = -1; i <= 1; i++) {
var bullet = new PirateBullet();
bullet.x = self.x + i * 60;
bullet.y = self.y + 60;
pirateBullets.push(bullet);
game.addChild(bullet);
}
};
self.takeDamage = function (amount) {
if (!self.active) return;
self.health -= amount;
// Flash red
tween(shipGraphics, {
tint: 0xff0000
}, {
duration: 100,
onFinish: function onFinish() {
tween(shipGraphics, {
tint: 0xffffff
}, {
duration: 200
});
}
});
if (self.health <= 0) {
self.active = false;
// Create explosion effect
var explosion = LK.getAsset('explosion', {
anchorX: 0.5,
anchorY: 0.5,
x: self.x,
y: self.y,
alpha: 0.9,
scaleX: 2.5,
scaleY: 2.5
});
game.addChild(explosion);
// Animate explosion
tween(explosion, {
alpha: 0,
scaleX: 4,
scaleY: 4
}, {
duration: 700,
onFinish: function onFinish() {
explosion.destroy();
}
});
LK.getSound('explosion').play();
// Always drop a coin
var coin = LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
x: self.x,
y: self.y
});
coins.push({
sprite: coin,
x: self.x,
y: self.y,
vx: (Math.random() - 0.5) * 3,
vy: Math.random() * 2 + 3
});
game.addChild(coin);
// Drop another coin
var coin2 = LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
x: self.x + 30,
y: self.y - 20
});
coins.push({
sprite: coin2,
x: self.x + 30,
y: self.y - 20,
vx: (Math.random() - 0.5) * 3,
vy: Math.random() * 2 + 3
});
game.addChild(coin2);
// Remove from array
for (var i = 0; i < pirates.length; i++) {
if (pirates[i] === self) {
pirates.splice(i, 1);
break;
}
}
// Increase score
score += 30;
updateScore();
self.destroy();
}
};
return self;
});
var BossShip = PirateShip.expand(function () {
var self = PirateShip.call(this);
// Get the pirateShip asset that was attached in the parent class
var shipGraphics = self.children[0];
shipGraphics.scaleX = 2.5;
shipGraphics.scaleY = 2.5;
shipGraphics.tint = 0xff5500; // Orange tint for the boss
self.health = 100;
self.maxHealth = 100;
self.speed = 1;
self.movementChangeTimer = 120;
self.shotPattern = 0;
self.patternTimer = 0;
self.isBoss = true;
// Boss healthbar
self.healthBarBg = LK.getAsset('healthBarBg', {
anchorX: 0.5,
anchorY: 0.5,
width: 600,
height: 30
});
self.healthBar = LK.getAsset('healthBar', {
anchorX: 0,
anchorY: 0.5,
width: 600,
height: 30
});
self.addChild(self.healthBarBg);
self.addChild(self.healthBar);
self.healthBarBg.y = -150;
self.healthBar.y = -150;
self.healthBar.x = self.healthBarBg.x - 300;
self.update = function () {
if (!self.active) return;
// Different movement pattern for boss
if (self.y < 300) {
self.y += self.speed;
} else {
// Horizontal movement only after reaching position
self.x += self.moveDirection * 1.5;
// Change direction when reaching screen edges
if (self.x < 400) {
self.x = 400;
self.moveDirection = 1;
} else if (self.x > 2048 - 400) {
self.x = 2048 - 400;
self.moveDirection = -1;
}
}
// Update boss healthbar
self.healthBar.width = self.health / self.maxHealth * 600;
// Shot pattern timing
self.patternTimer--;
if (self.patternTimer <= 0) {
self.shoot();
// Cycle through different shot patterns
self.shotPattern = (self.shotPattern + 1) % 3;
// Set different cooldowns based on pattern
if (self.shotPattern === 0) {
self.patternTimer = 90; // Spread shot
} else if (self.shotPattern === 1) {
self.patternTimer = 120; // Circle shot
} else {
self.patternTimer = 60; // Fast shot
}
}
};
self.shoot = function () {
if (!self.active) return;
LK.getSound('pirateShoot').play();
if (self.shotPattern === 0) {
// Wide spread shot
for (var i = -4; i <= 4; i++) {
var bullet = new PirateBullet();
bullet.x = self.x + i * 60;
bullet.y = self.y + 80;
pirateBullets.push(bullet);
game.addChild(bullet);
}
} else if (self.shotPattern === 1) {
// Circle shot
var bulletCount = 12;
for (var i = 0; i < bulletCount; i++) {
var angle = i / bulletCount * Math.PI * 2;
var bullet = new PirateBullet();
bullet.x = self.x + Math.cos(angle) * 60;
bullet.y = self.y + Math.sin(angle) * 60 + 80;
bullet.speed = 5; // Slower bullets
pirateBullets.push(bullet);
game.addChild(bullet);
}
} else {
// Fast triple shot
for (var i = -1; i <= 1; i++) {
var bullet = new PirateBullet();
bullet.x = self.x + i * 120;
bullet.y = self.y + 80;
bullet.speed = 12; // Faster bullets
pirateBullets.push(bullet);
game.addChild(bullet);
}
}
};
self.takeDamage = function (amount) {
if (!self.active) return;
self.health -= amount;
// Flash red
tween(shipGraphics, {
tint: 0xff0000
}, {
duration: 100,
onFinish: function onFinish() {
tween(shipGraphics, {
tint: 0xff5500 // Return to boss orange tint
}, {
duration: 200
});
}
});
// Check if defeated
if (self.health <= 0) {
self.active = false;
// Big explosion effect
for (var i = 0; i < 5; i++) {
LK.setTimeout(function () {
var explosion = LK.getAsset('explosion', {
anchorX: 0.5,
anchorY: 0.5,
x: self.x + (Math.random() - 0.5) * 200,
y: self.y + (Math.random() - 0.5) * 200,
alpha: 0.9,
scaleX: 2 + Math.random() * 2,
scaleY: 2 + Math.random() * 2
});
game.addChild(explosion);
// Animate explosion
tween(explosion, {
alpha: 0,
scaleX: 4,
scaleY: 4
}, {
duration: 700,
onFinish: function onFinish() {
explosion.destroy();
}
});
LK.getSound('explosion').play();
}, i * 200);
}
// Drop lots of coins
for (var c = 0; c < 20; c++) {
var coin = LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
x: self.x + (Math.random() - 0.5) * 200,
y: self.y + (Math.random() - 0.5) * 200
});
coins.push({
sprite: coin,
x: self.x + (Math.random() - 0.5) * 200,
y: self.y + (Math.random() - 0.5) * 200,
vx: (Math.random() - 0.5) * 5,
vy: (Math.random() - 0.5) * 5
});
game.addChild(coin);
}
// Remove from pirates array
for (var i = 0; i < pirates.length; i++) {
if (pirates[i] === self) {
pirates.splice(i, 1);
break;
}
}
// Increase score and add big bonus
score += 200;
updateScore();
// Show boss defeated message
var bossDefeatedTxt = new Text2('BOSS DEFEATED!', {
size: 120,
fill: 0xFFDD00
});
bossDefeatedTxt.anchor.set(0.5, 0.5);
bossDefeatedTxt.x = 2048 / 2;
bossDefeatedTxt.y = 2732 / 2;
game.addChild(bossDefeatedTxt);
// Animate boss defeated text
tween(bossDefeatedTxt, {
scale: 1.5
}, {
duration: 500,
onFinish: function onFinish() {
tween(bossDefeatedTxt, {
scale: 1.0,
alpha: 0
}, {
duration: 800,
onFinish: function onFinish() {
bossDefeatedTxt.destroy();
}
});
}
});
self.destroy();
}
};
return self;
});
var SuperWeapon = Container.expand(function () {
var self = Container.call(this);
var weaponGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2,
alpha: 0.9
});
self.speed = -20;
self.damage = 5;
self.active = true;
self.rotation = 0;
self.update = function () {
if (!self.active) return;
self.y += self.speed;
self.rotation += 0.2;
weaponGraphics.rotation = self.rotation;
};
self.hit = function () {
self.active = false;
// Flash effect
tween(weaponGraphics, {
alpha: 0,
scaleX: 3,
scaleY: 3
}, {
duration: 200,
onFinish: function onFinish() {
self.destroy();
}
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x0a2550 // Deep blue ocean color
});
/****
* Game Code
****/
// Game variables
var player;
var bullets = [];
var pirates = [];
var pirateBullets = [];
var coins = [];
var clouds = []; // Track clouds
var score = 0;
var money = storage.money;
var gameOver = false;
var spawnTimer = 0;
var waveTimer = 0;
var currentWave = 1;
var enemiesThisWave = 5;
var enemiesSpawned = 0;
var healthBar;
var healthBarBg;
var shieldBar;
var autoShoot = true;
var bossSpawned = false;
var cloudSpawnTimer = 0; // Timer for spawning clouds
// Swipe control variables
var startX = 0;
var startY = 0;
var isMoving = false;
var swipeSensitivity = 1.2; // Higher value = more responsive movement
var swipeInertia = 0.9; // Value between 0-1, higher = more inertia
var playerVelocityX = 0;
// UI elements
var scoreTxt;
var waveTxt;
var moneyTxt;
var weaponUpgradeBtn;
var shieldUpgradeBtn;
var weaponLevelTxt;
var shieldLevelTxt;
var specialWeaponBtn;
var specialWeaponTxt;
var weaponStatusTxt;
// Initialize player
function initPlayer() {
player = new CargoShip();
player.x = 2048 / 2;
player.y = 2732 - 200;
game.addChild(player);
// Create health bar background
healthBarBg = LK.getAsset('healthBarBg', {
anchorX: 0,
anchorY: 0,
x: 50,
y: 50
});
game.addChild(healthBarBg);
// Create health bar
healthBar = LK.getAsset('healthBar', {
anchorX: 0,
anchorY: 0,
x: 50,
y: 50
});
game.addChild(healthBar);
// Create shield bar if player has shields
if (player.shieldLevel > 0) {
shieldBar = LK.getAsset('shield', {
anchorX: 0,
anchorY: 0,
x: 50,
y: 90,
height: 20,
width: 500,
alpha: 0.6
});
game.addChild(shieldBar);
}
}
// Initialize UI
function initUI() {
// Score text
scoreTxt = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(scoreTxt);
// Weapon level text removed
// Wave text
waveTxt = new Text2('Wave: 1', {
size: 60,
fill: 0xFFFFFF
});
waveTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(waveTxt);
// Money text
moneyTxt = new Text2('Coins: ' + money, {
size: 60,
fill: 0xFFCC00
});
moneyTxt.anchor.set(0, 0);
moneyTxt.x = 120;
LK.gui.topLeft.addChild(moneyTxt);
// Weapon upgrade button
weaponUpgradeBtn = LK.getAsset('upgradeButton', {
anchorX: 0.5,
anchorY: 0.5
});
weaponUpgradeBtn.x = 2048 / 2 - 350;
weaponUpgradeBtn.y = 2732 - 80;
game.addChild(weaponUpgradeBtn);
// Weapon level text now removed
// Shield upgrade button
shieldUpgradeBtn = LK.getAsset('repairButton', {
anchorX: 0.5,
anchorY: 0.5
});
shieldUpgradeBtn.x = 2048 / 2 + 350;
shieldUpgradeBtn.y = 2732 - 80;
game.addChild(shieldUpgradeBtn);
// Shield level text is removed
// Special weapon button (visible only when weapon level is 3+)
specialWeaponBtn = LK.getAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5,
alpha: 0.8
});
specialWeaponBtn.x = 2048 / 2;
specialWeaponBtn.y = 2732 - 80;
specialWeaponBtn.visible = player.weaponLevel >= 3;
game.addChild(specialWeaponBtn);
// Special weapon text
var specialWeaponTxt = new Text2('SUPER\nATTACK', {
size: 35,
fill: 0xFFFF00
});
specialWeaponTxt.anchor.set(0.5, 0.5);
specialWeaponTxt.x = specialWeaponBtn.x;
specialWeaponTxt.y = specialWeaponBtn.y;
specialWeaponTxt.visible = player.weaponLevel >= 3;
game.addChild(specialWeaponTxt);
}
// Update score display
function updateScore() {
scoreTxt.setText('Score: ' + score);
LK.setScore(score);
}
// Update money display
function updateMoney() {
moneyTxt.setText('Coins: ' + money);
storage.money = money;
}
// Update wave display
function updateWave() {
waveTxt.setText('Wave: ' + currentWave);
}
// Get upgrade cost based on current level
function getUpgradeCost(level) {
return level * 50;
}
// Get shield upgrade cost
function getShieldCost(level) {
return (level + 1) * 80;
}
// Spawn a pirate ship
function spawnPirate() {
var pirateX = Math.random() * (2048 - 300) + 150;
var pirateY = -100;
var pirate;
// Spawn large pirates occasionally, more often in higher waves
if (Math.random() < 0.1 + currentWave * 0.02) {
pirate = new LargePirateShip();
pirate.speed += Math.min(currentWave * 0.1, 1); // Increase speed with wave
} else {
pirate = new PirateShip();
pirate.speed += Math.min(currentWave * 0.2, 2); // Increase speed with wave
pirate.health += Math.floor(currentWave / 3); // Increase health with wave
}
pirate.x = pirateX;
pirate.y = pirateY;
pirates.push(pirate);
game.addChild(pirate);
enemiesSpawned++;
}
// Start a new wave
function startNewWave() {
currentWave++;
enemiesThisWave = 5 + currentWave * 2;
enemiesSpawned = 0;
updateWave();
// Flash wave text
tween(waveTxt, {
scale: 1.5
}, {
duration: 300,
onFinish: function onFinish() {
tween(waveTxt, {
scale: 1.0
}, {
duration: 300
});
}
});
}
// Upgrade weapon
function upgradeWeapon() {
var cost = getUpgradeCost(player.weaponLevel);
if (money >= cost) {
money -= cost;
player.weaponLevel++;
storage.weaponLevel = player.weaponLevel;
updateMoney();
// Update button text
weaponLevelTxt.setText('Upgrade Weapon\n' + getUpgradeCost(player.weaponLevel) + ' coins');
// Update weapon level display
weaponStatusTxt.setText('Weapon Lvl: ' + player.weaponLevel);
// Show special weapon button if level 3+
if (player.weaponLevel >= 3) {
specialWeaponBtn.visible = true;
specialWeaponTxt.visible = true;
}
LK.getSound('upgrade').play();
// Show effect
tween(weaponUpgradeBtn, {
alpha: 0.5
}, {
duration: 200,
onFinish: function onFinish() {
tween(weaponUpgradeBtn, {
alpha: 1.0
}, {
duration: 200
});
}
});
}
}
// Activate super weapon
function activateSuperWeapon() {
// Create super weapon bullet
var superBullet = new SuperWeapon();
superBullet.x = player.x;
superBullet.y = player.y - 100;
superBullet.damage = player.weaponLevel * 2;
bullets.push(superBullet);
game.addChild(superBullet);
// Play special sound
LK.getSound('playerShoot').play();
// Cool visual effect
LK.effects.flashScreen(0x0099FF, 300);
// Make the special weapon button temporarily unavailable
specialWeaponBtn.alpha = 0.3;
specialWeaponTxt.alpha = 0.3;
specialWeaponBtn.interactive = false;
// Reset after cooldown
LK.setTimeout(function () {
specialWeaponBtn.alpha = 0.8;
specialWeaponTxt.alpha = 1;
specialWeaponBtn.interactive = true;
}, 3000);
}
// Upgrade shield function (disabled)
function upgradeShield() {
// Function is now empty as shield upgrading is disabled
}
// Handle touch/mouse events
function handleTouchMove(x, y) {
if (gameOver) return;
// Move player
if (player && player.active) {
if (isMoving) {
// Calculate swipe velocity with sensitivity multiplier
var deltaX = (x - startX) * swipeSensitivity;
// Apply velocity change based on swipe direction and magnitude
playerVelocityX = deltaX;
// Update starting position for next move
startX = x;
}
// Constrain to screen
if (player.x < 250) {
player.x = 250;
playerVelocityX = 0;
}
if (player.x > 2048 - 250) {
player.x = 2048 - 250;
playerVelocityX = 0;
}
}
}
// Game initialization
function initGame() {
// Add background
var background = LK.getAsset('background', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
width: 2048,
height: 2732
});
game.addChild(background);
// Initialize game state
score = 0;
money = storage.money || 1500; // Start with 1500 money for faster upgrades
storage.money = money; // Make sure storage is updated too
gameOver = false;
spawnTimer = 0;
waveTimer = 0;
currentWave = 1;
enemiesThisWave = 5;
enemiesSpawned = 0;
bossSpawned = false;
bullets = [];
pirates = [];
pirateBullets = [];
coins = [];
clouds = [];
cloudSpawnTimer = 0;
// Initialize player and UI first
initPlayer();
initUI();
// Now update displays after UI is initialized
updateScore();
updateMoney();
// Start background music
LK.playMusic('bgMusic');
}
// Touch/mouse events
game.move = function (x, y) {
handleTouchMove(x, y);
};
game.down = function (x, y, obj) {
// Check if clicked on upgrade buttons
if (obj === weaponUpgradeBtn) {
upgradeWeapon();
return;
}
// Shield upgrades disabled
if (obj === shieldUpgradeBtn) {
return;
}
// Check for special weapon button
if (obj === specialWeaponBtn && player.weaponLevel >= 3) {
activateSuperWeapon();
return;
}
// Start tracking swipe
startX = x;
startY = y;
isMoving = true;
playerVelocityX = 0;
// Otherwise move the player
handleTouchMove(x, y);
// Manual shoot on tap
if (player && player.active) {
player.shoot();
}
};
// Handle touch/mouse up
game.up = function (x, y) {
// Stop tracking movement but keep momentum
isMoving = false;
};
// Main game update loop
game.update = function () {
if (gameOver) return;
// Cloud spawning logic
cloudSpawnTimer--;
if (cloudSpawnTimer <= 0) {
// Spawn a new cloud at random x position
var cloud = new Cloud();
cloud.x = Math.random() * 2048;
cloud.y = -200;
clouds.push(cloud);
game.addChild(cloud);
// Reset timer (random interval between 30 and 120 frames)
cloudSpawnTimer = 30 + Math.floor(Math.random() * 90);
}
// Update clouds
for (var i = clouds.length - 1; i >= 0; i--) {
clouds[i].update();
}
// Update player
if (player && player.active) {
// Apply velocity with inertia for smooth movement
player.x += playerVelocityX;
playerVelocityX *= swipeInertia; // Apply inertia to slow down movement gradually
// Constrain to screen boundaries
if (player.x < 250) {
player.x = 250;
playerVelocityX = 0;
}
if (player.x > 2048 - 250) {
player.x = 2048 - 250;
playerVelocityX = 0;
}
player.update();
// Update health bar
var healthRatio = player.health / player.maxHealth;
healthBar.width = 500 * healthRatio;
// Update shield bar
if (player.shieldLevel > 0) {
// Make sure shield bar exists
if (!shieldBar) {
shieldBar = LK.getAsset('shield', {
anchorX: 0,
anchorY: 0,
x: 50,
y: 90,
height: 20,
width: 500,
alpha: 0.6
});
game.addChild(shieldBar);
}
// Update shield bar width
var shieldRatio = player.shieldHealth / player.maxShieldHealth;
shieldBar.width = 500 * shieldRatio;
shieldBar.visible = player.shieldHealth > 0;
// Make sure shield is visible if it should be
if (player.shield) {
player.shield.visible = player.shieldHealth > 0;
}
}
}
// Spawn enemies
spawnTimer--;
if (spawnTimer <= 0 && enemiesSpawned < enemiesThisWave) {
spawnPirate();
spawnTimer = Math.max(30, 90 - currentWave * 5); // Spawn faster in higher waves
}
// Check if wave is complete
if (enemiesSpawned >= enemiesThisWave && pirates.length === 0) {
waveTimer--;
if (waveTimer <= 0) {
// Every 3rd wave, spawn a boss instead of starting a new wave
if (currentWave > 0 && currentWave % 3 === 0 && !bossSpawned) {
// Spawn boss
var boss = new BossShip();
boss.x = 2048 / 2;
boss.y = -200;
pirates.push(boss);
game.addChild(boss);
// Show boss warning
var bossWarningTxt = new Text2('BOSS INCOMING!', {
size: 120,
fill: 0xFF3300
});
bossWarningTxt.anchor.set(0.5, 0.5);
bossWarningTxt.x = 2048 / 2;
bossWarningTxt.y = 2732 / 2;
game.addChild(bossWarningTxt);
// Animate warning text
tween(bossWarningTxt, {
scale: 1.5
}, {
duration: 500,
onFinish: function onFinish() {
tween(bossWarningTxt, {
scale: 1.0,
alpha: 0
}, {
duration: 800,
onFinish: function onFinish() {
bossWarningTxt.destroy();
}
});
}
});
// Flash screen
LK.effects.flashScreen(0xFF3300, 500);
bossSpawned = true;
} else {
startNewWave();
bossSpawned = false;
}
waveTimer = 180; // Delay before next wave
}
}
// Update pirates
for (var i = 0; i < pirates.length; i++) {
pirates[i].update();
}
// Update bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
bullet.update();
// Check for off-screen
if (bullet.y < -50) {
bullet.destroy();
bullets.splice(i, 1);
continue;
}
// Check for collisions with pirates
for (var j = 0; j < pirates.length; j++) {
var pirate = pirates[j];
if (bullet.active && pirate.active && bullet.intersects(pirate)) {
pirate.takeDamage(bullet.damage);
bullet.hit();
break;
}
}
}
// Update pirate bullets
for (var i = pirateBullets.length - 1; i >= 0; i--) {
var bullet = pirateBullets[i];
bullet.update();
// Check for off-screen
if (bullet.y > 2732 + 50) {
bullet.destroy();
pirateBullets.splice(i, 1);
continue;
}
// Check for collision with player
if (bullet.active && player && player.active && bullet.intersects(player)) {
player.takeDamage(bullet.damage);
bullet.hit();
pirateBullets.splice(i, 1);
}
}
// Update coins
for (var i = coins.length - 1; i >= 0; i--) {
var coin = coins[i];
// Apply physics
coin.y += coin.vy;
coin.x += coin.vx;
coin.vy += 0.1; // Gravity
// Enhanced coin magnet effect - attract coins to player from farther with more force
if (player && player.active && Math.abs(coin.x - player.x) < 1200 && Math.abs(coin.y - player.y) < 800) {
var dx = player.x - coin.x;
var dy = player.y - coin.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 0) {
coin.vx += dx / dist * 6;
coin.vy += dy / dist * 6;
}
}
// Update sprite position
coin.sprite.x = coin.x;
coin.sprite.y = coin.y;
// Check if coin is collected with increased collection radius
if (player && player.active && Math.abs(coin.x - player.x) < 500 && Math.abs(coin.y - player.y) < 300) {
coin.sprite.destroy();
coins.splice(i, 1);
money += 10; // Double coin value to 10 for faster money collection
updateMoney();
LK.getSound('coinPickup').play();
continue;
}
// Remove if off screen
if (coin.y > 2732 + 50) {
coin.sprite.destroy();
coins.splice(i, 1);
}
}
};
// Initialize the game
initGame();