/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { healthUpgrades: 0, ammoUpgrades: 0, speedUpgrades: 0, coins: 0, healthUpgradeCost: 200, ammoUpgradeCost: 100, speedUpgradeCost: 300, hasShotgun: false, hasMachinegun: false }); /**** * Classes ****/ var BossZombie = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('bossZombie', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 0.5 + Math.random() * 0.3; // Slower than normal zombies self.health = 10; // Much higher health self.damage = 25; // Higher damage self.lastPlayerCollision = false; self.scaleX = 1.0; // Normal size self.scaleY = 1.0; self.update = function () { var dx = player.x - self.x; var dy = player.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } var currentCollision = self.intersects(player); if (!self.lastPlayerCollision && currentCollision) { player.takeDamage(self.damage); // Boss zombie dies from collision but doesn't give coins self.health = 0; LK.effects.flashObject(self, 0xffffff, 100); var index = zombies.indexOf(self); if (index > -1) { zombies.splice(index, 1); } self.destroy(); } self.lastPlayerCollision = currentCollision; }; self.takeDamage = function (damage) { self.health -= damage; if (self.health <= 0) { LK.effects.flashObject(self, 0xffffff, 100); LK.setScore(LK.getScore() + 10000); // 10000 score for boss storage.coins += 10000; // 10000 coins for boss if (soundEnabled) LK.getSound('zombieHit').play(); var index = zombies.indexOf(self); if (index > -1) { zombies.splice(index, 1); } self.destroy(); // Unlock map when boss is defeated if (isSecondMap) { mapLocked = false; storage.mapLocked = false; } // Show custom congratulations screen when boss is killed showCongratulations(); } }; return self; }); var Bullet = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 8; self.dx = 0; self.dy = 0; self.lifetime = 120; self.update = function () { self.x += self.dx * self.speed; self.y += self.dy * self.speed; // Rotate bullet to face movement direction graphics.rotation = Math.atan2(self.dy, self.dx); self.lifetime--; if (self.lifetime <= 0 || self.isOutOfBounds()) { self.remove(); return; } for (var i = 0; i < zombies.length; i++) { var zombie = zombies[i]; if (self.intersects(zombie)) { zombie.takeDamage(1); self.remove(); return; } } }; self.isOutOfBounds = function () { return self.x < 0 || self.x > 2048 || self.y < 0 || self.y > 2732; }; self.remove = function () { var index = bullets.indexOf(self); if (index > -1) { bullets.splice(index, 1); } self.destroy(); }; return self; }); var IceBoss = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('iceBoss', { anchorX: 0.5, anchorY: 0.5 }); graphics.tint = 0x87CEEB; // Light blue tint for ice effect self.speed = 0.8 + Math.random() * 0.4; // Faster than regular boss self.health = 15; // Higher health than regular boss self.damage = 30; // Higher damage than regular boss self.lastPlayerCollision = false; self.scaleX = 6.0; // 6.0 times larger than player (even bigger) self.scaleY = 6.0; self.update = function () { var dx = player.x - self.x; var dy = player.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } var currentCollision = self.intersects(player); if (!self.lastPlayerCollision && currentCollision) { player.takeDamage(self.damage); // Ice boss dies from collision but doesn't give coins self.health = 0; LK.effects.flashObject(self, 0x87CEEB, 100); var index = zombies.indexOf(self); if (index > -1) { zombies.splice(index, 1); } self.destroy(); } self.lastPlayerCollision = currentCollision; }; self.takeDamage = function (damage) { self.health -= damage; if (self.health <= 0) { LK.effects.flashObject(self, 0x87CEEB, 100); LK.setScore(LK.getScore() + 15000); // 15000 score for ice boss storage.coins += 15000; // 15000 coins for ice boss if (soundEnabled) LK.getSound('zombieHit').play(); var index = zombies.indexOf(self); if (index > -1) { zombies.splice(index, 1); } self.destroy(); // Unlock map when ice boss is defeated if (isSecondMap) { mapLocked = false; storage.mapLocked = false; } // Show custom congratulations screen when ice boss is killed showCongratulations(); } }; return self; }); var IceMonster = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('iceMonster', { anchorX: 0.5, anchorY: 0.5 }); graphics.tint = 0x87CEEB; // Light blue tint for ice effect self.speed = 1.5 + Math.random() * 0.7; // Slightly faster than normal zombies self.health = 2; // Higher health than normal zombies self.damage = 15; // Higher damage than normal zombies self.lastPlayerCollision = false; self.update = function () { var dx = player.x - self.x; var dy = player.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } var currentCollision = self.intersects(player); if (!self.lastPlayerCollision && currentCollision) { player.takeDamage(self.damage); // Ice monster dies from collision but doesn't give coins self.health = 0; LK.effects.flashObject(self, 0x87CEEB, 100); var index = zombies.indexOf(self); if (index > -1) { zombies.splice(index, 1); } self.destroy(); } self.lastPlayerCollision = currentCollision; }; self.takeDamage = function (damage) { self.health -= damage; if (self.health <= 0) { LK.effects.flashObject(self, 0x87CEEB, 100); LK.setScore(LK.getScore() + 15); storage.coins += 150; zombiesKilledInWave++; // Track zombie kills if (soundEnabled) LK.getSound('iceMhit').play(); var index = zombies.indexOf(self); if (index > -1) { zombies.splice(index, 1); } self.destroy(); } }; return self; }); var MachinegunBullet = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('machinegunBullet', { anchorX: 0.5, anchorY: 0.5 }); graphics.tint = 0x00ff00; // Green tint to differentiate from other bullets self.speed = 12; // Faster than normal bullets self.dx = 0; self.dy = 0; self.lifetime = 120; // Same lifetime as normal bullets self.update = function () { self.x += self.dx * self.speed; self.y += self.dy * self.speed; // Rotate bullet to face movement direction graphics.rotation = Math.atan2(self.dy, self.dx); self.lifetime--; if (self.lifetime <= 0 || self.isOutOfBounds()) { self.remove(); return; } for (var i = 0; i < zombies.length; i++) { var zombie = zombies[i]; if (self.intersects(zombie)) { zombie.takeDamage(1); self.remove(); return; } } }; self.isOutOfBounds = function () { return self.x < 0 || self.x > 2048 || self.y < 0 || self.y > 2732; }; self.remove = function () { var index = bullets.indexOf(self); if (index > -1) { bullets.splice(index, 1); } self.destroy(); }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.health = 100; self.maxHealth = 100; self.ammo = 30; self.maxAmmo = 30; self.shootCooldown = 0; self.baseShootCooldown = 10; self.weaponType = 'normal'; self.update = function () { if (self.shootCooldown > 0) { self.shootCooldown--; } }; self.takeDamage = function (damage) { self.health -= damage; if (soundEnabled) LK.getSound('playerHit').play(); if (self.health <= 0) { self.health = 0; LK.effects.flashScreen(0xff0000, 1000); showCustomGameOver(); } else { LK.effects.flashObject(self, 0xff0000, 200); } }; self.canShoot = function () { return self.ammo > 0 && self.shootCooldown <= 0; }; self.shoot = function () { if (self.canShoot()) { self.ammo--; if (self.weaponType === 'machinegun') { self.shootCooldown = Math.max(1, self.baseShootCooldown - 5); // Faster fire rate } else { self.shootCooldown = self.baseShootCooldown; } return true; } return false; }; return self; }); var ShotgunBullet = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('shotgunBullet', { anchorX: 0.5, anchorY: 0.5 }); graphics.tint = 0xffaa00; // Orange tint to differentiate from normal bullets self.speed = 8; self.dx = 0; self.dy = 0; self.lifetime = 100; // Shorter lifetime than normal bullets self.update = function () { self.x += self.dx * self.speed; self.y += self.dy * self.speed; // Rotate bullet to face movement direction graphics.rotation = Math.atan2(self.dy, self.dx); self.lifetime--; if (self.lifetime <= 0 || self.isOutOfBounds()) { self.remove(); return; } for (var i = 0; i < zombies.length; i++) { var zombie = zombies[i]; if (self.intersects(zombie)) { zombie.takeDamage(1); self.remove(); return; } } }; self.isOutOfBounds = function () { return self.x < 0 || self.x > 2048 || self.y < 0 || self.y > 2732; }; self.remove = function () { var index = bullets.indexOf(self); if (index > -1) { bullets.splice(index, 1); } self.destroy(); }; return self; }); var Zombie = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('zombie', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 1 + Math.random() * 0.5; self.health = 1; self.damage = 10; self.lastPlayerCollision = false; self.update = function () { var dx = player.x - self.x; var dy = player.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } var currentCollision = self.intersects(player); if (!self.lastPlayerCollision && currentCollision) { player.takeDamage(self.damage); // Zombie dies from collision but doesn't give coins self.health = 0; LK.effects.flashObject(self, 0xffffff, 100); var index = zombies.indexOf(self); if (index > -1) { zombies.splice(index, 1); } self.destroy(); } self.lastPlayerCollision = currentCollision; }; self.takeDamage = function (damage) { self.health -= damage; if (self.health <= 0) { LK.effects.flashObject(self, 0xffffff, 100); LK.setScore(LK.getScore() + 10); storage.coins += 100; zombiesKilledInWave++; // Track zombie kills if (soundEnabled) LK.getSound('zombieHit').play(); var index = zombies.indexOf(self); if (index > -1) { zombies.splice(index, 1); } self.destroy(); } }; return self; }); var Zombie2 = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('zombie2', { anchorX: 0.5, anchorY: 0.5 }); graphics.tint = 0xff6b6b; // Reddish tint to differentiate self.speed = 1 + Math.random() * 0.5; self.health = 1; self.damage = 10; self.lastPlayerCollision = false; self.update = function () { var dx = player.x - self.x; var dy = player.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } var currentCollision = self.intersects(player); if (!self.lastPlayerCollision && currentCollision) { player.takeDamage(self.damage); // Zombie dies from collision but doesn't give coins self.health = 0; LK.effects.flashObject(self, 0xffffff, 100); var index = zombies.indexOf(self); if (index > -1) { zombies.splice(index, 1); } self.destroy(); } self.lastPlayerCollision = currentCollision; }; self.takeDamage = function (damage) { self.health -= damage; if (self.health <= 0) { LK.effects.flashObject(self, 0xffffff, 100); LK.setScore(LK.getScore() + 10); storage.coins += 100; zombiesKilledInWave++; // Track zombie kills if (soundEnabled) LK.getSound('zombieHit').play(); var index = zombies.indexOf(self); if (index > -1) { zombies.splice(index, 1); } self.destroy(); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2d2d2d }); /**** * Game Code ****/ var arena; if (isSecondMap) { arena = game.attachAsset('secondMap', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, scaleX: 1.14, scaleY: 1.52 }); } else { arena = game.attachAsset('secondMap', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, scaleX: 1.14, scaleY: 1.52 }); } var player = game.addChild(new Player()); player.x = 2048 / 2; player.y = 2732 / 2; player.scaleX = 1.0; player.scaleY = 1.0; // Apply stored upgrades player.maxHealth = 100 + storage.healthUpgrades * 20; player.health = player.maxHealth; player.maxAmmo = 30 + storage.ammoUpgrades * 10; player.ammo = player.maxAmmo; player.baseShootCooldown = Math.max(1, 10 - storage.speedUpgrades); // Weapon status display - define early so it can be used in game.update var weaponStatus = new Text2('Weapon: ' + (player.weaponType || 'Normal'), { size: 60, fill: 0xFFFFFF }); // Function to update weapon button colors function updateWeaponButtons() { if (normalWeaponButton) { normalWeaponButton.tint = player.weaponType === 'normal' ? 0x4CAF50 : 0x666666; } if (shotgunWeaponButton) { shotgunWeaponButton.tint = player.weaponType === 'shotgun' ? 0x4CAF50 : 0x666666; } if (machinegunWeaponButton) { machinegunWeaponButton.tint = player.weaponType === 'machinegun' ? 0x4CAF50 : 0x666666; } weaponStatus.setText('Weapon: ' + (player.weaponType || 'Normal')); } var zombies = []; var bullets = []; var waveNumber = 1; var zombiesInWave = 5; var zombiesSpawned = 0; var spawnTimer = 0; var gameOverScreen = null; var showingGameOver = false; var showingMarket = false; var marketPanel = null; var isPaused = false; var pausePanel = null; var isBossWave = false; var isFirstShot = true; var zombiesKilledInWave = 0; var zombiesRequiredToKill = 8; var isSecondMap = storage.isSecondMap || false; // Track which map we're on, persist in storage var mapLocked = storage.mapLocked || false; // Track if map is locked until boss defeat // Upgrade costs that increase with each purchase - loaded from storage var healthUpgradeCost = storage.healthUpgradeCost; var ammoUpgradeCost = storage.ammoUpgradeCost; var speedUpgradeCost = storage.speedUpgradeCost; var healthBackground = LK.getAsset('Tahta', { width: 300, height: 60, anchorX: 0, anchorY: 1, x: 120, y: 0 }); healthBackground.alpha = 0.7; LK.gui.bottomLeft.addChild(healthBackground); var healthBar = new Text2('Health: 100', { size: 60, fill: 0xFF0000 }); healthBar.anchor.set(0, 1); healthBar.x = 120; // Move away from bottom-left corner LK.gui.bottomLeft.addChild(healthBar); var ammoBackground = LK.getAsset('Tahta', { width: 300, height: 60, anchorX: 0, anchorY: 1, x: 120, y: -70 }); ammoBackground.alpha = 0.7; LK.gui.bottomLeft.addChild(ammoBackground); var ammoDisplay = new Text2('Ammo: 30', { size: 60, fill: 0x00FF00 }); ammoDisplay.anchor.set(0, 1); ammoDisplay.x = 120; // Move away from bottom-left corner ammoDisplay.y = -70; LK.gui.bottomLeft.addChild(ammoDisplay); var waveBackground = LK.getAsset('Tahta', { width: 300, height: 60, anchorX: 0, anchorY: 1, x: 120, y: -140 }); waveBackground.alpha = 0.7; LK.gui.bottomLeft.addChild(waveBackground); var waveInfo = new Text2('Wave: 1', { size: 60, fill: 0xFFFF00 }); waveInfo.anchor.set(0, 1); waveInfo.x = 120; // Move away from bottom-left corner waveInfo.y = -140; LK.gui.bottomLeft.addChild(waveInfo); var killProgressBackground = LK.getAsset('Tahta', { width: 350, height: 60, anchorX: 0, anchorY: 1, x: 120, y: -210 }); killProgressBackground.alpha = 0.7; LK.gui.bottomLeft.addChild(killProgressBackground); var killProgress = new Text2('Kills: 0/8', { size: 60, fill: 0xFF6B6B }); killProgress.anchor.set(0, 1); killProgress.x = 120; killProgress.y = -210; LK.gui.bottomLeft.addChild(killProgress); var scoreBackground = LK.getAsset('Tahta', { width: 350, height: 90, anchorX: 0.5, anchorY: 0, x: 0, y: 0 }); scoreBackground.alpha = 0.7; LK.gui.top.addChild(scoreBackground); var scoreDisplay = new Text2('SCORE: 0', { size: 80, fill: 0xFFFFFF }); scoreDisplay.anchor.set(0.5, 0); LK.gui.top.addChild(scoreDisplay); var coinBackground = LK.getAsset('Tahta', { width: 300, height: 70, anchorX: 0.5, anchorY: 0, x: 0, y: 90 }); coinBackground.alpha = 0.7; LK.gui.top.addChild(coinBackground); var coinDisplay = new Text2('COIN: ' + storage.coins, { size: 60, fill: 0xFFD700 }); coinDisplay.anchor.set(0.5, 0); coinDisplay.y = 90; LK.gui.top.addChild(coinDisplay); function showCustomGameOver() { if (showingGameOver) return; showingGameOver = true; gameOverScreen = new Container(); // Semi-transparent background var background = LK.getAsset('arena', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, scaleX: 4, scaleY: 4 }); background.alpha = 0.8; background.tint = 0x000000; gameOverScreen.addChild(background); // Game Over title var gameOverTitle = new Text2('GAME OVER', { size: 140, fill: 0xFF0000 }); gameOverTitle.anchor.set(0.5, 0.5); gameOverTitle.x = 2048 / 2; gameOverTitle.y = 2732 / 2 - 200; gameOverScreen.addChild(gameOverTitle); // Final score display var finalScore = new Text2('Final Score: ' + LK.getScore(), { size: 100, fill: 0xFFFFFF }); finalScore.anchor.set(0.5, 0.5); finalScore.x = 2048 / 2; finalScore.y = 2732 / 2 - 100; gameOverScreen.addChild(finalScore); // Market button var marketButton = LK.getAsset('marketButton', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 + 50 }); marketButton.tint = 0x2196F3; marketButton.down = function (x, y, obj) { showMarket(); }; gameOverScreen.addChild(marketButton); var marketText = new Text2('MARKET', { size: 80, fill: 0xFFFFFF }); marketText.anchor.set(0.5, 0.5); marketText.x = 2048 / 2; marketText.y = 2732 / 2 + 50; gameOverScreen.addChild(marketText); // Restart button var restartButton = LK.getAsset('marketButton', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 + 150 }); restartButton.tint = 0xFF5722; restartButton.down = function (x, y, obj) { restartGame(); }; gameOverScreen.addChild(restartButton); var restartText = new Text2('RESTART', { size: 80, fill: 0xFFFFFF }); restartText.anchor.set(0.5, 0.5); restartText.x = 2048 / 2; restartText.y = 2732 / 2 + 150; gameOverScreen.addChild(restartText); game.addChild(gameOverScreen); } function showCongratulations() { if (showingGameOver) return; showingGameOver = true; gameOverScreen = new Container(); // Semi-transparent background var background = LK.getAsset('arena', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, scaleX: 4, scaleY: 4 }); background.alpha = 0.9; background.tint = 0x0a0a1a; gameOverScreen.addChild(background); // Main victory panel background var victoryPanel = LK.getAsset('Tahta', { width: 1800, height: 2000, anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 }); victoryPanel.alpha = 0.95; victoryPanel.tint = 0x1a4a2a; gameOverScreen.addChild(victoryPanel); // Victory crown/trophy icon var crownIcon = new Text2('👑', { size: 200, fill: 0xFFD700 }); crownIcon.anchor.set(0.5, 0.5); crownIcon.x = 2048 / 2; crownIcon.y = 2732 / 2 - 650; gameOverScreen.addChild(crownIcon); // Congratulations title with enhanced styling var congratsTitle = new Text2('VICTORY!', { size: 180, fill: 0xFFD700 }); congratsTitle.anchor.set(0.5, 0.5); congratsTitle.x = 2048 / 2; congratsTitle.y = 2732 / 2 - 450; gameOverScreen.addChild(congratsTitle); // Victory subtitle var victorySubtitle = new Text2('BOSS ELIMINATED', { size: 100, fill: 0x90EE90 }); victorySubtitle.anchor.set(0.5, 0.5); victorySubtitle.x = 2048 / 2; victorySubtitle.y = 2732 / 2 - 320; gameOverScreen.addChild(victorySubtitle); // Statistics panel background var statsPanel = LK.getAsset('Tahta', { width: 1500, height: 300, anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 - 100 }); statsPanel.alpha = 0.8; statsPanel.tint = 0x2a2a4a; gameOverScreen.addChild(statsPanel); // Final score display with background var scoreLabel = new Text2('FINAL SCORE', { size: 70, fill: 0xFFD700 }); scoreLabel.anchor.set(0.5, 0.5); scoreLabel.x = 2048 / 2; scoreLabel.y = 2732 / 2 - 150; gameOverScreen.addChild(scoreLabel); var finalScore = new Text2(LK.getScore().toString(), { size: 120, fill: 0xFFFFFF }); finalScore.anchor.set(0.5, 0.5); finalScore.x = 2048 / 2; finalScore.y = 2732 / 2 - 50; gameOverScreen.addChild(finalScore); // Coins earned display var coinsEarned = new Text2('💰 Coins Earned: ' + (isSecondMap ? '15,000' : '10,000'), { size: 80, fill: 0xFFD700 }); coinsEarned.anchor.set(0.5, 0.5); coinsEarned.x = 2048 / 2; coinsEarned.y = 2732 / 2 + 50; gameOverScreen.addChild(coinsEarned); // Action buttons with enhanced styling // Market button var marketButtonBg = LK.getAsset('Tahta', { width: 600, height: 120, anchorX: 0.5, anchorY: 0.5, x: 2048 / 2 - 350, y: 2732 / 2 + 250 }); marketButtonBg.alpha = 0.9; marketButtonBg.tint = 0x2196F3; gameOverScreen.addChild(marketButtonBg); var marketButton = LK.getAsset('marketButton', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2 - 350, y: 2732 / 2 + 250 }); marketButton.alpha = 0.01; marketButton.down = function (x, y, obj) { showMarket(); }; gameOverScreen.addChild(marketButton); var marketIcon = new Text2('🛒', { size: 60, fill: 0xFFFFFF }); marketIcon.anchor.set(0.5, 0.5); marketIcon.x = 2048 / 2 - 400; marketIcon.y = 2732 / 2 + 250; gameOverScreen.addChild(marketIcon); var marketText = new Text2('SHOP', { size: 70, fill: 0xFFFFFF }); marketText.anchor.set(0.5, 0.5); marketText.x = 2048 / 2 - 300; marketText.y = 2732 / 2 + 250; gameOverScreen.addChild(marketText); // Restart button var restartButtonBg = LK.getAsset('Tahta', { width: 600, height: 120, anchorX: 0.5, anchorY: 0.5, x: 2048 / 2 + 350, y: 2732 / 2 + 250 }); restartButtonBg.alpha = 0.9; restartButtonBg.tint = 0x4CAF50; gameOverScreen.addChild(restartButtonBg); var restartButton = LK.getAsset('marketButton', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2 + 350, y: 2732 / 2 + 250 }); restartButton.alpha = 0.01; restartButton.down = function (x, y, obj) { restartGame(); }; gameOverScreen.addChild(restartButton); var restartIcon = new Text2('🔄', { size: 60, fill: 0xFFFFFF }); restartIcon.anchor.set(0.5, 0.5); restartIcon.x = 2048 / 2 + 300; restartIcon.y = 2732 / 2 + 250; gameOverScreen.addChild(restartIcon); var restartText = new Text2('PLAY AGAIN', { size: 60, fill: 0xFFFFFF }); restartText.anchor.set(0.5, 0.5); restartText.x = 2048 / 2 + 400; restartText.y = 2732 / 2 + 250; gameOverScreen.addChild(restartText); // Continue playing button var continueButtonBg = LK.getAsset('Tahta', { width: 1200, height: 120, anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 + 400 }); continueButtonBg.alpha = 0.9; continueButtonBg.tint = 0xFF9800; gameOverScreen.addChild(continueButtonBg); var continueButton = LK.getAsset('marketButton', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 + 400 }); continueButton.alpha = 0.01; continueButton.down = function (x, y, obj) { hideGameOver(); // Continue the game without restarting }; gameOverScreen.addChild(continueButton); var continueIcon = new Text2('⚡', { size: 60, fill: 0xFFFFFF }); continueIcon.anchor.set(0.5, 0.5); continueIcon.x = 2048 / 2 - 150; continueIcon.y = 2732 / 2 + 400; gameOverScreen.addChild(continueIcon); var continueText = new Text2('CONTINUE SURVIVING', { size: 70, fill: 0xFFFFFF }); continueText.anchor.set(0.5, 0.5); continueText.x = 2048 / 2 + 50; continueText.y = 2732 / 2 + 400; gameOverScreen.addChild(continueText); // Achievement badge var achievementBadge = LK.getAsset('Tahta', { width: 400, height: 150, anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 + 550 }); achievementBadge.alpha = 0.8; achievementBadge.tint = 0x8B4513; gameOverScreen.addChild(achievementBadge); var achievementText = new Text2('🏆 BOSS SLAYER 🏆', { size: 60, fill: 0xFFD700 }); achievementText.anchor.set(0.5, 0.5); achievementText.x = 2048 / 2; achievementText.y = 2732 / 2 + 550; gameOverScreen.addChild(achievementText); game.addChild(gameOverScreen); } function hideGameOver() { if (gameOverScreen) { gameOverScreen.destroy(); gameOverScreen = null; } showingGameOver = false; } function showMarket() { if (showingMarket) return; showingMarket = true; marketPanel = new Container(); // Semi-transparent background var background = LK.getAsset('arena', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, scaleX: 4, scaleY: 4 }); background.alpha = 0.95; background.tint = 0x1a1a1a; marketPanel.addChild(background); // Main market panel background var mainPanel = LK.getAsset('Tahta', { width: 1800, height: 2200, anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 }); mainPanel.alpha = 0.95; mainPanel.tint = 0x2a2a2a; marketPanel.addChild(mainPanel); // Market title with enhanced styling var marketTitle = new Text2('🛒 MARKET', { size: 160, fill: 0xFFD700 }); marketTitle.anchor.set(0.5, 0.5); marketTitle.x = 2048 / 2; marketTitle.y = 2732 / 2 - 850; marketPanel.addChild(marketTitle); // Current coins display with enhanced styling var currentCoins = storage.coins; var coinPanel = LK.getAsset('Tahta', { width: 600, height: 120, anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 - 700 }); coinPanel.alpha = 0.9; coinPanel.tint = 0x4a4a4a; marketPanel.addChild(coinPanel); var scoreText = new Text2('💰 COINS: ' + storage.coins, { size: 100, fill: 0xFFD700 }); scoreText.anchor.set(0.5, 0.5); scoreText.x = 2048 / 2; scoreText.y = 2732 / 2 - 700; marketPanel.addChild(scoreText); // Health upgrade section var healthSection = LK.getAsset('Tahta', { width: 1600, height: 200, anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 - 450 }); healthSection.alpha = 0.8; healthSection.tint = 0x4CAF50; marketPanel.addChild(healthSection); var healthIcon = new Text2('❤️', { size: 120, fill: 0xFFFFFF }); healthIcon.anchor.set(0.5, 0.5); healthIcon.x = 2048 / 2 - 650; healthIcon.y = 2732 / 2 - 450; marketPanel.addChild(healthIcon); var healthTitle = new Text2('HEALTH BOOST', { size: 80, fill: 0xFFFFFF }); healthTitle.anchor.set(0, 0.5); healthTitle.x = 2048 / 2 - 550; healthTitle.y = 2732 / 2 - 480; marketPanel.addChild(healthTitle); var healthDesc = new Text2('+20 Max Health & Heal', { size: 60, fill: 0xE8F5E8 }); healthDesc.anchor.set(0, 0.5); healthDesc.x = 2048 / 2 - 550; healthDesc.y = 2732 / 2 - 420; marketPanel.addChild(healthDesc); var healthCost = new Text2('💰 ' + healthUpgradeCost, { size: 90, fill: storage.coins >= healthUpgradeCost ? 0xFFD700 : 0xFF4444 }); healthCost.anchor.set(1, 0.5); healthCost.x = 2048 / 2 + 650; healthCost.y = 2732 / 2 - 450; marketPanel.addChild(healthCost); var healthUpgrade = LK.getAsset('marketButton', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 - 450 }); healthUpgrade.alpha = 0.01; healthUpgrade.down = function (x, y, obj) { if (storage.coins >= healthUpgradeCost) { storage.coins -= healthUpgradeCost; healthUpgradeCost = Math.floor(healthUpgradeCost * 1.5); // Increase cost by 50% storage.healthUpgradeCost = healthUpgradeCost; // Save to storage storage.healthUpgrades++; player.maxHealth += 20; player.health = Math.min(player.health + 20, player.maxHealth); coinDisplay.setText('COIN: ' + storage.coins); LK.getSound('coinPurchase').play(); hideMarket(); showMarket(); // Refresh market display } }; marketPanel.addChild(healthUpgrade); // Ammo upgrade section var ammoSection = LK.getAsset('Tahta', { width: 1600, height: 200, anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 - 200 }); ammoSection.alpha = 0.8; ammoSection.tint = 0x2196F3; marketPanel.addChild(ammoSection); var ammoIcon = new Text2('🔫', { size: 120, fill: 0xFFFFFF }); ammoIcon.anchor.set(0.5, 0.5); ammoIcon.x = 2048 / 2 - 650; ammoIcon.y = 2732 / 2 - 200; marketPanel.addChild(ammoIcon); var ammoTitle = new Text2('AMMO BOOST', { size: 80, fill: 0xFFFFFF }); ammoTitle.anchor.set(0, 0.5); ammoTitle.x = 2048 / 2 - 550; ammoTitle.y = 2732 / 2 - 230; marketPanel.addChild(ammoTitle); var ammoDesc = new Text2('+10 Max Ammo & Reload', { size: 60, fill: 0xE3F2FD }); ammoDesc.anchor.set(0, 0.5); ammoDesc.x = 2048 / 2 - 550; ammoDesc.y = 2732 / 2 - 170; marketPanel.addChild(ammoDesc); var ammoCost = new Text2('💰 ' + ammoUpgradeCost, { size: 90, fill: storage.coins >= ammoUpgradeCost ? 0xFFD700 : 0xFF4444 }); ammoCost.anchor.set(1, 0.5); ammoCost.x = 2048 / 2 + 650; ammoCost.y = 2732 / 2 - 200; marketPanel.addChild(ammoCost); var ammoUpgrade = LK.getAsset('marketButton', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 - 200 }); ammoUpgrade.alpha = 0.01; ammoUpgrade.down = function (x, y, obj) { if (storage.coins >= ammoUpgradeCost) { storage.coins -= ammoUpgradeCost; ammoUpgradeCost = Math.floor(ammoUpgradeCost * 1.5); // Increase cost by 50% storage.ammoUpgradeCost = ammoUpgradeCost; // Save to storage storage.ammoUpgrades++; player.maxAmmo += 10; player.ammo = Math.min(player.ammo + 10, player.maxAmmo); coinDisplay.setText('COIN: ' + storage.coins); LK.getSound('coinPurchase').play(); hideMarket(); showMarket(); // Refresh market display } }; marketPanel.addChild(ammoUpgrade); // Speed upgrade section var speedSection = LK.getAsset('Tahta', { width: 1600, height: 200, anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 + 50 }); speedSection.alpha = 0.8; speedSection.tint = 0xFF9800; marketPanel.addChild(speedSection); var speedIcon = new Text2('⚡', { size: 120, fill: 0xFFFFFF }); speedIcon.anchor.set(0.5, 0.5); speedIcon.x = 2048 / 2 - 650; speedIcon.y = 2732 / 2 + 50; marketPanel.addChild(speedIcon); var speedTitle = new Text2('FIRE RATE BOOST', { size: 80, fill: 0xFFFFFF }); speedTitle.anchor.set(0, 0.5); speedTitle.x = 2048 / 2 - 550; speedTitle.y = 2732 / 2 + 20; marketPanel.addChild(speedTitle); var speedDesc = new Text2('Shoot Faster!', { size: 60, fill: 0xFFF3E0 }); speedDesc.anchor.set(0, 0.5); speedDesc.x = 2048 / 2 - 550; speedDesc.y = 2732 / 2 + 80; marketPanel.addChild(speedDesc); var speedCost = new Text2('💰 ' + speedUpgradeCost, { size: 90, fill: storage.coins >= speedUpgradeCost ? 0xFFD700 : 0xFF4444 }); speedCost.anchor.set(1, 0.5); speedCost.x = 2048 / 2 + 650; speedCost.y = 2732 / 2 + 50; marketPanel.addChild(speedCost); var speedUpgrade = LK.getAsset('marketButton', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 + 50 }); speedUpgrade.alpha = 0.01; speedUpgrade.down = function (x, y, obj) { if (storage.coins >= speedUpgradeCost) { storage.coins -= speedUpgradeCost; speedUpgradeCost = Math.floor(speedUpgradeCost * 1.5); // Increase cost by 50% storage.speedUpgradeCost = speedUpgradeCost; // Save to storage storage.speedUpgrades++; player.baseShootCooldown = Math.max(1, player.baseShootCooldown - 1); coinDisplay.setText('COIN: ' + storage.coins); LK.getSound('coinPurchase').play(); hideMarket(); showMarket(); // Refresh market display } }; marketPanel.addChild(speedUpgrade); // Shotgun weapon section var shotgunSection = LK.getAsset('Tahta', { width: 1600, height: 200, anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 + 300 }); shotgunSection.alpha = 0.8; shotgunSection.tint = 0x795548; marketPanel.addChild(shotgunSection); var shotgunIcon = new Text2('🔫', { size: 120, fill: 0xFFFFFF }); shotgunIcon.anchor.set(0.5, 0.5); shotgunIcon.x = 2048 / 2 - 650; shotgunIcon.y = 2732 / 2 + 300; marketPanel.addChild(shotgunIcon); var shotgunTitle = new Text2('POMPALΙ TÜFEK', { size: 80, fill: 0xFFFFFF }); shotgunTitle.anchor.set(0, 0.5); shotgunTitle.x = 2048 / 2 - 550; shotgunTitle.y = 2732 / 2 + 270; marketPanel.addChild(shotgunTitle); var shotgunDesc = new Text2('Spread Shot +5 Bullets', { size: 60, fill: 0xEFEBE9 }); shotgunDesc.anchor.set(0, 0.5); shotgunDesc.x = 2048 / 2 - 550; shotgunDesc.y = 2732 / 2 + 330; marketPanel.addChild(shotgunDesc); var shotgunCost = new Text2(storage.hasShotgun ? 'SATILDI' : '💰 500', { size: 90, fill: storage.hasShotgun ? 0x888888 : storage.coins >= 500 ? 0xFFD700 : 0xFF4444 }); shotgunCost.anchor.set(1, 0.5); shotgunCost.x = 2048 / 2 + 650; shotgunCost.y = 2732 / 2 + 300; marketPanel.addChild(shotgunCost); var shotgunUpgrade = LK.getAsset('marketButton', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 + 300 }); shotgunUpgrade.alpha = 0.01; shotgunUpgrade.down = function (x, y, obj) { if (!storage.hasShotgun && storage.coins >= 500) { storage.coins -= 500; storage.hasShotgun = true; player.weaponType = 'shotgun'; coinDisplay.setText('COIN: ' + storage.coins); LK.getSound('coinPurchase').play(); hideMarket(); showMarket(); // Refresh market display } }; marketPanel.addChild(shotgunUpgrade); // Machine gun weapon section var machinegunSection = LK.getAsset('Tahta', { width: 1600, height: 200, anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 + 550 }); machinegunSection.alpha = 0.8; machinegunSection.tint = 0x607D8B; marketPanel.addChild(machinegunSection); var machinegunIcon = new Text2('🔫', { size: 120, fill: 0xFFFFFF }); machinegunIcon.anchor.set(0.5, 0.5); machinegunIcon.x = 2048 / 2 - 650; machinegunIcon.y = 2732 / 2 + 550; marketPanel.addChild(machinegunIcon); var machinegunTitle = new Text2('HAFİF MAKİNELİ TÜFEK', { size: 80, fill: 0xFFFFFF }); machinegunTitle.anchor.set(0, 0.5); machinegunTitle.x = 2048 / 2 - 550; machinegunTitle.y = 2732 / 2 + 520; marketPanel.addChild(machinegunTitle); var machinegunDesc = new Text2('Rapid Fire Mode', { size: 60, fill: 0xECEFF1 }); machinegunDesc.anchor.set(0, 0.5); machinegunDesc.x = 2048 / 2 - 550; machinegunDesc.y = 2732 / 2 + 580; marketPanel.addChild(machinegunDesc); var machinegunCost = new Text2(storage.hasMachinegun ? 'SATILDI' : '💰 800', { size: 90, fill: storage.hasMachinegun ? 0x888888 : storage.coins >= 800 ? 0xFFD700 : 0xFF4444 }); machinegunCost.anchor.set(1, 0.5); machinegunCost.x = 2048 / 2 + 650; machinegunCost.y = 2732 / 2 + 550; marketPanel.addChild(machinegunCost); var machinegunUpgrade = LK.getAsset('marketButton', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 + 550 }); machinegunUpgrade.alpha = 0.01; machinegunUpgrade.down = function (x, y, obj) { if (!storage.hasMachinegun && storage.coins >= 800) { storage.coins -= 800; storage.hasMachinegun = true; player.weaponType = 'machinegun'; coinDisplay.setText('COIN: ' + storage.coins); LK.getSound('coinPurchase').play(); hideMarket(); showMarket(); // Refresh market display } }; marketPanel.addChild(machinegunUpgrade); // Upgrade status display var upgradeStatus = LK.getAsset('Tahta', { width: 1600, height: 150, anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 + 750 }); upgradeStatus.alpha = 0.8; upgradeStatus.tint = 0x333333; marketPanel.addChild(upgradeStatus); var statusTitle = new Text2('📊 UPGRADE STATUS', { size: 70, fill: 0xFFFFFF }); statusTitle.anchor.set(0.5, 0.5); statusTitle.x = 2048 / 2; statusTitle.y = 2732 / 2 + 710; marketPanel.addChild(statusTitle); var statusText = new Text2('❤️ ' + storage.healthUpgrades + ' 🔫 ' + storage.ammoUpgrades + ' ⚡ ' + storage.speedUpgrades + ' Weapon: ' + (player.weaponType || 'Normal'), { size: 70, fill: 0xFFD700 }); statusText.anchor.set(0.5, 0.5); statusText.x = 2048 / 2; statusText.y = 2732 / 2 + 790; marketPanel.addChild(statusText); // Enhanced close button var closeButtonBg = LK.getAsset('Tahta', { width: 800, height: 150, anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 + 950 }); closeButtonBg.alpha = 0.9; closeButtonBg.tint = 0x666666; marketPanel.addChild(closeButtonBg); var closeButton = LK.getAsset('marketButton', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 + 950 }); closeButton.alpha = 0.01; closeButton.down = function (x, y, obj) { hideMarket(); }; marketPanel.addChild(closeButton); var closeText = new Text2('❌ CLOSE MARKET', { size: 90, fill: 0xFFFFFF }); closeText.anchor.set(0.5, 0.5); closeText.x = 2048 / 2; closeText.y = 2732 / 2 + 950; marketPanel.addChild(closeText); game.addChild(marketPanel); } function hideMarket() { if (marketPanel) { marketPanel.destroy(); marketPanel = null; } showingMarket = false; // Refresh weapon buttons if new weapons were purchased refreshWeaponButtons(); } function refreshWeaponButtons() { // Remove existing weapon buttons if (shotgunWeaponButton && !storage.hasShotgun) { shotgunWeaponButton.destroy(); shotgunWeaponText.destroy(); shotgunWeaponButton = null; shotgunWeaponText = null; } if (machinegunWeaponButton && !storage.hasMachinegun) { machinegunWeaponButton.destroy(); machinegunWeaponText.destroy(); machinegunWeaponButton = null; machinegunWeaponText = null; } // Add shotgun button if purchased and not already added if (storage.hasShotgun && !shotgunWeaponButton) { shotgunWeaponButton = LK.getAsset('weaponIcon', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2 - 650, y: 2732 - 120 }); shotgunWeaponButton.tint = player.weaponType === 'shotgun' ? 0x4CAF50 : 0x666666; bottomPanel.addChild(shotgunWeaponButton); shotgunWeaponText = new Text2('🔫', { size: 60, fill: 0xFFAA00 }); shotgunWeaponText.anchor.set(0.5, 0.5); shotgunWeaponText.x = 2048 / 2 - 650; shotgunWeaponText.y = 2732 - 120; bottomPanel.addChild(shotgunWeaponText); shotgunWeaponButton.down = function (x, y, obj) { if (!showingGameOver && !showingMarket && !isPaused) { player.weaponType = 'shotgun'; updateWeaponButtons(); } }; } // Add machine gun button if purchased and not already added if (storage.hasMachinegun && !machinegunWeaponButton) { machinegunWeaponButton = LK.getAsset('weaponIcon', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2 - 500, y: 2732 - 120 }); machinegunWeaponButton.tint = player.weaponType === 'machinegun' ? 0x4CAF50 : 0x666666; bottomPanel.addChild(machinegunWeaponButton); machinegunWeaponText = new Text2('🔫', { size: 60, fill: 0x00FF00 }); machinegunWeaponText.anchor.set(0.5, 0.5); machinegunWeaponText.x = 2048 / 2 - 500; machinegunWeaponText.y = 2732 - 120; bottomPanel.addChild(machinegunWeaponText); machinegunWeaponButton.down = function (x, y, obj) { if (!showingGameOver && !showingMarket && !isPaused) { player.weaponType = 'machinegun'; updateWeaponButtons(); } }; } } function showPause() { if (isPaused) return; isPaused = true; pausePanel = new Container(); // Semi-transparent background var background = LK.getAsset('arena', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, scaleX: 3, scaleY: 3 }); background.alpha = 0.8; background.tint = 0x000000; pausePanel.addChild(background); // Pause menu panel with wooden background var pauseMenuBackground = LK.getAsset('Tahta', { width: 600, height: 500, anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 }); pauseMenuBackground.alpha = 0.9; pausePanel.addChild(pauseMenuBackground); // Pause title var pauseTitle = new Text2('PAUSE MENU', { size: 100, fill: 0xFFFFFF }); pauseTitle.anchor.set(0.5, 0.5); pauseTitle.x = 2048 / 2; pauseTitle.y = 2732 / 2 - 180; pausePanel.addChild(pauseTitle); // Restart button var restartButton = LK.getAsset('marketButton', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 - 80 }); restartButton.tint = 0xFF5722; restartButton.down = function (x, y, obj) { hidePause(); restartGame(); }; pausePanel.addChild(restartButton); var restartText = new Text2('RESTART', { size: 60, fill: 0xFFFFFF }); restartText.anchor.set(0.5, 0.5); restartText.x = 2048 / 2; restartText.y = 2732 / 2 - 80; pausePanel.addChild(restartText); // Continue button var continueButton = LK.getAsset('marketButton', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 + 20 }); continueButton.down = function (x, y, obj) { hidePause(); }; pausePanel.addChild(continueButton); var continueText = new Text2('CONTINUE', { size: 60, fill: 0xFFFFFF }); continueText.anchor.set(0.5, 0.5); continueText.x = 2048 / 2; continueText.y = 2732 / 2 + 20; pausePanel.addChild(continueText); // Market button var marketButton = LK.getAsset('marketButton', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 + 120 }); marketButton.tint = 0x2196F3; marketButton.down = function (x, y, obj) { hidePause(); showMarket(); }; pausePanel.addChild(marketButton); var marketText = new Text2('MARKET', { size: 60, fill: 0xFFFFFF }); marketText.anchor.set(0.5, 0.5); marketText.x = 2048 / 2; marketText.y = 2732 / 2 + 120; pausePanel.addChild(marketText); game.addChild(pausePanel); } function hidePause() { if (pausePanel) { pausePanel.destroy(); pausePanel = null; } isPaused = false; } function restartGame() { hideGameOver(); // Reset player with upgraded stats player.maxHealth = 100 + storage.healthUpgrades * 20; player.health = player.maxHealth; player.maxAmmo = 30 + storage.ammoUpgrades * 10; player.ammo = player.maxAmmo; player.baseShootCooldown = Math.max(1, 10 - storage.speedUpgrades); player.x = 2048 / 2; player.y = 2732 / 2; // Clear all entities for (var i = 0; i < zombies.length; i++) { zombies[i].destroy(); } zombies = []; for (var i = 0; i < bullets.length; i++) { bullets[i].destroy(); } bullets = []; // Reset game state waveNumber = 1; zombiesInWave = 5; zombiesSpawned = 0; spawnTimer = 0; isFirstShot = true; zombiesKilledInWave = 0; zombiesRequiredToKill = 8; isBossWave = false; bossKilled = false; // Keep current map state when restarting - don't change map unless unlocked // If map is locked, stay on second map regardless of restart method if (!mapLocked) { // Only reset to first map if map is not locked // Map only changes when specifically using Next Map button or when unlocked } LK.setScore(0); } function spawnZombie() { var zombie; // Check if this is a boss wave (every 15th wave) if (isBossWave) { if (isSecondMap) { // On second map, spawn ice boss instead of regular boss zombie = new IceBoss(); } else { zombie = new BossZombie(); } } else if (isSecondMap) { // On second map, spawn ice monsters instead of regular zombies zombie = new IceMonster(); } else { // On forestMap (first map), spawn only regular zombies zombie = Math.random() < 0.5 ? new Zombie() : new Zombie2(); } // Define spawn locations around the arena edges var spawnLocations = [{ x: Math.random() * 2048, y: 100 }, // Top edge { x: Math.random() * 2048, y: 2632 }, // Bottom edge { x: 100, y: Math.random() * 2732 }, // Left edge { x: 1948, y: Math.random() * 2732 }, // Right edge { x: 300, y: 300 }, // Top-left corner { x: 1748, y: 300 }, // Top-right corner { x: 300, y: 2432 }, // Bottom-left corner { x: 1748, y: 2432 } // Bottom-right corner ]; // Pick a random spawn location from the predefined spots var spawnIndex = Math.floor(Math.random() * spawnLocations.length); var spawnPoint = spawnLocations[spawnIndex]; zombie.x = spawnPoint.x; zombie.y = spawnPoint.y; // Only apply scaling to non-boss zombies if (!isBossWave) { // Increase zombie health by 25% every 5 waves var healthMultiplier = Math.floor(waveNumber / 5) * 0.25; zombie.health = Math.floor(1 * (1 + healthMultiplier)); // Increase zombie speed by 25% every 15 waves var speedMultiplier = Math.floor(waveNumber / 15) * 0.25; zombie.speed = zombie.speed * (1 + speedMultiplier); // Increase zombie damage by 25% every 10 waves var damageMultiplier = Math.floor(waveNumber / 10) * 0.25; zombie.damage = Math.floor(zombie.damage * (1 + damageMultiplier)); zombie.scaleX = 1.0; zombie.scaleY = 1.0; } else { // Boss zombies get stronger each boss wave var bossWaveNumber = Math.floor(waveNumber / 15); zombie.health = 10 + bossWaveNumber * 5; // More health each boss wave zombie.damage = 25 + bossWaveNumber * 10; // More damage each boss wave } zombies.push(zombie); game.addChild(zombie); } function shootBullet(targetX, targetY) { if (player.shoot()) { var dx = targetX - player.x; var dy = targetY - player.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { // Rotate player to face shooting direction player.rotation = Math.atan2(dy, dx); } if (player.weaponType === 'shotgun') { // Shotgun fires 5 bullets in a spread pattern for (var i = 0; i < 5; i++) { var bullet = new ShotgunBullet(); bullet.x = player.x; bullet.y = player.y; var spreadAngle = (i - 2) * 0.3; // Spread bullets in a fan pattern var angle = Math.atan2(dy, dx) + spreadAngle; bullet.dx = Math.cos(angle); bullet.dy = Math.sin(angle); bullet.scaleX = 0.18; bullet.scaleY = 0.18; bullets.push(bullet); game.addChild(bullet); } } else if (player.weaponType === 'machinegun') { // Machine gun fires rapid bullets var bullet = new MachinegunBullet(); bullet.x = player.x; bullet.y = player.y; bullet.dx = dx / distance; bullet.dy = dy / distance; bullet.scaleX = 0.12; bullet.scaleY = 0.12; bullets.push(bullet); game.addChild(bullet); } else { // Normal weapon var bullet = new Bullet(); bullet.x = player.x; bullet.y = player.y; bullet.dx = dx / distance; bullet.dy = dy / distance; bullet.scaleX = 0.15; bullet.scaleY = 0.15; bullets.push(bullet); game.addChild(bullet); } if (soundEnabled) LK.getSound('shoot').play(); } } game.down = function (x, y, obj) { // Pause menu button clicks when paused if (isPaused) { // Restart button click if (x >= 2048 / 2 - 150 && x <= 2048 / 2 + 150 && y >= 2732 / 2 - 130 && y <= 2732 / 2 - 30) { hidePause(); restartGame(); return; } // Continue button click if (x >= 2048 / 2 - 150 && x <= 2048 / 2 + 150 && y >= 2732 / 2 - 30 && y <= 2732 / 2 + 70) { hidePause(); return; } // Market button click if (x >= 2048 / 2 - 150 && x <= 2048 / 2 + 150 && y >= 2732 / 2 + 70 && y <= 2732 / 2 + 170) { hidePause(); showMarket(); return; } return; } if (showingGameOver) { // Market button click detection if (x >= 2048 / 2 - 150 && x <= 2048 / 2 + 150 && y >= 2732 / 2 + 10 && y <= 2732 / 2 + 90) { showMarket(); return; } // Restart button click detection if (x >= 2048 / 2 - 150 && x <= 2048 / 2 + 150 && y >= 2732 / 2 + 110 && y <= 2732 / 2 + 190) { restartGame(); return; } } else if (showingMarket) { var currentCoins = storage.coins; // Health upgrade button click if (x >= 2048 / 2 - 300 && x <= 2048 / 2 + 300 && y >= 2732 / 2 - 200 && y <= 2732 / 2 - 100) { if (storage.coins >= healthUpgradeCost) { storage.coins -= healthUpgradeCost; healthUpgradeCost = Math.floor(healthUpgradeCost * 1.5); // Increase cost by 50% storage.healthUpgradeCost = healthUpgradeCost; // Save to storage storage.healthUpgrades++; player.maxHealth += 20; player.health = Math.min(player.health + 20, player.maxHealth); coinDisplay.setText('COIN: ' + storage.coins); LK.getSound('coinPurchase').play(); hideMarket(); showMarket(); // Refresh market display } return; } // Ammo upgrade button click if (x >= 2048 / 2 - 250 && x <= 2048 / 2 + 250 && y >= 2732 / 2 - 100 && y <= 2732 / 2 + 0) { if (storage.coins >= ammoUpgradeCost) { storage.coins -= ammoUpgradeCost; ammoUpgradeCost = Math.floor(ammoUpgradeCost * 1.5); // Increase cost by 50% storage.ammoUpgradeCost = ammoUpgradeCost; // Save to storage storage.ammoUpgrades++; player.maxAmmo += 10; player.ammo = Math.min(player.ammo + 10, player.maxAmmo); coinDisplay.setText('COIN: ' + storage.coins); LK.getSound('coinPurchase').play(); hideMarket(); showMarket(); // Refresh market display } return; } // Speed upgrade button click if (x >= 2048 / 2 - 275 && x <= 2048 / 2 + 275 && y >= 2732 / 2 + 0 && y <= 2732 / 2 + 100) { if (storage.coins >= speedUpgradeCost) { storage.coins -= speedUpgradeCost; speedUpgradeCost = Math.floor(speedUpgradeCost * 1.5); // Increase cost by 50% storage.speedUpgradeCost = speedUpgradeCost; // Save to storage storage.speedUpgrades++; player.baseShootCooldown = Math.max(1, player.baseShootCooldown - 1); coinDisplay.setText('COIN: ' + storage.coins); LK.getSound('coinPurchase').play(); hideMarket(); showMarket(); // Refresh market display } return; } // Shotgun weapon button click if (x >= 2048 / 2 - 300 && x <= 2048 / 2 + 300 && y >= 2732 / 2 + 250 && y <= 2732 / 2 + 350) { if (!storage.hasShotgun && storage.coins >= 500) { storage.coins -= 500; storage.hasShotgun = true; player.weaponType = 'shotgun'; coinDisplay.setText('COIN: ' + storage.coins); LK.getSound('coinPurchase').play(); hideMarket(); showMarket(); // Refresh market display } return; } // Machine gun weapon button click if (x >= 2048 / 2 - 300 && x <= 2048 / 2 + 300 && y >= 2732 / 2 + 500 && y <= 2732 / 2 + 600) { if (!storage.hasMachinegun && storage.coins >= 800) { storage.coins -= 800; storage.hasMachinegun = true; player.weaponType = 'machinegun'; coinDisplay.setText('COIN: ' + storage.coins); LK.getSound('coinPurchase').play(); hideMarket(); showMarket(); // Refresh market display } return; } // Close button click if (x >= 2048 / 2 - 200 && x <= 2048 / 2 + 200 && y >= 2732 / 2 + 900 && y <= 2732 / 2 + 1000) { hideMarket(); return; } } else { shootBullet(x, y); } }; game.update = function () { if (showingGameOver || showingMarket || isPaused) { return; } spawnTimer++; if (zombiesSpawned < zombiesInWave && spawnTimer >= 60) { spawnZombie(); zombiesSpawned++; spawnTimer = 0; } // Check if required zombies killed to progress wave if (zombiesKilledInWave >= zombiesRequiredToKill) { waveNumber++; zombiesKilledInWave = 0; // Calculate new required kills (25% more than previous wave) zombiesRequiredToKill = Math.ceil(zombiesRequiredToKill * 1.25); // Check if current wave is a boss wave (every 15th wave) isBossWave = waveNumber % 15 === 0; if (isBossWave) { zombiesInWave = 1; // Only 1 boss zombie } else { zombiesInWave = Math.min(5 + waveNumber * 2, 20); } zombiesSpawned = 0; } // Check if boss has been killed and prevent further spawning var bossKilled = false; for (var i = 0; i < zombies.length; i++) { if (zombies[i] instanceof BossZombie) { bossKilled = false; break; } } if (isBossWave && zombiesSpawned > 0 && zombies.length === 0) { // Boss was killed, don't spawn more zombies return; } if (zombiesSpawned >= zombiesInWave && zombies.length === 0) { // Keep spawning zombies until kill requirement is met zombiesSpawned = 0; } // Check if player has no ammo and end game if (player.ammo <= 0) { LK.effects.flashScreen(0xff0000, 1000); showCustomGameOver(); return; } healthBar.setText('Health: ' + player.health); ammoDisplay.setText('Ammo: ' + player.ammo); scoreDisplay.setText('SCORE: ' + LK.getScore()); coinDisplay.setText('COIN: ' + storage.coins); waveInfo.setText('Wave: ' + waveNumber + (isBossWave ? ' (BOSS)' : '')); killProgress.setText('Kills: ' + zombiesKilledInWave + '/' + zombiesRequiredToKill); weaponStatus.setText('Weapon: ' + (player.weaponType || 'Normal')); for (var i = bullets.length - 1; i >= 0; i--) { bullets[i].update(); } for (var i = zombies.length - 1; i >= 0; i--) { zombies[i].update(); } }; // Sound toggle button var soundButton = LK.getAsset('Tahta', { width: 120, height: 120, anchorX: 1, anchorY: 1, x: 0, y: -130 }); soundButton.alpha = 0.8; LK.gui.bottomRight.addChild(soundButton); var soundText = new Text2('🔊', { size: 60, fill: 0xFFFFFF }); soundText.anchor.set(0.5, 0.5); soundText.x = -60; soundText.y = -190; LK.gui.bottomRight.addChild(soundText); var soundEnabled = true; soundButton.down = function (x, y, obj) { if (soundEnabled) { soundText.setText('🔇'); soundText.alpha = 0.5; soundEnabled = false; } else { soundText.setText('🔊'); soundText.alpha = 1.0; soundEnabled = true; } }; // Music toggle button var musicButton = LK.getAsset('Tahta', { width: 120, height: 120, anchorX: 1, anchorY: 1, x: 0, y: 0 }); musicButton.alpha = 0.8; LK.gui.bottomRight.addChild(musicButton); var musicText = new Text2('♪', { size: 80, fill: 0xFFFFFF }); musicText.anchor.set(0.5, 0.5); musicText.x = -60; musicText.y = -60; LK.gui.bottomRight.addChild(musicText); var musicPlaying = true; musicButton.down = function (x, y, obj) { if (musicPlaying) { LK.stopMusic(); musicText.setText('♪'); musicText.alpha = 0.5; musicPlaying = false; } else { // Market quick access button var marketQuickButton = LK.getAsset('Tahta', { width: 120, height: 120, anchorX: 0.5, anchorY: 1, x: 0, y: 0 }); marketQuickButton.alpha = 0.8; LK.gui.bottom.addChild(marketQuickButton); var marketQuickText = new Text2('🛒', { size: 80, fill: 0xFFFFFF }); marketQuickText.anchor.set(0.5, 0.5); marketQuickText.x = 0; marketQuickText.y = -60; LK.gui.bottom.addChild(marketQuickText); marketQuickButton.down = function (x, y, obj) { if (!showingGameOver && !showingMarket && !isPaused) { showMarket(); } }; // Surrender button in top-left corner next to pause shortcut var surrenderButton = LK.getAsset('Tahta', { width: 120, height: 120, anchorX: 0, anchorY: 0, x: 120, y: 0 }); surrenderButton.alpha = 0.8; LK.gui.topLeft.addChild(surrenderButton); var surrenderText = new Text2('🏳️', { size: 80, fill: 0xFFFFFF }); surrenderText.anchor.set(0.5, 0.5); surrenderText.x = 60; surrenderText.y = 60; LK.gui.topLeft.addChild(surrenderText); surrenderButton.down = function (x, y, obj) { if (!showingGameOver && !showingMarket && !isPaused) { player.ammo = 0; LK.effects.flashScreen(0xff0000, 1000); showCustomGameOver(); } }; // Market button in top-right corner var topMarketButton = LK.getAsset('Tahta', { width: 120, height: 120, anchorX: 1, anchorY: 0, x: 0, y: 0 }); topMarketButton.alpha = 0.8; LK.gui.topRight.addChild(topMarketButton); var topMarketText = new Text2('🛒', { size: 80, fill: 0xFFFFFF }); topMarketText.anchor.set(0.5, 0.5); topMarketText.x = -60; topMarketText.y = 60; LK.gui.topRight.addChild(topMarketText); topMarketButton.down = function (x, y, obj) { if (!showingGameOver && !showingMarket && !isPaused) { showMarket(); } }; // Bottom panel for game interface var bottomPanel = new Container(); var bottomPanelBg = LK.getAsset('Tahta', { width: 2048, height: 300, anchorX: 0.5, anchorY: 1, x: 2048 / 2, y: 2732 }); bottomPanelBg.alpha = 0.9; bottomPanelBg.tint = 0x2a2a2a; bottomPanel.addChild(bottomPanelBg); // Panel title var panelTitle = new Text2('GAME CONTROLS', { size: 80, fill: 0xFFD700 }); panelTitle.anchor.set(0.5, 0); panelTitle.x = 2048 / 2; panelTitle.y = 2732 - 280; bottomPanel.addChild(panelTitle); // Ammo reload button var reloadButton = LK.getAsset('Tahta', { width: 200, height: 80, anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 - 120 }); reloadButton.alpha = 0.8; reloadButton.tint = 0x4CAF50; bottomPanel.addChild(reloadButton); var reloadText = new Text2('RELOAD', { size: 50, fill: 0xFFFFFF }); reloadText.anchor.set(0.5, 0.5); reloadText.x = 2048 / 2; reloadText.y = 2732 - 120; bottomPanel.addChild(reloadText); reloadButton.down = function (x, y, obj) { if (!showingGameOver && !showingMarket && !isPaused) { player.ammo = player.maxAmmo; LK.effects.flashObject(reloadButton, 0x00ff00, 200); } }; // Quick market access var quickMarketButton = LK.getAsset('Tahta', { width: 200, height: 80, anchorX: 0.5, anchorY: 0.5, x: 2048 / 2 + 400, y: 2732 - 120 }); quickMarketButton.alpha = 0.8; quickMarketButton.tint = 0x2196F3; bottomPanel.addChild(quickMarketButton); var quickMarketText = new Text2('MARKET', { size: 50, fill: 0xFFFFFF }); quickMarketText.anchor.set(0.5, 0.5); quickMarketText.x = 2048 / 2 + 400; quickMarketText.y = 2732 - 120; bottomPanel.addChild(quickMarketText); quickMarketButton.down = function (x, y, obj) { if (!showingGameOver && !showingMarket && !isPaused) { showMarket(); } }; // Weapon selection section title var weaponSectionTitle = new Text2('WEAPON SELECTION', { size: 50, fill: 0xFFD700 }); weaponSectionTitle.anchor.set(0.5, 0); weaponSectionTitle.x = 2048 / 2 - 600; weaponSectionTitle.y = 2732 - 200; bottomPanel.addChild(weaponSectionTitle); // Add weapon status to bottom panel weaponStatus.anchor.set(0.5, 0); weaponStatus.x = 2048 / 2 - 400; weaponStatus.y = 2732 - 200; bottomPanel.addChild(weaponStatus); // Normal weapon button normalWeaponButton = LK.getAsset('weaponIcon', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2 - 800, y: 2732 - 120 }); normalWeaponButton.tint = player.weaponType === 'normal' ? 0x4CAF50 : 0x666666; bottomPanel.addChild(normalWeaponButton); normalWeaponText = new Text2('🔫', { size: 60, fill: 0xFFFFFF }); normalWeaponText.anchor.set(0.5, 0.5); normalWeaponText.x = 2048 / 2 - 800; normalWeaponText.y = 2732 - 120; bottomPanel.addChild(normalWeaponText); normalWeaponButton.down = function (x, y, obj) { if (!showingGameOver && !showingMarket && !isPaused) { player.weaponType = 'normal'; updateWeaponButtons(); } }; // Define weapon button variables in global scope var shotgunWeaponButton = null; var shotgunWeaponText = null; var machinegunWeaponButton = null; var machinegunWeaponText = null; var normalWeaponButton = null; var normalWeaponText = null; // Shotgun weapon button (only if purchased) if (storage.hasShotgun) { shotgunWeaponButton = LK.getAsset('weaponIcon', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2 - 650, y: 2732 - 120 }); shotgunWeaponButton.tint = player.weaponType === 'shotgun' ? 0x4CAF50 : 0x666666; bottomPanel.addChild(shotgunWeaponButton); shotgunWeaponText = new Text2('🔫', { size: 60, fill: 0xFFAA00 }); shotgunWeaponText.anchor.set(0.5, 0.5); shotgunWeaponText.x = 2048 / 2 - 650; shotgunWeaponText.y = 2732 - 120; bottomPanel.addChild(shotgunWeaponText); shotgunWeaponButton.down = function (x, y, obj) { if (!showingGameOver && !showingMarket && !isPaused) { player.weaponType = 'shotgun'; updateWeaponButtons(); } }; } // Machine gun weapon button (only if purchased) if (storage.hasMachinegun) { machinegunWeaponButton = LK.getAsset('weaponIcon', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2 - 500, y: 2732 - 120 }); machinegunWeaponButton.tint = player.weaponType === 'machinegun' ? 0x4CAF50 : 0x666666; bottomPanel.addChild(machinegunWeaponButton); machinegunWeaponText = new Text2('🔫', { size: 60, fill: 0x00FF00 }); machinegunWeaponText.anchor.set(0.5, 0.5); machinegunWeaponText.x = 2048 / 2 - 500; machinegunWeaponText.y = 2732 - 120; bottomPanel.addChild(machinegunWeaponText); machinegunWeaponButton.down = function (x, y, obj) { if (!showingGameOver && !showingMarket && !isPaused) { player.weaponType = 'machinegun'; updateWeaponButtons(); } }; } var pauseButton = LK.getAsset('Tahta', { width: 200, height: 80, anchorX: 0.5, anchorY: 0.5, x: 2048 / 2 - 400, y: 2732 - 120 }); pauseButton.alpha = 0.8; pauseButton.tint = 0xFF9800; bottomPanel.addChild(pauseButton); var pauseText = new Text2('PAUSE', { size: 50, fill: 0xFFFFFF }); pauseText.anchor.set(0.5, 0.5); pauseText.x = 2048 / 2 - 400; pauseText.y = 2732 - 120; bottomPanel.addChild(pauseText); pauseButton.down = function (x, y, obj) { if (!showingGameOver && !showingMarket && !isPaused) { showPause(); } }; game.addChild(bottomPanel); LK.playMusic('bgmusic'); musicText.setText('♪'); musicText.alpha = 1.0; musicPlaying = true; } }; LK.playMusic('bgmusic');
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
healthUpgrades: 0,
ammoUpgrades: 0,
speedUpgrades: 0,
coins: 0,
healthUpgradeCost: 200,
ammoUpgradeCost: 100,
speedUpgradeCost: 300,
hasShotgun: false,
hasMachinegun: false
});
/****
* Classes
****/
var BossZombie = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('bossZombie', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 0.5 + Math.random() * 0.3; // Slower than normal zombies
self.health = 10; // Much higher health
self.damage = 25; // Higher damage
self.lastPlayerCollision = false;
self.scaleX = 1.0; // Normal size
self.scaleY = 1.0;
self.update = function () {
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
var currentCollision = self.intersects(player);
if (!self.lastPlayerCollision && currentCollision) {
player.takeDamage(self.damage);
// Boss zombie dies from collision but doesn't give coins
self.health = 0;
LK.effects.flashObject(self, 0xffffff, 100);
var index = zombies.indexOf(self);
if (index > -1) {
zombies.splice(index, 1);
}
self.destroy();
}
self.lastPlayerCollision = currentCollision;
};
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
LK.effects.flashObject(self, 0xffffff, 100);
LK.setScore(LK.getScore() + 10000); // 10000 score for boss
storage.coins += 10000; // 10000 coins for boss
if (soundEnabled) LK.getSound('zombieHit').play();
var index = zombies.indexOf(self);
if (index > -1) {
zombies.splice(index, 1);
}
self.destroy();
// Unlock map when boss is defeated
if (isSecondMap) {
mapLocked = false;
storage.mapLocked = false;
}
// Show custom congratulations screen when boss is killed
showCongratulations();
}
};
return self;
});
var Bullet = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.dx = 0;
self.dy = 0;
self.lifetime = 120;
self.update = function () {
self.x += self.dx * self.speed;
self.y += self.dy * self.speed;
// Rotate bullet to face movement direction
graphics.rotation = Math.atan2(self.dy, self.dx);
self.lifetime--;
if (self.lifetime <= 0 || self.isOutOfBounds()) {
self.remove();
return;
}
for (var i = 0; i < zombies.length; i++) {
var zombie = zombies[i];
if (self.intersects(zombie)) {
zombie.takeDamage(1);
self.remove();
return;
}
}
};
self.isOutOfBounds = function () {
return self.x < 0 || self.x > 2048 || self.y < 0 || self.y > 2732;
};
self.remove = function () {
var index = bullets.indexOf(self);
if (index > -1) {
bullets.splice(index, 1);
}
self.destroy();
};
return self;
});
var IceBoss = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('iceBoss', {
anchorX: 0.5,
anchorY: 0.5
});
graphics.tint = 0x87CEEB; // Light blue tint for ice effect
self.speed = 0.8 + Math.random() * 0.4; // Faster than regular boss
self.health = 15; // Higher health than regular boss
self.damage = 30; // Higher damage than regular boss
self.lastPlayerCollision = false;
self.scaleX = 6.0; // 6.0 times larger than player (even bigger)
self.scaleY = 6.0;
self.update = function () {
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
var currentCollision = self.intersects(player);
if (!self.lastPlayerCollision && currentCollision) {
player.takeDamage(self.damage);
// Ice boss dies from collision but doesn't give coins
self.health = 0;
LK.effects.flashObject(self, 0x87CEEB, 100);
var index = zombies.indexOf(self);
if (index > -1) {
zombies.splice(index, 1);
}
self.destroy();
}
self.lastPlayerCollision = currentCollision;
};
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
LK.effects.flashObject(self, 0x87CEEB, 100);
LK.setScore(LK.getScore() + 15000); // 15000 score for ice boss
storage.coins += 15000; // 15000 coins for ice boss
if (soundEnabled) LK.getSound('zombieHit').play();
var index = zombies.indexOf(self);
if (index > -1) {
zombies.splice(index, 1);
}
self.destroy();
// Unlock map when ice boss is defeated
if (isSecondMap) {
mapLocked = false;
storage.mapLocked = false;
}
// Show custom congratulations screen when ice boss is killed
showCongratulations();
}
};
return self;
});
var IceMonster = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('iceMonster', {
anchorX: 0.5,
anchorY: 0.5
});
graphics.tint = 0x87CEEB; // Light blue tint for ice effect
self.speed = 1.5 + Math.random() * 0.7; // Slightly faster than normal zombies
self.health = 2; // Higher health than normal zombies
self.damage = 15; // Higher damage than normal zombies
self.lastPlayerCollision = false;
self.update = function () {
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
var currentCollision = self.intersects(player);
if (!self.lastPlayerCollision && currentCollision) {
player.takeDamage(self.damage);
// Ice monster dies from collision but doesn't give coins
self.health = 0;
LK.effects.flashObject(self, 0x87CEEB, 100);
var index = zombies.indexOf(self);
if (index > -1) {
zombies.splice(index, 1);
}
self.destroy();
}
self.lastPlayerCollision = currentCollision;
};
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
LK.effects.flashObject(self, 0x87CEEB, 100);
LK.setScore(LK.getScore() + 15);
storage.coins += 150;
zombiesKilledInWave++; // Track zombie kills
if (soundEnabled) LK.getSound('iceMhit').play();
var index = zombies.indexOf(self);
if (index > -1) {
zombies.splice(index, 1);
}
self.destroy();
}
};
return self;
});
var MachinegunBullet = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('machinegunBullet', {
anchorX: 0.5,
anchorY: 0.5
});
graphics.tint = 0x00ff00; // Green tint to differentiate from other bullets
self.speed = 12; // Faster than normal bullets
self.dx = 0;
self.dy = 0;
self.lifetime = 120; // Same lifetime as normal bullets
self.update = function () {
self.x += self.dx * self.speed;
self.y += self.dy * self.speed;
// Rotate bullet to face movement direction
graphics.rotation = Math.atan2(self.dy, self.dx);
self.lifetime--;
if (self.lifetime <= 0 || self.isOutOfBounds()) {
self.remove();
return;
}
for (var i = 0; i < zombies.length; i++) {
var zombie = zombies[i];
if (self.intersects(zombie)) {
zombie.takeDamage(1);
self.remove();
return;
}
}
};
self.isOutOfBounds = function () {
return self.x < 0 || self.x > 2048 || self.y < 0 || self.y > 2732;
};
self.remove = function () {
var index = bullets.indexOf(self);
if (index > -1) {
bullets.splice(index, 1);
}
self.destroy();
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 100;
self.maxHealth = 100;
self.ammo = 30;
self.maxAmmo = 30;
self.shootCooldown = 0;
self.baseShootCooldown = 10;
self.weaponType = 'normal';
self.update = function () {
if (self.shootCooldown > 0) {
self.shootCooldown--;
}
};
self.takeDamage = function (damage) {
self.health -= damage;
if (soundEnabled) LK.getSound('playerHit').play();
if (self.health <= 0) {
self.health = 0;
LK.effects.flashScreen(0xff0000, 1000);
showCustomGameOver();
} else {
LK.effects.flashObject(self, 0xff0000, 200);
}
};
self.canShoot = function () {
return self.ammo > 0 && self.shootCooldown <= 0;
};
self.shoot = function () {
if (self.canShoot()) {
self.ammo--;
if (self.weaponType === 'machinegun') {
self.shootCooldown = Math.max(1, self.baseShootCooldown - 5); // Faster fire rate
} else {
self.shootCooldown = self.baseShootCooldown;
}
return true;
}
return false;
};
return self;
});
var ShotgunBullet = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('shotgunBullet', {
anchorX: 0.5,
anchorY: 0.5
});
graphics.tint = 0xffaa00; // Orange tint to differentiate from normal bullets
self.speed = 8;
self.dx = 0;
self.dy = 0;
self.lifetime = 100; // Shorter lifetime than normal bullets
self.update = function () {
self.x += self.dx * self.speed;
self.y += self.dy * self.speed;
// Rotate bullet to face movement direction
graphics.rotation = Math.atan2(self.dy, self.dx);
self.lifetime--;
if (self.lifetime <= 0 || self.isOutOfBounds()) {
self.remove();
return;
}
for (var i = 0; i < zombies.length; i++) {
var zombie = zombies[i];
if (self.intersects(zombie)) {
zombie.takeDamage(1);
self.remove();
return;
}
}
};
self.isOutOfBounds = function () {
return self.x < 0 || self.x > 2048 || self.y < 0 || self.y > 2732;
};
self.remove = function () {
var index = bullets.indexOf(self);
if (index > -1) {
bullets.splice(index, 1);
}
self.destroy();
};
return self;
});
var Zombie = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('zombie', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 1 + Math.random() * 0.5;
self.health = 1;
self.damage = 10;
self.lastPlayerCollision = false;
self.update = function () {
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
var currentCollision = self.intersects(player);
if (!self.lastPlayerCollision && currentCollision) {
player.takeDamage(self.damage);
// Zombie dies from collision but doesn't give coins
self.health = 0;
LK.effects.flashObject(self, 0xffffff, 100);
var index = zombies.indexOf(self);
if (index > -1) {
zombies.splice(index, 1);
}
self.destroy();
}
self.lastPlayerCollision = currentCollision;
};
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
LK.effects.flashObject(self, 0xffffff, 100);
LK.setScore(LK.getScore() + 10);
storage.coins += 100;
zombiesKilledInWave++; // Track zombie kills
if (soundEnabled) LK.getSound('zombieHit').play();
var index = zombies.indexOf(self);
if (index > -1) {
zombies.splice(index, 1);
}
self.destroy();
}
};
return self;
});
var Zombie2 = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('zombie2', {
anchorX: 0.5,
anchorY: 0.5
});
graphics.tint = 0xff6b6b; // Reddish tint to differentiate
self.speed = 1 + Math.random() * 0.5;
self.health = 1;
self.damage = 10;
self.lastPlayerCollision = false;
self.update = function () {
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
var currentCollision = self.intersects(player);
if (!self.lastPlayerCollision && currentCollision) {
player.takeDamage(self.damage);
// Zombie dies from collision but doesn't give coins
self.health = 0;
LK.effects.flashObject(self, 0xffffff, 100);
var index = zombies.indexOf(self);
if (index > -1) {
zombies.splice(index, 1);
}
self.destroy();
}
self.lastPlayerCollision = currentCollision;
};
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
LK.effects.flashObject(self, 0xffffff, 100);
LK.setScore(LK.getScore() + 10);
storage.coins += 100;
zombiesKilledInWave++; // Track zombie kills
if (soundEnabled) LK.getSound('zombieHit').play();
var index = zombies.indexOf(self);
if (index > -1) {
zombies.splice(index, 1);
}
self.destroy();
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2d2d2d
});
/****
* Game Code
****/
var arena;
if (isSecondMap) {
arena = game.attachAsset('secondMap', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
scaleX: 1.14,
scaleY: 1.52
});
} else {
arena = game.attachAsset('secondMap', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
scaleX: 1.14,
scaleY: 1.52
});
}
var player = game.addChild(new Player());
player.x = 2048 / 2;
player.y = 2732 / 2;
player.scaleX = 1.0;
player.scaleY = 1.0;
// Apply stored upgrades
player.maxHealth = 100 + storage.healthUpgrades * 20;
player.health = player.maxHealth;
player.maxAmmo = 30 + storage.ammoUpgrades * 10;
player.ammo = player.maxAmmo;
player.baseShootCooldown = Math.max(1, 10 - storage.speedUpgrades);
// Weapon status display - define early so it can be used in game.update
var weaponStatus = new Text2('Weapon: ' + (player.weaponType || 'Normal'), {
size: 60,
fill: 0xFFFFFF
});
// Function to update weapon button colors
function updateWeaponButtons() {
if (normalWeaponButton) {
normalWeaponButton.tint = player.weaponType === 'normal' ? 0x4CAF50 : 0x666666;
}
if (shotgunWeaponButton) {
shotgunWeaponButton.tint = player.weaponType === 'shotgun' ? 0x4CAF50 : 0x666666;
}
if (machinegunWeaponButton) {
machinegunWeaponButton.tint = player.weaponType === 'machinegun' ? 0x4CAF50 : 0x666666;
}
weaponStatus.setText('Weapon: ' + (player.weaponType || 'Normal'));
}
var zombies = [];
var bullets = [];
var waveNumber = 1;
var zombiesInWave = 5;
var zombiesSpawned = 0;
var spawnTimer = 0;
var gameOverScreen = null;
var showingGameOver = false;
var showingMarket = false;
var marketPanel = null;
var isPaused = false;
var pausePanel = null;
var isBossWave = false;
var isFirstShot = true;
var zombiesKilledInWave = 0;
var zombiesRequiredToKill = 8;
var isSecondMap = storage.isSecondMap || false; // Track which map we're on, persist in storage
var mapLocked = storage.mapLocked || false; // Track if map is locked until boss defeat
// Upgrade costs that increase with each purchase - loaded from storage
var healthUpgradeCost = storage.healthUpgradeCost;
var ammoUpgradeCost = storage.ammoUpgradeCost;
var speedUpgradeCost = storage.speedUpgradeCost;
var healthBackground = LK.getAsset('Tahta', {
width: 300,
height: 60,
anchorX: 0,
anchorY: 1,
x: 120,
y: 0
});
healthBackground.alpha = 0.7;
LK.gui.bottomLeft.addChild(healthBackground);
var healthBar = new Text2('Health: 100', {
size: 60,
fill: 0xFF0000
});
healthBar.anchor.set(0, 1);
healthBar.x = 120; // Move away from bottom-left corner
LK.gui.bottomLeft.addChild(healthBar);
var ammoBackground = LK.getAsset('Tahta', {
width: 300,
height: 60,
anchorX: 0,
anchorY: 1,
x: 120,
y: -70
});
ammoBackground.alpha = 0.7;
LK.gui.bottomLeft.addChild(ammoBackground);
var ammoDisplay = new Text2('Ammo: 30', {
size: 60,
fill: 0x00FF00
});
ammoDisplay.anchor.set(0, 1);
ammoDisplay.x = 120; // Move away from bottom-left corner
ammoDisplay.y = -70;
LK.gui.bottomLeft.addChild(ammoDisplay);
var waveBackground = LK.getAsset('Tahta', {
width: 300,
height: 60,
anchorX: 0,
anchorY: 1,
x: 120,
y: -140
});
waveBackground.alpha = 0.7;
LK.gui.bottomLeft.addChild(waveBackground);
var waveInfo = new Text2('Wave: 1', {
size: 60,
fill: 0xFFFF00
});
waveInfo.anchor.set(0, 1);
waveInfo.x = 120; // Move away from bottom-left corner
waveInfo.y = -140;
LK.gui.bottomLeft.addChild(waveInfo);
var killProgressBackground = LK.getAsset('Tahta', {
width: 350,
height: 60,
anchorX: 0,
anchorY: 1,
x: 120,
y: -210
});
killProgressBackground.alpha = 0.7;
LK.gui.bottomLeft.addChild(killProgressBackground);
var killProgress = new Text2('Kills: 0/8', {
size: 60,
fill: 0xFF6B6B
});
killProgress.anchor.set(0, 1);
killProgress.x = 120;
killProgress.y = -210;
LK.gui.bottomLeft.addChild(killProgress);
var scoreBackground = LK.getAsset('Tahta', {
width: 350,
height: 90,
anchorX: 0.5,
anchorY: 0,
x: 0,
y: 0
});
scoreBackground.alpha = 0.7;
LK.gui.top.addChild(scoreBackground);
var scoreDisplay = new Text2('SCORE: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreDisplay.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreDisplay);
var coinBackground = LK.getAsset('Tahta', {
width: 300,
height: 70,
anchorX: 0.5,
anchorY: 0,
x: 0,
y: 90
});
coinBackground.alpha = 0.7;
LK.gui.top.addChild(coinBackground);
var coinDisplay = new Text2('COIN: ' + storage.coins, {
size: 60,
fill: 0xFFD700
});
coinDisplay.anchor.set(0.5, 0);
coinDisplay.y = 90;
LK.gui.top.addChild(coinDisplay);
function showCustomGameOver() {
if (showingGameOver) return;
showingGameOver = true;
gameOverScreen = new Container();
// Semi-transparent background
var background = LK.getAsset('arena', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
scaleX: 4,
scaleY: 4
});
background.alpha = 0.8;
background.tint = 0x000000;
gameOverScreen.addChild(background);
// Game Over title
var gameOverTitle = new Text2('GAME OVER', {
size: 140,
fill: 0xFF0000
});
gameOverTitle.anchor.set(0.5, 0.5);
gameOverTitle.x = 2048 / 2;
gameOverTitle.y = 2732 / 2 - 200;
gameOverScreen.addChild(gameOverTitle);
// Final score display
var finalScore = new Text2('Final Score: ' + LK.getScore(), {
size: 100,
fill: 0xFFFFFF
});
finalScore.anchor.set(0.5, 0.5);
finalScore.x = 2048 / 2;
finalScore.y = 2732 / 2 - 100;
gameOverScreen.addChild(finalScore);
// Market button
var marketButton = LK.getAsset('marketButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 + 50
});
marketButton.tint = 0x2196F3;
marketButton.down = function (x, y, obj) {
showMarket();
};
gameOverScreen.addChild(marketButton);
var marketText = new Text2('MARKET', {
size: 80,
fill: 0xFFFFFF
});
marketText.anchor.set(0.5, 0.5);
marketText.x = 2048 / 2;
marketText.y = 2732 / 2 + 50;
gameOverScreen.addChild(marketText);
// Restart button
var restartButton = LK.getAsset('marketButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 + 150
});
restartButton.tint = 0xFF5722;
restartButton.down = function (x, y, obj) {
restartGame();
};
gameOverScreen.addChild(restartButton);
var restartText = new Text2('RESTART', {
size: 80,
fill: 0xFFFFFF
});
restartText.anchor.set(0.5, 0.5);
restartText.x = 2048 / 2;
restartText.y = 2732 / 2 + 150;
gameOverScreen.addChild(restartText);
game.addChild(gameOverScreen);
}
function showCongratulations() {
if (showingGameOver) return;
showingGameOver = true;
gameOverScreen = new Container();
// Semi-transparent background
var background = LK.getAsset('arena', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
scaleX: 4,
scaleY: 4
});
background.alpha = 0.9;
background.tint = 0x0a0a1a;
gameOverScreen.addChild(background);
// Main victory panel background
var victoryPanel = LK.getAsset('Tahta', {
width: 1800,
height: 2000,
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2
});
victoryPanel.alpha = 0.95;
victoryPanel.tint = 0x1a4a2a;
gameOverScreen.addChild(victoryPanel);
// Victory crown/trophy icon
var crownIcon = new Text2('👑', {
size: 200,
fill: 0xFFD700
});
crownIcon.anchor.set(0.5, 0.5);
crownIcon.x = 2048 / 2;
crownIcon.y = 2732 / 2 - 650;
gameOverScreen.addChild(crownIcon);
// Congratulations title with enhanced styling
var congratsTitle = new Text2('VICTORY!', {
size: 180,
fill: 0xFFD700
});
congratsTitle.anchor.set(0.5, 0.5);
congratsTitle.x = 2048 / 2;
congratsTitle.y = 2732 / 2 - 450;
gameOverScreen.addChild(congratsTitle);
// Victory subtitle
var victorySubtitle = new Text2('BOSS ELIMINATED', {
size: 100,
fill: 0x90EE90
});
victorySubtitle.anchor.set(0.5, 0.5);
victorySubtitle.x = 2048 / 2;
victorySubtitle.y = 2732 / 2 - 320;
gameOverScreen.addChild(victorySubtitle);
// Statistics panel background
var statsPanel = LK.getAsset('Tahta', {
width: 1500,
height: 300,
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 - 100
});
statsPanel.alpha = 0.8;
statsPanel.tint = 0x2a2a4a;
gameOverScreen.addChild(statsPanel);
// Final score display with background
var scoreLabel = new Text2('FINAL SCORE', {
size: 70,
fill: 0xFFD700
});
scoreLabel.anchor.set(0.5, 0.5);
scoreLabel.x = 2048 / 2;
scoreLabel.y = 2732 / 2 - 150;
gameOverScreen.addChild(scoreLabel);
var finalScore = new Text2(LK.getScore().toString(), {
size: 120,
fill: 0xFFFFFF
});
finalScore.anchor.set(0.5, 0.5);
finalScore.x = 2048 / 2;
finalScore.y = 2732 / 2 - 50;
gameOverScreen.addChild(finalScore);
// Coins earned display
var coinsEarned = new Text2('💰 Coins Earned: ' + (isSecondMap ? '15,000' : '10,000'), {
size: 80,
fill: 0xFFD700
});
coinsEarned.anchor.set(0.5, 0.5);
coinsEarned.x = 2048 / 2;
coinsEarned.y = 2732 / 2 + 50;
gameOverScreen.addChild(coinsEarned);
// Action buttons with enhanced styling
// Market button
var marketButtonBg = LK.getAsset('Tahta', {
width: 600,
height: 120,
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 - 350,
y: 2732 / 2 + 250
});
marketButtonBg.alpha = 0.9;
marketButtonBg.tint = 0x2196F3;
gameOverScreen.addChild(marketButtonBg);
var marketButton = LK.getAsset('marketButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 - 350,
y: 2732 / 2 + 250
});
marketButton.alpha = 0.01;
marketButton.down = function (x, y, obj) {
showMarket();
};
gameOverScreen.addChild(marketButton);
var marketIcon = new Text2('🛒', {
size: 60,
fill: 0xFFFFFF
});
marketIcon.anchor.set(0.5, 0.5);
marketIcon.x = 2048 / 2 - 400;
marketIcon.y = 2732 / 2 + 250;
gameOverScreen.addChild(marketIcon);
var marketText = new Text2('SHOP', {
size: 70,
fill: 0xFFFFFF
});
marketText.anchor.set(0.5, 0.5);
marketText.x = 2048 / 2 - 300;
marketText.y = 2732 / 2 + 250;
gameOverScreen.addChild(marketText);
// Restart button
var restartButtonBg = LK.getAsset('Tahta', {
width: 600,
height: 120,
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 + 350,
y: 2732 / 2 + 250
});
restartButtonBg.alpha = 0.9;
restartButtonBg.tint = 0x4CAF50;
gameOverScreen.addChild(restartButtonBg);
var restartButton = LK.getAsset('marketButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 + 350,
y: 2732 / 2 + 250
});
restartButton.alpha = 0.01;
restartButton.down = function (x, y, obj) {
restartGame();
};
gameOverScreen.addChild(restartButton);
var restartIcon = new Text2('🔄', {
size: 60,
fill: 0xFFFFFF
});
restartIcon.anchor.set(0.5, 0.5);
restartIcon.x = 2048 / 2 + 300;
restartIcon.y = 2732 / 2 + 250;
gameOverScreen.addChild(restartIcon);
var restartText = new Text2('PLAY AGAIN', {
size: 60,
fill: 0xFFFFFF
});
restartText.anchor.set(0.5, 0.5);
restartText.x = 2048 / 2 + 400;
restartText.y = 2732 / 2 + 250;
gameOverScreen.addChild(restartText);
// Continue playing button
var continueButtonBg = LK.getAsset('Tahta', {
width: 1200,
height: 120,
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 + 400
});
continueButtonBg.alpha = 0.9;
continueButtonBg.tint = 0xFF9800;
gameOverScreen.addChild(continueButtonBg);
var continueButton = LK.getAsset('marketButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 + 400
});
continueButton.alpha = 0.01;
continueButton.down = function (x, y, obj) {
hideGameOver();
// Continue the game without restarting
};
gameOverScreen.addChild(continueButton);
var continueIcon = new Text2('⚡', {
size: 60,
fill: 0xFFFFFF
});
continueIcon.anchor.set(0.5, 0.5);
continueIcon.x = 2048 / 2 - 150;
continueIcon.y = 2732 / 2 + 400;
gameOverScreen.addChild(continueIcon);
var continueText = new Text2('CONTINUE SURVIVING', {
size: 70,
fill: 0xFFFFFF
});
continueText.anchor.set(0.5, 0.5);
continueText.x = 2048 / 2 + 50;
continueText.y = 2732 / 2 + 400;
gameOverScreen.addChild(continueText);
// Achievement badge
var achievementBadge = LK.getAsset('Tahta', {
width: 400,
height: 150,
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 + 550
});
achievementBadge.alpha = 0.8;
achievementBadge.tint = 0x8B4513;
gameOverScreen.addChild(achievementBadge);
var achievementText = new Text2('🏆 BOSS SLAYER 🏆', {
size: 60,
fill: 0xFFD700
});
achievementText.anchor.set(0.5, 0.5);
achievementText.x = 2048 / 2;
achievementText.y = 2732 / 2 + 550;
gameOverScreen.addChild(achievementText);
game.addChild(gameOverScreen);
}
function hideGameOver() {
if (gameOverScreen) {
gameOverScreen.destroy();
gameOverScreen = null;
}
showingGameOver = false;
}
function showMarket() {
if (showingMarket) return;
showingMarket = true;
marketPanel = new Container();
// Semi-transparent background
var background = LK.getAsset('arena', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
scaleX: 4,
scaleY: 4
});
background.alpha = 0.95;
background.tint = 0x1a1a1a;
marketPanel.addChild(background);
// Main market panel background
var mainPanel = LK.getAsset('Tahta', {
width: 1800,
height: 2200,
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2
});
mainPanel.alpha = 0.95;
mainPanel.tint = 0x2a2a2a;
marketPanel.addChild(mainPanel);
// Market title with enhanced styling
var marketTitle = new Text2('🛒 MARKET', {
size: 160,
fill: 0xFFD700
});
marketTitle.anchor.set(0.5, 0.5);
marketTitle.x = 2048 / 2;
marketTitle.y = 2732 / 2 - 850;
marketPanel.addChild(marketTitle);
// Current coins display with enhanced styling
var currentCoins = storage.coins;
var coinPanel = LK.getAsset('Tahta', {
width: 600,
height: 120,
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 - 700
});
coinPanel.alpha = 0.9;
coinPanel.tint = 0x4a4a4a;
marketPanel.addChild(coinPanel);
var scoreText = new Text2('💰 COINS: ' + storage.coins, {
size: 100,
fill: 0xFFD700
});
scoreText.anchor.set(0.5, 0.5);
scoreText.x = 2048 / 2;
scoreText.y = 2732 / 2 - 700;
marketPanel.addChild(scoreText);
// Health upgrade section
var healthSection = LK.getAsset('Tahta', {
width: 1600,
height: 200,
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 - 450
});
healthSection.alpha = 0.8;
healthSection.tint = 0x4CAF50;
marketPanel.addChild(healthSection);
var healthIcon = new Text2('❤️', {
size: 120,
fill: 0xFFFFFF
});
healthIcon.anchor.set(0.5, 0.5);
healthIcon.x = 2048 / 2 - 650;
healthIcon.y = 2732 / 2 - 450;
marketPanel.addChild(healthIcon);
var healthTitle = new Text2('HEALTH BOOST', {
size: 80,
fill: 0xFFFFFF
});
healthTitle.anchor.set(0, 0.5);
healthTitle.x = 2048 / 2 - 550;
healthTitle.y = 2732 / 2 - 480;
marketPanel.addChild(healthTitle);
var healthDesc = new Text2('+20 Max Health & Heal', {
size: 60,
fill: 0xE8F5E8
});
healthDesc.anchor.set(0, 0.5);
healthDesc.x = 2048 / 2 - 550;
healthDesc.y = 2732 / 2 - 420;
marketPanel.addChild(healthDesc);
var healthCost = new Text2('💰 ' + healthUpgradeCost, {
size: 90,
fill: storage.coins >= healthUpgradeCost ? 0xFFD700 : 0xFF4444
});
healthCost.anchor.set(1, 0.5);
healthCost.x = 2048 / 2 + 650;
healthCost.y = 2732 / 2 - 450;
marketPanel.addChild(healthCost);
var healthUpgrade = LK.getAsset('marketButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 - 450
});
healthUpgrade.alpha = 0.01;
healthUpgrade.down = function (x, y, obj) {
if (storage.coins >= healthUpgradeCost) {
storage.coins -= healthUpgradeCost;
healthUpgradeCost = Math.floor(healthUpgradeCost * 1.5); // Increase cost by 50%
storage.healthUpgradeCost = healthUpgradeCost; // Save to storage
storage.healthUpgrades++;
player.maxHealth += 20;
player.health = Math.min(player.health + 20, player.maxHealth);
coinDisplay.setText('COIN: ' + storage.coins);
LK.getSound('coinPurchase').play();
hideMarket();
showMarket(); // Refresh market display
}
};
marketPanel.addChild(healthUpgrade);
// Ammo upgrade section
var ammoSection = LK.getAsset('Tahta', {
width: 1600,
height: 200,
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 - 200
});
ammoSection.alpha = 0.8;
ammoSection.tint = 0x2196F3;
marketPanel.addChild(ammoSection);
var ammoIcon = new Text2('🔫', {
size: 120,
fill: 0xFFFFFF
});
ammoIcon.anchor.set(0.5, 0.5);
ammoIcon.x = 2048 / 2 - 650;
ammoIcon.y = 2732 / 2 - 200;
marketPanel.addChild(ammoIcon);
var ammoTitle = new Text2('AMMO BOOST', {
size: 80,
fill: 0xFFFFFF
});
ammoTitle.anchor.set(0, 0.5);
ammoTitle.x = 2048 / 2 - 550;
ammoTitle.y = 2732 / 2 - 230;
marketPanel.addChild(ammoTitle);
var ammoDesc = new Text2('+10 Max Ammo & Reload', {
size: 60,
fill: 0xE3F2FD
});
ammoDesc.anchor.set(0, 0.5);
ammoDesc.x = 2048 / 2 - 550;
ammoDesc.y = 2732 / 2 - 170;
marketPanel.addChild(ammoDesc);
var ammoCost = new Text2('💰 ' + ammoUpgradeCost, {
size: 90,
fill: storage.coins >= ammoUpgradeCost ? 0xFFD700 : 0xFF4444
});
ammoCost.anchor.set(1, 0.5);
ammoCost.x = 2048 / 2 + 650;
ammoCost.y = 2732 / 2 - 200;
marketPanel.addChild(ammoCost);
var ammoUpgrade = LK.getAsset('marketButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 - 200
});
ammoUpgrade.alpha = 0.01;
ammoUpgrade.down = function (x, y, obj) {
if (storage.coins >= ammoUpgradeCost) {
storage.coins -= ammoUpgradeCost;
ammoUpgradeCost = Math.floor(ammoUpgradeCost * 1.5); // Increase cost by 50%
storage.ammoUpgradeCost = ammoUpgradeCost; // Save to storage
storage.ammoUpgrades++;
player.maxAmmo += 10;
player.ammo = Math.min(player.ammo + 10, player.maxAmmo);
coinDisplay.setText('COIN: ' + storage.coins);
LK.getSound('coinPurchase').play();
hideMarket();
showMarket(); // Refresh market display
}
};
marketPanel.addChild(ammoUpgrade);
// Speed upgrade section
var speedSection = LK.getAsset('Tahta', {
width: 1600,
height: 200,
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 + 50
});
speedSection.alpha = 0.8;
speedSection.tint = 0xFF9800;
marketPanel.addChild(speedSection);
var speedIcon = new Text2('⚡', {
size: 120,
fill: 0xFFFFFF
});
speedIcon.anchor.set(0.5, 0.5);
speedIcon.x = 2048 / 2 - 650;
speedIcon.y = 2732 / 2 + 50;
marketPanel.addChild(speedIcon);
var speedTitle = new Text2('FIRE RATE BOOST', {
size: 80,
fill: 0xFFFFFF
});
speedTitle.anchor.set(0, 0.5);
speedTitle.x = 2048 / 2 - 550;
speedTitle.y = 2732 / 2 + 20;
marketPanel.addChild(speedTitle);
var speedDesc = new Text2('Shoot Faster!', {
size: 60,
fill: 0xFFF3E0
});
speedDesc.anchor.set(0, 0.5);
speedDesc.x = 2048 / 2 - 550;
speedDesc.y = 2732 / 2 + 80;
marketPanel.addChild(speedDesc);
var speedCost = new Text2('💰 ' + speedUpgradeCost, {
size: 90,
fill: storage.coins >= speedUpgradeCost ? 0xFFD700 : 0xFF4444
});
speedCost.anchor.set(1, 0.5);
speedCost.x = 2048 / 2 + 650;
speedCost.y = 2732 / 2 + 50;
marketPanel.addChild(speedCost);
var speedUpgrade = LK.getAsset('marketButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 + 50
});
speedUpgrade.alpha = 0.01;
speedUpgrade.down = function (x, y, obj) {
if (storage.coins >= speedUpgradeCost) {
storage.coins -= speedUpgradeCost;
speedUpgradeCost = Math.floor(speedUpgradeCost * 1.5); // Increase cost by 50%
storage.speedUpgradeCost = speedUpgradeCost; // Save to storage
storage.speedUpgrades++;
player.baseShootCooldown = Math.max(1, player.baseShootCooldown - 1);
coinDisplay.setText('COIN: ' + storage.coins);
LK.getSound('coinPurchase').play();
hideMarket();
showMarket(); // Refresh market display
}
};
marketPanel.addChild(speedUpgrade);
// Shotgun weapon section
var shotgunSection = LK.getAsset('Tahta', {
width: 1600,
height: 200,
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 + 300
});
shotgunSection.alpha = 0.8;
shotgunSection.tint = 0x795548;
marketPanel.addChild(shotgunSection);
var shotgunIcon = new Text2('🔫', {
size: 120,
fill: 0xFFFFFF
});
shotgunIcon.anchor.set(0.5, 0.5);
shotgunIcon.x = 2048 / 2 - 650;
shotgunIcon.y = 2732 / 2 + 300;
marketPanel.addChild(shotgunIcon);
var shotgunTitle = new Text2('POMPALΙ TÜFEK', {
size: 80,
fill: 0xFFFFFF
});
shotgunTitle.anchor.set(0, 0.5);
shotgunTitle.x = 2048 / 2 - 550;
shotgunTitle.y = 2732 / 2 + 270;
marketPanel.addChild(shotgunTitle);
var shotgunDesc = new Text2('Spread Shot +5 Bullets', {
size: 60,
fill: 0xEFEBE9
});
shotgunDesc.anchor.set(0, 0.5);
shotgunDesc.x = 2048 / 2 - 550;
shotgunDesc.y = 2732 / 2 + 330;
marketPanel.addChild(shotgunDesc);
var shotgunCost = new Text2(storage.hasShotgun ? 'SATILDI' : '💰 500', {
size: 90,
fill: storage.hasShotgun ? 0x888888 : storage.coins >= 500 ? 0xFFD700 : 0xFF4444
});
shotgunCost.anchor.set(1, 0.5);
shotgunCost.x = 2048 / 2 + 650;
shotgunCost.y = 2732 / 2 + 300;
marketPanel.addChild(shotgunCost);
var shotgunUpgrade = LK.getAsset('marketButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 + 300
});
shotgunUpgrade.alpha = 0.01;
shotgunUpgrade.down = function (x, y, obj) {
if (!storage.hasShotgun && storage.coins >= 500) {
storage.coins -= 500;
storage.hasShotgun = true;
player.weaponType = 'shotgun';
coinDisplay.setText('COIN: ' + storage.coins);
LK.getSound('coinPurchase').play();
hideMarket();
showMarket(); // Refresh market display
}
};
marketPanel.addChild(shotgunUpgrade);
// Machine gun weapon section
var machinegunSection = LK.getAsset('Tahta', {
width: 1600,
height: 200,
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 + 550
});
machinegunSection.alpha = 0.8;
machinegunSection.tint = 0x607D8B;
marketPanel.addChild(machinegunSection);
var machinegunIcon = new Text2('🔫', {
size: 120,
fill: 0xFFFFFF
});
machinegunIcon.anchor.set(0.5, 0.5);
machinegunIcon.x = 2048 / 2 - 650;
machinegunIcon.y = 2732 / 2 + 550;
marketPanel.addChild(machinegunIcon);
var machinegunTitle = new Text2('HAFİF MAKİNELİ TÜFEK', {
size: 80,
fill: 0xFFFFFF
});
machinegunTitle.anchor.set(0, 0.5);
machinegunTitle.x = 2048 / 2 - 550;
machinegunTitle.y = 2732 / 2 + 520;
marketPanel.addChild(machinegunTitle);
var machinegunDesc = new Text2('Rapid Fire Mode', {
size: 60,
fill: 0xECEFF1
});
machinegunDesc.anchor.set(0, 0.5);
machinegunDesc.x = 2048 / 2 - 550;
machinegunDesc.y = 2732 / 2 + 580;
marketPanel.addChild(machinegunDesc);
var machinegunCost = new Text2(storage.hasMachinegun ? 'SATILDI' : '💰 800', {
size: 90,
fill: storage.hasMachinegun ? 0x888888 : storage.coins >= 800 ? 0xFFD700 : 0xFF4444
});
machinegunCost.anchor.set(1, 0.5);
machinegunCost.x = 2048 / 2 + 650;
machinegunCost.y = 2732 / 2 + 550;
marketPanel.addChild(machinegunCost);
var machinegunUpgrade = LK.getAsset('marketButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 + 550
});
machinegunUpgrade.alpha = 0.01;
machinegunUpgrade.down = function (x, y, obj) {
if (!storage.hasMachinegun && storage.coins >= 800) {
storage.coins -= 800;
storage.hasMachinegun = true;
player.weaponType = 'machinegun';
coinDisplay.setText('COIN: ' + storage.coins);
LK.getSound('coinPurchase').play();
hideMarket();
showMarket(); // Refresh market display
}
};
marketPanel.addChild(machinegunUpgrade);
// Upgrade status display
var upgradeStatus = LK.getAsset('Tahta', {
width: 1600,
height: 150,
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 + 750
});
upgradeStatus.alpha = 0.8;
upgradeStatus.tint = 0x333333;
marketPanel.addChild(upgradeStatus);
var statusTitle = new Text2('📊 UPGRADE STATUS', {
size: 70,
fill: 0xFFFFFF
});
statusTitle.anchor.set(0.5, 0.5);
statusTitle.x = 2048 / 2;
statusTitle.y = 2732 / 2 + 710;
marketPanel.addChild(statusTitle);
var statusText = new Text2('❤️ ' + storage.healthUpgrades + ' 🔫 ' + storage.ammoUpgrades + ' ⚡ ' + storage.speedUpgrades + ' Weapon: ' + (player.weaponType || 'Normal'), {
size: 70,
fill: 0xFFD700
});
statusText.anchor.set(0.5, 0.5);
statusText.x = 2048 / 2;
statusText.y = 2732 / 2 + 790;
marketPanel.addChild(statusText);
// Enhanced close button
var closeButtonBg = LK.getAsset('Tahta', {
width: 800,
height: 150,
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 + 950
});
closeButtonBg.alpha = 0.9;
closeButtonBg.tint = 0x666666;
marketPanel.addChild(closeButtonBg);
var closeButton = LK.getAsset('marketButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 + 950
});
closeButton.alpha = 0.01;
closeButton.down = function (x, y, obj) {
hideMarket();
};
marketPanel.addChild(closeButton);
var closeText = new Text2('❌ CLOSE MARKET', {
size: 90,
fill: 0xFFFFFF
});
closeText.anchor.set(0.5, 0.5);
closeText.x = 2048 / 2;
closeText.y = 2732 / 2 + 950;
marketPanel.addChild(closeText);
game.addChild(marketPanel);
}
function hideMarket() {
if (marketPanel) {
marketPanel.destroy();
marketPanel = null;
}
showingMarket = false;
// Refresh weapon buttons if new weapons were purchased
refreshWeaponButtons();
}
function refreshWeaponButtons() {
// Remove existing weapon buttons
if (shotgunWeaponButton && !storage.hasShotgun) {
shotgunWeaponButton.destroy();
shotgunWeaponText.destroy();
shotgunWeaponButton = null;
shotgunWeaponText = null;
}
if (machinegunWeaponButton && !storage.hasMachinegun) {
machinegunWeaponButton.destroy();
machinegunWeaponText.destroy();
machinegunWeaponButton = null;
machinegunWeaponText = null;
}
// Add shotgun button if purchased and not already added
if (storage.hasShotgun && !shotgunWeaponButton) {
shotgunWeaponButton = LK.getAsset('weaponIcon', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 - 650,
y: 2732 - 120
});
shotgunWeaponButton.tint = player.weaponType === 'shotgun' ? 0x4CAF50 : 0x666666;
bottomPanel.addChild(shotgunWeaponButton);
shotgunWeaponText = new Text2('🔫', {
size: 60,
fill: 0xFFAA00
});
shotgunWeaponText.anchor.set(0.5, 0.5);
shotgunWeaponText.x = 2048 / 2 - 650;
shotgunWeaponText.y = 2732 - 120;
bottomPanel.addChild(shotgunWeaponText);
shotgunWeaponButton.down = function (x, y, obj) {
if (!showingGameOver && !showingMarket && !isPaused) {
player.weaponType = 'shotgun';
updateWeaponButtons();
}
};
}
// Add machine gun button if purchased and not already added
if (storage.hasMachinegun && !machinegunWeaponButton) {
machinegunWeaponButton = LK.getAsset('weaponIcon', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 - 500,
y: 2732 - 120
});
machinegunWeaponButton.tint = player.weaponType === 'machinegun' ? 0x4CAF50 : 0x666666;
bottomPanel.addChild(machinegunWeaponButton);
machinegunWeaponText = new Text2('🔫', {
size: 60,
fill: 0x00FF00
});
machinegunWeaponText.anchor.set(0.5, 0.5);
machinegunWeaponText.x = 2048 / 2 - 500;
machinegunWeaponText.y = 2732 - 120;
bottomPanel.addChild(machinegunWeaponText);
machinegunWeaponButton.down = function (x, y, obj) {
if (!showingGameOver && !showingMarket && !isPaused) {
player.weaponType = 'machinegun';
updateWeaponButtons();
}
};
}
}
function showPause() {
if (isPaused) return;
isPaused = true;
pausePanel = new Container();
// Semi-transparent background
var background = LK.getAsset('arena', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
scaleX: 3,
scaleY: 3
});
background.alpha = 0.8;
background.tint = 0x000000;
pausePanel.addChild(background);
// Pause menu panel with wooden background
var pauseMenuBackground = LK.getAsset('Tahta', {
width: 600,
height: 500,
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2
});
pauseMenuBackground.alpha = 0.9;
pausePanel.addChild(pauseMenuBackground);
// Pause title
var pauseTitle = new Text2('PAUSE MENU', {
size: 100,
fill: 0xFFFFFF
});
pauseTitle.anchor.set(0.5, 0.5);
pauseTitle.x = 2048 / 2;
pauseTitle.y = 2732 / 2 - 180;
pausePanel.addChild(pauseTitle);
// Restart button
var restartButton = LK.getAsset('marketButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 - 80
});
restartButton.tint = 0xFF5722;
restartButton.down = function (x, y, obj) {
hidePause();
restartGame();
};
pausePanel.addChild(restartButton);
var restartText = new Text2('RESTART', {
size: 60,
fill: 0xFFFFFF
});
restartText.anchor.set(0.5, 0.5);
restartText.x = 2048 / 2;
restartText.y = 2732 / 2 - 80;
pausePanel.addChild(restartText);
// Continue button
var continueButton = LK.getAsset('marketButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 + 20
});
continueButton.down = function (x, y, obj) {
hidePause();
};
pausePanel.addChild(continueButton);
var continueText = new Text2('CONTINUE', {
size: 60,
fill: 0xFFFFFF
});
continueText.anchor.set(0.5, 0.5);
continueText.x = 2048 / 2;
continueText.y = 2732 / 2 + 20;
pausePanel.addChild(continueText);
// Market button
var marketButton = LK.getAsset('marketButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 + 120
});
marketButton.tint = 0x2196F3;
marketButton.down = function (x, y, obj) {
hidePause();
showMarket();
};
pausePanel.addChild(marketButton);
var marketText = new Text2('MARKET', {
size: 60,
fill: 0xFFFFFF
});
marketText.anchor.set(0.5, 0.5);
marketText.x = 2048 / 2;
marketText.y = 2732 / 2 + 120;
pausePanel.addChild(marketText);
game.addChild(pausePanel);
}
function hidePause() {
if (pausePanel) {
pausePanel.destroy();
pausePanel = null;
}
isPaused = false;
}
function restartGame() {
hideGameOver();
// Reset player with upgraded stats
player.maxHealth = 100 + storage.healthUpgrades * 20;
player.health = player.maxHealth;
player.maxAmmo = 30 + storage.ammoUpgrades * 10;
player.ammo = player.maxAmmo;
player.baseShootCooldown = Math.max(1, 10 - storage.speedUpgrades);
player.x = 2048 / 2;
player.y = 2732 / 2;
// Clear all entities
for (var i = 0; i < zombies.length; i++) {
zombies[i].destroy();
}
zombies = [];
for (var i = 0; i < bullets.length; i++) {
bullets[i].destroy();
}
bullets = [];
// Reset game state
waveNumber = 1;
zombiesInWave = 5;
zombiesSpawned = 0;
spawnTimer = 0;
isFirstShot = true;
zombiesKilledInWave = 0;
zombiesRequiredToKill = 8;
isBossWave = false;
bossKilled = false;
// Keep current map state when restarting - don't change map unless unlocked
// If map is locked, stay on second map regardless of restart method
if (!mapLocked) {
// Only reset to first map if map is not locked
// Map only changes when specifically using Next Map button or when unlocked
}
LK.setScore(0);
}
function spawnZombie() {
var zombie;
// Check if this is a boss wave (every 15th wave)
if (isBossWave) {
if (isSecondMap) {
// On second map, spawn ice boss instead of regular boss
zombie = new IceBoss();
} else {
zombie = new BossZombie();
}
} else if (isSecondMap) {
// On second map, spawn ice monsters instead of regular zombies
zombie = new IceMonster();
} else {
// On forestMap (first map), spawn only regular zombies
zombie = Math.random() < 0.5 ? new Zombie() : new Zombie2();
}
// Define spawn locations around the arena edges
var spawnLocations = [{
x: Math.random() * 2048,
y: 100
},
// Top edge
{
x: Math.random() * 2048,
y: 2632
},
// Bottom edge
{
x: 100,
y: Math.random() * 2732
},
// Left edge
{
x: 1948,
y: Math.random() * 2732
},
// Right edge
{
x: 300,
y: 300
},
// Top-left corner
{
x: 1748,
y: 300
},
// Top-right corner
{
x: 300,
y: 2432
},
// Bottom-left corner
{
x: 1748,
y: 2432
} // Bottom-right corner
];
// Pick a random spawn location from the predefined spots
var spawnIndex = Math.floor(Math.random() * spawnLocations.length);
var spawnPoint = spawnLocations[spawnIndex];
zombie.x = spawnPoint.x;
zombie.y = spawnPoint.y;
// Only apply scaling to non-boss zombies
if (!isBossWave) {
// Increase zombie health by 25% every 5 waves
var healthMultiplier = Math.floor(waveNumber / 5) * 0.25;
zombie.health = Math.floor(1 * (1 + healthMultiplier));
// Increase zombie speed by 25% every 15 waves
var speedMultiplier = Math.floor(waveNumber / 15) * 0.25;
zombie.speed = zombie.speed * (1 + speedMultiplier);
// Increase zombie damage by 25% every 10 waves
var damageMultiplier = Math.floor(waveNumber / 10) * 0.25;
zombie.damage = Math.floor(zombie.damage * (1 + damageMultiplier));
zombie.scaleX = 1.0;
zombie.scaleY = 1.0;
} else {
// Boss zombies get stronger each boss wave
var bossWaveNumber = Math.floor(waveNumber / 15);
zombie.health = 10 + bossWaveNumber * 5; // More health each boss wave
zombie.damage = 25 + bossWaveNumber * 10; // More damage each boss wave
}
zombies.push(zombie);
game.addChild(zombie);
}
function shootBullet(targetX, targetY) {
if (player.shoot()) {
var dx = targetX - player.x;
var dy = targetY - player.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
// Rotate player to face shooting direction
player.rotation = Math.atan2(dy, dx);
}
if (player.weaponType === 'shotgun') {
// Shotgun fires 5 bullets in a spread pattern
for (var i = 0; i < 5; i++) {
var bullet = new ShotgunBullet();
bullet.x = player.x;
bullet.y = player.y;
var spreadAngle = (i - 2) * 0.3; // Spread bullets in a fan pattern
var angle = Math.atan2(dy, dx) + spreadAngle;
bullet.dx = Math.cos(angle);
bullet.dy = Math.sin(angle);
bullet.scaleX = 0.18;
bullet.scaleY = 0.18;
bullets.push(bullet);
game.addChild(bullet);
}
} else if (player.weaponType === 'machinegun') {
// Machine gun fires rapid bullets
var bullet = new MachinegunBullet();
bullet.x = player.x;
bullet.y = player.y;
bullet.dx = dx / distance;
bullet.dy = dy / distance;
bullet.scaleX = 0.12;
bullet.scaleY = 0.12;
bullets.push(bullet);
game.addChild(bullet);
} else {
// Normal weapon
var bullet = new Bullet();
bullet.x = player.x;
bullet.y = player.y;
bullet.dx = dx / distance;
bullet.dy = dy / distance;
bullet.scaleX = 0.15;
bullet.scaleY = 0.15;
bullets.push(bullet);
game.addChild(bullet);
}
if (soundEnabled) LK.getSound('shoot').play();
}
}
game.down = function (x, y, obj) {
// Pause menu button clicks when paused
if (isPaused) {
// Restart button click
if (x >= 2048 / 2 - 150 && x <= 2048 / 2 + 150 && y >= 2732 / 2 - 130 && y <= 2732 / 2 - 30) {
hidePause();
restartGame();
return;
}
// Continue button click
if (x >= 2048 / 2 - 150 && x <= 2048 / 2 + 150 && y >= 2732 / 2 - 30 && y <= 2732 / 2 + 70) {
hidePause();
return;
}
// Market button click
if (x >= 2048 / 2 - 150 && x <= 2048 / 2 + 150 && y >= 2732 / 2 + 70 && y <= 2732 / 2 + 170) {
hidePause();
showMarket();
return;
}
return;
}
if (showingGameOver) {
// Market button click detection
if (x >= 2048 / 2 - 150 && x <= 2048 / 2 + 150 && y >= 2732 / 2 + 10 && y <= 2732 / 2 + 90) {
showMarket();
return;
}
// Restart button click detection
if (x >= 2048 / 2 - 150 && x <= 2048 / 2 + 150 && y >= 2732 / 2 + 110 && y <= 2732 / 2 + 190) {
restartGame();
return;
}
} else if (showingMarket) {
var currentCoins = storage.coins;
// Health upgrade button click
if (x >= 2048 / 2 - 300 && x <= 2048 / 2 + 300 && y >= 2732 / 2 - 200 && y <= 2732 / 2 - 100) {
if (storage.coins >= healthUpgradeCost) {
storage.coins -= healthUpgradeCost;
healthUpgradeCost = Math.floor(healthUpgradeCost * 1.5); // Increase cost by 50%
storage.healthUpgradeCost = healthUpgradeCost; // Save to storage
storage.healthUpgrades++;
player.maxHealth += 20;
player.health = Math.min(player.health + 20, player.maxHealth);
coinDisplay.setText('COIN: ' + storage.coins);
LK.getSound('coinPurchase').play();
hideMarket();
showMarket(); // Refresh market display
}
return;
}
// Ammo upgrade button click
if (x >= 2048 / 2 - 250 && x <= 2048 / 2 + 250 && y >= 2732 / 2 - 100 && y <= 2732 / 2 + 0) {
if (storage.coins >= ammoUpgradeCost) {
storage.coins -= ammoUpgradeCost;
ammoUpgradeCost = Math.floor(ammoUpgradeCost * 1.5); // Increase cost by 50%
storage.ammoUpgradeCost = ammoUpgradeCost; // Save to storage
storage.ammoUpgrades++;
player.maxAmmo += 10;
player.ammo = Math.min(player.ammo + 10, player.maxAmmo);
coinDisplay.setText('COIN: ' + storage.coins);
LK.getSound('coinPurchase').play();
hideMarket();
showMarket(); // Refresh market display
}
return;
}
// Speed upgrade button click
if (x >= 2048 / 2 - 275 && x <= 2048 / 2 + 275 && y >= 2732 / 2 + 0 && y <= 2732 / 2 + 100) {
if (storage.coins >= speedUpgradeCost) {
storage.coins -= speedUpgradeCost;
speedUpgradeCost = Math.floor(speedUpgradeCost * 1.5); // Increase cost by 50%
storage.speedUpgradeCost = speedUpgradeCost; // Save to storage
storage.speedUpgrades++;
player.baseShootCooldown = Math.max(1, player.baseShootCooldown - 1);
coinDisplay.setText('COIN: ' + storage.coins);
LK.getSound('coinPurchase').play();
hideMarket();
showMarket(); // Refresh market display
}
return;
}
// Shotgun weapon button click
if (x >= 2048 / 2 - 300 && x <= 2048 / 2 + 300 && y >= 2732 / 2 + 250 && y <= 2732 / 2 + 350) {
if (!storage.hasShotgun && storage.coins >= 500) {
storage.coins -= 500;
storage.hasShotgun = true;
player.weaponType = 'shotgun';
coinDisplay.setText('COIN: ' + storage.coins);
LK.getSound('coinPurchase').play();
hideMarket();
showMarket(); // Refresh market display
}
return;
}
// Machine gun weapon button click
if (x >= 2048 / 2 - 300 && x <= 2048 / 2 + 300 && y >= 2732 / 2 + 500 && y <= 2732 / 2 + 600) {
if (!storage.hasMachinegun && storage.coins >= 800) {
storage.coins -= 800;
storage.hasMachinegun = true;
player.weaponType = 'machinegun';
coinDisplay.setText('COIN: ' + storage.coins);
LK.getSound('coinPurchase').play();
hideMarket();
showMarket(); // Refresh market display
}
return;
}
// Close button click
if (x >= 2048 / 2 - 200 && x <= 2048 / 2 + 200 && y >= 2732 / 2 + 900 && y <= 2732 / 2 + 1000) {
hideMarket();
return;
}
} else {
shootBullet(x, y);
}
};
game.update = function () {
if (showingGameOver || showingMarket || isPaused) {
return;
}
spawnTimer++;
if (zombiesSpawned < zombiesInWave && spawnTimer >= 60) {
spawnZombie();
zombiesSpawned++;
spawnTimer = 0;
}
// Check if required zombies killed to progress wave
if (zombiesKilledInWave >= zombiesRequiredToKill) {
waveNumber++;
zombiesKilledInWave = 0;
// Calculate new required kills (25% more than previous wave)
zombiesRequiredToKill = Math.ceil(zombiesRequiredToKill * 1.25);
// Check if current wave is a boss wave (every 15th wave)
isBossWave = waveNumber % 15 === 0;
if (isBossWave) {
zombiesInWave = 1; // Only 1 boss zombie
} else {
zombiesInWave = Math.min(5 + waveNumber * 2, 20);
}
zombiesSpawned = 0;
}
// Check if boss has been killed and prevent further spawning
var bossKilled = false;
for (var i = 0; i < zombies.length; i++) {
if (zombies[i] instanceof BossZombie) {
bossKilled = false;
break;
}
}
if (isBossWave && zombiesSpawned > 0 && zombies.length === 0) {
// Boss was killed, don't spawn more zombies
return;
}
if (zombiesSpawned >= zombiesInWave && zombies.length === 0) {
// Keep spawning zombies until kill requirement is met
zombiesSpawned = 0;
}
// Check if player has no ammo and end game
if (player.ammo <= 0) {
LK.effects.flashScreen(0xff0000, 1000);
showCustomGameOver();
return;
}
healthBar.setText('Health: ' + player.health);
ammoDisplay.setText('Ammo: ' + player.ammo);
scoreDisplay.setText('SCORE: ' + LK.getScore());
coinDisplay.setText('COIN: ' + storage.coins);
waveInfo.setText('Wave: ' + waveNumber + (isBossWave ? ' (BOSS)' : ''));
killProgress.setText('Kills: ' + zombiesKilledInWave + '/' + zombiesRequiredToKill);
weaponStatus.setText('Weapon: ' + (player.weaponType || 'Normal'));
for (var i = bullets.length - 1; i >= 0; i--) {
bullets[i].update();
}
for (var i = zombies.length - 1; i >= 0; i--) {
zombies[i].update();
}
};
// Sound toggle button
var soundButton = LK.getAsset('Tahta', {
width: 120,
height: 120,
anchorX: 1,
anchorY: 1,
x: 0,
y: -130
});
soundButton.alpha = 0.8;
LK.gui.bottomRight.addChild(soundButton);
var soundText = new Text2('🔊', {
size: 60,
fill: 0xFFFFFF
});
soundText.anchor.set(0.5, 0.5);
soundText.x = -60;
soundText.y = -190;
LK.gui.bottomRight.addChild(soundText);
var soundEnabled = true;
soundButton.down = function (x, y, obj) {
if (soundEnabled) {
soundText.setText('🔇');
soundText.alpha = 0.5;
soundEnabled = false;
} else {
soundText.setText('🔊');
soundText.alpha = 1.0;
soundEnabled = true;
}
};
// Music toggle button
var musicButton = LK.getAsset('Tahta', {
width: 120,
height: 120,
anchorX: 1,
anchorY: 1,
x: 0,
y: 0
});
musicButton.alpha = 0.8;
LK.gui.bottomRight.addChild(musicButton);
var musicText = new Text2('♪', {
size: 80,
fill: 0xFFFFFF
});
musicText.anchor.set(0.5, 0.5);
musicText.x = -60;
musicText.y = -60;
LK.gui.bottomRight.addChild(musicText);
var musicPlaying = true;
musicButton.down = function (x, y, obj) {
if (musicPlaying) {
LK.stopMusic();
musicText.setText('♪');
musicText.alpha = 0.5;
musicPlaying = false;
} else {
// Market quick access button
var marketQuickButton = LK.getAsset('Tahta', {
width: 120,
height: 120,
anchorX: 0.5,
anchorY: 1,
x: 0,
y: 0
});
marketQuickButton.alpha = 0.8;
LK.gui.bottom.addChild(marketQuickButton);
var marketQuickText = new Text2('🛒', {
size: 80,
fill: 0xFFFFFF
});
marketQuickText.anchor.set(0.5, 0.5);
marketQuickText.x = 0;
marketQuickText.y = -60;
LK.gui.bottom.addChild(marketQuickText);
marketQuickButton.down = function (x, y, obj) {
if (!showingGameOver && !showingMarket && !isPaused) {
showMarket();
}
};
// Surrender button in top-left corner next to pause shortcut
var surrenderButton = LK.getAsset('Tahta', {
width: 120,
height: 120,
anchorX: 0,
anchorY: 0,
x: 120,
y: 0
});
surrenderButton.alpha = 0.8;
LK.gui.topLeft.addChild(surrenderButton);
var surrenderText = new Text2('🏳️', {
size: 80,
fill: 0xFFFFFF
});
surrenderText.anchor.set(0.5, 0.5);
surrenderText.x = 60;
surrenderText.y = 60;
LK.gui.topLeft.addChild(surrenderText);
surrenderButton.down = function (x, y, obj) {
if (!showingGameOver && !showingMarket && !isPaused) {
player.ammo = 0;
LK.effects.flashScreen(0xff0000, 1000);
showCustomGameOver();
}
};
// Market button in top-right corner
var topMarketButton = LK.getAsset('Tahta', {
width: 120,
height: 120,
anchorX: 1,
anchorY: 0,
x: 0,
y: 0
});
topMarketButton.alpha = 0.8;
LK.gui.topRight.addChild(topMarketButton);
var topMarketText = new Text2('🛒', {
size: 80,
fill: 0xFFFFFF
});
topMarketText.anchor.set(0.5, 0.5);
topMarketText.x = -60;
topMarketText.y = 60;
LK.gui.topRight.addChild(topMarketText);
topMarketButton.down = function (x, y, obj) {
if (!showingGameOver && !showingMarket && !isPaused) {
showMarket();
}
};
// Bottom panel for game interface
var bottomPanel = new Container();
var bottomPanelBg = LK.getAsset('Tahta', {
width: 2048,
height: 300,
anchorX: 0.5,
anchorY: 1,
x: 2048 / 2,
y: 2732
});
bottomPanelBg.alpha = 0.9;
bottomPanelBg.tint = 0x2a2a2a;
bottomPanel.addChild(bottomPanelBg);
// Panel title
var panelTitle = new Text2('GAME CONTROLS', {
size: 80,
fill: 0xFFD700
});
panelTitle.anchor.set(0.5, 0);
panelTitle.x = 2048 / 2;
panelTitle.y = 2732 - 280;
bottomPanel.addChild(panelTitle);
// Ammo reload button
var reloadButton = LK.getAsset('Tahta', {
width: 200,
height: 80,
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 - 120
});
reloadButton.alpha = 0.8;
reloadButton.tint = 0x4CAF50;
bottomPanel.addChild(reloadButton);
var reloadText = new Text2('RELOAD', {
size: 50,
fill: 0xFFFFFF
});
reloadText.anchor.set(0.5, 0.5);
reloadText.x = 2048 / 2;
reloadText.y = 2732 - 120;
bottomPanel.addChild(reloadText);
reloadButton.down = function (x, y, obj) {
if (!showingGameOver && !showingMarket && !isPaused) {
player.ammo = player.maxAmmo;
LK.effects.flashObject(reloadButton, 0x00ff00, 200);
}
};
// Quick market access
var quickMarketButton = LK.getAsset('Tahta', {
width: 200,
height: 80,
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 + 400,
y: 2732 - 120
});
quickMarketButton.alpha = 0.8;
quickMarketButton.tint = 0x2196F3;
bottomPanel.addChild(quickMarketButton);
var quickMarketText = new Text2('MARKET', {
size: 50,
fill: 0xFFFFFF
});
quickMarketText.anchor.set(0.5, 0.5);
quickMarketText.x = 2048 / 2 + 400;
quickMarketText.y = 2732 - 120;
bottomPanel.addChild(quickMarketText);
quickMarketButton.down = function (x, y, obj) {
if (!showingGameOver && !showingMarket && !isPaused) {
showMarket();
}
};
// Weapon selection section title
var weaponSectionTitle = new Text2('WEAPON SELECTION', {
size: 50,
fill: 0xFFD700
});
weaponSectionTitle.anchor.set(0.5, 0);
weaponSectionTitle.x = 2048 / 2 - 600;
weaponSectionTitle.y = 2732 - 200;
bottomPanel.addChild(weaponSectionTitle);
// Add weapon status to bottom panel
weaponStatus.anchor.set(0.5, 0);
weaponStatus.x = 2048 / 2 - 400;
weaponStatus.y = 2732 - 200;
bottomPanel.addChild(weaponStatus);
// Normal weapon button
normalWeaponButton = LK.getAsset('weaponIcon', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 - 800,
y: 2732 - 120
});
normalWeaponButton.tint = player.weaponType === 'normal' ? 0x4CAF50 : 0x666666;
bottomPanel.addChild(normalWeaponButton);
normalWeaponText = new Text2('🔫', {
size: 60,
fill: 0xFFFFFF
});
normalWeaponText.anchor.set(0.5, 0.5);
normalWeaponText.x = 2048 / 2 - 800;
normalWeaponText.y = 2732 - 120;
bottomPanel.addChild(normalWeaponText);
normalWeaponButton.down = function (x, y, obj) {
if (!showingGameOver && !showingMarket && !isPaused) {
player.weaponType = 'normal';
updateWeaponButtons();
}
};
// Define weapon button variables in global scope
var shotgunWeaponButton = null;
var shotgunWeaponText = null;
var machinegunWeaponButton = null;
var machinegunWeaponText = null;
var normalWeaponButton = null;
var normalWeaponText = null;
// Shotgun weapon button (only if purchased)
if (storage.hasShotgun) {
shotgunWeaponButton = LK.getAsset('weaponIcon', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 - 650,
y: 2732 - 120
});
shotgunWeaponButton.tint = player.weaponType === 'shotgun' ? 0x4CAF50 : 0x666666;
bottomPanel.addChild(shotgunWeaponButton);
shotgunWeaponText = new Text2('🔫', {
size: 60,
fill: 0xFFAA00
});
shotgunWeaponText.anchor.set(0.5, 0.5);
shotgunWeaponText.x = 2048 / 2 - 650;
shotgunWeaponText.y = 2732 - 120;
bottomPanel.addChild(shotgunWeaponText);
shotgunWeaponButton.down = function (x, y, obj) {
if (!showingGameOver && !showingMarket && !isPaused) {
player.weaponType = 'shotgun';
updateWeaponButtons();
}
};
}
// Machine gun weapon button (only if purchased)
if (storage.hasMachinegun) {
machinegunWeaponButton = LK.getAsset('weaponIcon', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 - 500,
y: 2732 - 120
});
machinegunWeaponButton.tint = player.weaponType === 'machinegun' ? 0x4CAF50 : 0x666666;
bottomPanel.addChild(machinegunWeaponButton);
machinegunWeaponText = new Text2('🔫', {
size: 60,
fill: 0x00FF00
});
machinegunWeaponText.anchor.set(0.5, 0.5);
machinegunWeaponText.x = 2048 / 2 - 500;
machinegunWeaponText.y = 2732 - 120;
bottomPanel.addChild(machinegunWeaponText);
machinegunWeaponButton.down = function (x, y, obj) {
if (!showingGameOver && !showingMarket && !isPaused) {
player.weaponType = 'machinegun';
updateWeaponButtons();
}
};
}
var pauseButton = LK.getAsset('Tahta', {
width: 200,
height: 80,
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 - 400,
y: 2732 - 120
});
pauseButton.alpha = 0.8;
pauseButton.tint = 0xFF9800;
bottomPanel.addChild(pauseButton);
var pauseText = new Text2('PAUSE', {
size: 50,
fill: 0xFFFFFF
});
pauseText.anchor.set(0.5, 0.5);
pauseText.x = 2048 / 2 - 400;
pauseText.y = 2732 - 120;
bottomPanel.addChild(pauseText);
pauseButton.down = function (x, y, obj) {
if (!showingGameOver && !showingMarket && !isPaused) {
showPause();
}
};
game.addChild(bottomPanel);
LK.playMusic('bgmusic');
musicText.setText('♪');
musicText.alpha = 1.0;
musicPlaying = true;
}
};
LK.playMusic('bgmusic');
Üstten görünümlü zombi. In-Game asset. 2d. High contrast. No shadows
Ortasında elips şeklinde bir boşluk hariç her yeri sık ağaçlık olan bir orman. In-Game asset. 2d. High contrast. No shadows
Ahşap tema. In-Game asset. 2d. High contrast. No shadows
pompalı tüfek mermisi. In-Game asset. 2d. High contrast. No shadows
hafif makineli tüfek mermisi. In-Game asset. 2d. High contrast. No shadows
Uzi çiz. In-Game asset. 2d. High contrast. No shadows
Pompalı Tüfek. In-Game asset. 2d. High contrast. No shadows
Bunun arkaplanını sil
Arkaplanını sil
boss zombie. In-Game asset. 2d. High contrast. No shadows
dümdüz sadece buzullardan oluşsun aralarında yarıklar olmasın