/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ // Coin (altın) kutusu var Coin = Container.expand(function () { var self = Container.call(this); var coinGfx = self.attachAsset('coin', { anchorX: 0.5, anchorY: 0.5 }); self.radius = coinGfx.width * 0.5; self.update = function () { // Hafifçe döndür coinGfx.rotation += 0.12; }; return self; }); // Düşman karakteri (AI) - Enemy1: Kendini iyileştirme yeteneği var Enemy = Container.expand(function () { var self = Container.call(this); var enemyGfx = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5 }); self.radius = enemyGfx.width * 0.5; self.type = 1; self.speed = 3 + Math.random() * 2; self.dir = Math.random() * Math.PI * 2; self.shootCooldown = 60 + Math.floor(Math.random() * 60); self.targetX = 0; self.targetY = 0; self.maxHealth = 3 + Math.floor(Math.random() * 2); // 3-4 can self.health = self.maxHealth; // --- YENİ: Kendini iyileştirme özelliği --- self.healCooldown = 180 + Math.floor(Math.random() * 120); // 3-5 saniyede bir // --- KOMİK KONUŞMA BALONU --- // Funny lines (ENGLISH + EMOJIS) self._funnyLines = ["You can't catch me! 🏃♂️💨", "That tickles! 😂", "I'm about to explode! 💥", "Alien or comedian? 👽🤡", "Look, I'm dancing! 🕺", "Don't shoot, I'm friendly! ✌️", "Tea break time! 🍵", "Beep bop! Error! 🤖", "Are you a hero or a clown? 🦸♂️🤡", "Leveling up soon! ⏫", "Oops, wrong galaxy! 💫", "Pizza delivery! 🍕", "I want a burger! 🍔", "Insert coin to continue! 👾", "Dance battle, anyone? 💃", "Quack! Wrong sound? 🦆", "Say cheese! 🧀", "Rawr! I'm a tiny dino. 🦖", "Brain freeze! 🧠❄️", "Crab rave time! 🦀🎶", "Hoot hoot! Night shift. 🦉", "I floss daily. 🦷", "To the moon! 🚀", "Catch me if you can! 😜", "This is my serious face. 🥸"]; self._speechBubble = null; self._speechTimer = 0; self._showSpeech = function (text) { // Eski balon varsa sil if (self._speechBubble) { self._speechBubble.destroy(); self._speechBubble = null; } var bubble = new Text2(text, { size: 48, fill: 0xffffff, font: "Impact" }); bubble.anchor.set(0.5, 1); bubble.x = self.x; bubble.y = self.y - self.radius - 60; bubble.alpha = 1; game.addChild(bubble); self._speechBubble = bubble; // Balonu 1.2 saniyede kaybolacak şekilde animasyonla tween(bubble, { alpha: 0 }, { duration: 1200, onFinish: function onFinish() { if (bubble) bubble.visible = false; if (self._speechBubble === bubble) self._speechBubble = null; } }); }; self.takeDamage = function (amount) { self.health -= amount; LK.effects.flashObject(self, 0xffff00, 200); // Komik konuşma: Hasar alınca %60 ihtimalle konuşsun if (Math.random() < 0.6) { var line = self._funnyLines[Math.floor(Math.random() * self._funnyLines.length)]; self._showSpeech(line); } if (self.health <= 0) { // Destroy health bar if exists if (self._healthBar) { self._healthBar.destroy(); self._healthBar = null; } // Destroy visible health bar if exists if (self._visHealthBar) { self._visHealthBar.destroy(); self._visHealthBar = null; self._visHealthBarBg = null; self._visHealthBarFg = null; } self.destroy(); // Skor boost varsa 2 puan ver if (player._superScoreBoost && player._scoreBoost > 0) { score += 10 + (comboCount > 1 ? comboCount : 0); } else if (player._scoreBoost && player._scoreBoost > 0) { score += 2 + (comboCount > 1 ? comboCount : 0); } else { score += 1 + (comboCount > 1 ? comboCount : 0); } updateScoreAndLevel(); if (score > 0 && score % 10 === 0) { increaseDifficulty(); } // Remove from enemies array in main loop self._shouldRemove = true; } }; self.update = function () { if (self._frozen && self._frozen > 0) { // Donmuşsa titret self.x += Math.sin(self._frozen) * 2; self.y += Math.cos(self._frozen) * 2; return; } // --- YENİ: Kendini iyileştirme --- if (self.healCooldown > 0) { self.healCooldown--; } else { if (self.health < self.maxHealth) { self.health++; LK.effects.flashObject(self, 0x00ff00, 200); } self.healCooldown = 180 + Math.floor(Math.random() * 120); } // Basit AI: Oyuncuya doğru hareket et var dx = player.x - self.x; var dy = player.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 1) { self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; } // Ateş etme if (self.shootCooldown > 0) { self.shootCooldown--; } else { self.shootCooldown = 90 + Math.floor(Math.random() * 60); spawnEnemyBullet(self.x, self.y, player.x, player.y); } // --- KOMİK KONUŞMA: Rastgele aralıklarla konuşsun --- // Her update'de sayaç azalt, 0 olunca konuş if (self._speechTimer > 0) { self._speechTimer--; } else if (Math.random() < 0.01) { // %1 ihtimalle her frame var line = self._funnyLines[Math.floor(Math.random() * self._funnyLines.length)]; self._showSpeech(line); self._speechTimer = 180 + Math.floor(Math.random() * 120); // 3-5 saniye bekle } // --- HEALTH BAR (rectangle) --- // Create health bar if not exists if (!self._visHealthBar) { self._visHealthBar = new Container(); self._visHealthBarBg = new Container(); self._visHealthBarFg = new Container(); self._visHealthBar.addChild(self._visHealthBarBg); self._visHealthBar.addChild(self._visHealthBarFg); game.addChild(self._visHealthBar); } if (self._visHealthBar) { // Position above enemy self._visHealthBar.x = self.x; self._visHealthBar.y = self.y - self.radius - 28; // Health percent var hp = Math.max(0, self.health) / self.maxHealth; // Clamp width var fgWidth = Math.max(24, 180 * hp); self._visHealthBarFg.width = fgWidth; // Color: green > yellow > red if (hp > 0.6) { self._visHealthBarFg.tint = 0x00ff00; } else if (hp > 0.3) { self._visHealthBarFg.tint = 0xffe100; } else { self._visHealthBarFg.tint = 0xff4444; } self._visHealthBar.visible = true; } // Konuşma balonunu takip ettir if (self._speechBubble) { self._speechBubble.x = self.x; self._speechBubble.y = self.y - self.radius - 60; } }; return self; }); // Düşman karakteri 2 (dairesel hareket, elips) - Enemy2: Kalkan oluşturma yeteneği var Enemy2 = Container.expand(function () { var self = Container.call(this); var enemyGfx = self.attachAsset('enemy2', { anchorX: 0.5, anchorY: 0.5 }); self.radius = enemyGfx.width * 0.5; self.type = 2; self.angle = Math.random() * Math.PI * 2; // Enemy2: Orbit around a random point in the arena, not the player self.centerX = 200 + Math.random() * 1648; self.centerY = 200 + Math.random() * 2332; self.orbitRadius = 400 + Math.random() * 200; self.speed = 0.012 + Math.random() * 0.008; self.shootCooldown = 120 + Math.floor(Math.random() * 60); self.maxHealth = 4 + Math.floor(Math.random() * 2); // 4-5 can self.health = self.maxHealth; // --- YENİ: Kalkan özelliği --- self.shield = 0; self.shieldCooldown = 240 + Math.floor(Math.random() * 120); // 4-6 saniyede bir self.takeDamage = function (amount) { if (self.shield > 0) { self.shield--; LK.effects.flashObject(self, 0x00ffff, 200); return; } self.health -= amount; LK.effects.flashObject(self, 0xffff00, 200); if (self.health <= 0) { // Destroy health bar if exists if (self._healthBar) { self._healthBar.destroy(); self._healthBar = null; } // Destroy visible health bar if exists if (self._visHealthBar) { self._visHealthBar.destroy(); self._visHealthBar = null; self._visHealthBarBg = null; self._visHealthBarFg = null; } self.destroy(); if (player._scoreBoost && player._scoreBoost > 0) { score += 2 + (comboCount > 1 ? comboCount : 0); } else { score += 1 + (comboCount > 1 ? comboCount : 0); } updateScoreAndLevel(); if (score > 0 && score % 10 === 0) { increaseDifficulty(); } self._shouldRemove = true; } }; self.update = function () { if (self._frozen && self._frozen > 0) { self.x += Math.sin(self._frozen) * 2; self.y += Math.cos(self._frozen) * 2; return; } // --- YENİ: Kalkan oluşturma --- if (self.shieldCooldown > 0) { self.shieldCooldown--; } else { self.shield = 2; // 2 vuruşluk kalkan self.shieldCooldown = 240 + Math.floor(Math.random() * 120); LK.effects.flashObject(self, 0x00ffff, 200); } // Kalkan efekti için: kalkanı varsa hafif mavi tint if (self.shield > 0 && enemyGfx) { enemyGfx.alpha = 0.7; } else if (enemyGfx) { enemyGfx.alpha = 1.0; } self.angle += self.speed; self.x = self.centerX + Math.cos(self.angle) * self.orbitRadius; self.y = self.centerY + Math.sin(self.angle) * self.orbitRadius; // Ateş etme if (self.shootCooldown > 0) { self.shootCooldown--; } else { self.shootCooldown = 120 + Math.floor(Math.random() * 60); spawnEnemyBullet(self.x, self.y, player.x, player.y); } // --- HEALTH BAR (rectangle) --- // Create health bar if not exists if (!self._visHealthBar) { self._visHealthBar = new Container(); self._visHealthBarBg = new Container(); self._visHealthBarFg = new Container(); self._visHealthBar.addChild(self._visHealthBarBg); self._visHealthBar.addChild(self._visHealthBarFg); game.addChild(self._visHealthBar); } if (self._visHealthBar) { // Position above enemy self._visHealthBar.x = self.x; self._visHealthBar.y = self.y - self.radius - 28; // Health percent var hp = Math.max(0, self.health) / self.maxHealth; // Clamp width var fgWidth = Math.max(24, 180 * hp); self._visHealthBarFg.width = fgWidth; // Color: green > yellow > red if (hp > 0.6) { self._visHealthBarFg.tint = 0x00ff00; } else if (hp > 0.3) { self._visHealthBarFg.tint = 0xffe100; } else { self._visHealthBarFg.tint = 0xff4444; } self._visHealthBar.visible = true; } }; return self; }); // Düşman karakteri 3 (rastgele zıplama, mor kutu) - Enemy3: Ölünce ikiye bölünme yeteneği var Enemy3 = Container.expand(function () { var self = Container.call(this); var enemyGfx = self.attachAsset('enemy3', { anchorX: 0.5, anchorY: 0.5 }); self.radius = enemyGfx.width * 0.5; self.type = 3; self.jumpTimer = 60 + Math.floor(Math.random() * 60); self.targetX = 200 + Math.random() * 1648; self.targetY = 200 + Math.random() * 2332; self.speed = 12 + Math.random() * 6; self.shootCooldown = 100 + Math.floor(Math.random() * 60); self.maxHealth = 2 + Math.floor(Math.random() * 2); // 2-3 can self.health = self.maxHealth; self.takeDamage = function (amount) { self.health -= amount; LK.effects.flashObject(self, 0xffff00, 200); if (self.health <= 0) { // Destroy health bar if exists if (self._healthBar) { self._healthBar.destroy(); self._healthBar = null; } // Destroy visible health bar if exists if (self._visHealthBar) { self._visHealthBar.destroy(); self._visHealthBar = null; self._visHealthBarBg = null; self._visHealthBarFg = null; } // Splitting on death removed self.destroy(); if (player._scoreBoost && player._scoreBoost > 0) { score += 2 + (comboCount > 1 ? comboCount : 0); } else { score += 1 + (comboCount > 1 ? comboCount : 0); } updateScoreAndLevel(); if (score > 0 && score % 10 === 0) { increaseDifficulty(); } self._shouldRemove = true; } }; self.update = function () { if (self._frozen && self._frozen > 0) { self.x += Math.sin(self._frozen) * 2; self.y += Math.cos(self._frozen) * 2; return; } self.jumpTimer--; if (self.jumpTimer <= 0) { self.targetX = 200 + Math.random() * 1648; self.targetY = 200 + Math.random() * 2332; self.jumpTimer = 60 + Math.floor(Math.random() * 60); } var dx = self.targetX - self.x; var dy = self.targetY - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 1) { self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; } // Ateş etme if (self.shootCooldown > 0) { self.shootCooldown--; } else { self.shootCooldown = 100 + Math.floor(Math.random() * 60); spawnEnemyBullet(self.x, self.y, player.x, player.y); } // --- HEALTH BAR (rectangle) --- // Create health bar if not exists if (!self._visHealthBar) { self._visHealthBar = new Container(); self._visHealthBarBg = new Container(); self._visHealthBarFg = new Container(); self._visHealthBar.addChild(self._visHealthBarBg); self._visHealthBar.addChild(self._visHealthBarFg); game.addChild(self._visHealthBar); } if (self._visHealthBar) { // Position above enemy self._visHealthBar.x = self.x; self._visHealthBar.y = self.y - self.radius - 28; // Health percent var hp = Math.max(0, self.health) / self.maxHealth; // Clamp width var fgWidth = Math.max(24, 180 * hp); self._visHealthBarFg.width = fgWidth; // Color: green > yellow > red if (hp > 0.6) { self._visHealthBarFg.tint = 0x00ff00; } else if (hp > 0.3) { self._visHealthBarFg.tint = 0xffe100; } else { self._visHealthBarFg.tint = 0xff4444; } self._visHealthBar.visible = true; } }; return self; }); // Düşman mermisi var EnemyBullet = Container.expand(function () { var self = Container.call(this); var bulletGfx = self.attachAsset('enemyBullet', { anchorX: 0.5, anchorY: 0.5 }); self.radius = bulletGfx.width * 0.5; self.vx = 0; self.vy = 0; self.update = function () { self.x += self.vx; self.y += self.vy; }; return self; }); // Oyuncu karakteri var Player = Container.expand(function () { var self = Container.call(this); var playerGfx = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.radius = playerGfx.width * 0.5; self.shootCooldown = 0; // Oyuncuya can ekle self.maxHealth = typeof playerMaxHealth !== "undefined" ? playerMaxHealth : 5; self.health = typeof playerHealth !== "undefined" ? playerHealth : self.maxHealth; self.update = function () { if (self.shootCooldown > 0) self.shootCooldown--; }; return self; }); // Oyuncu mermisi var PlayerBullet = Container.expand(function () { var self = Container.call(this); var bulletGfx = self.attachAsset('playerBullet', { anchorX: 0.5, anchorY: 0.5 }); self.radius = bulletGfx.width * 0.5; self.vx = 0; self.vy = 0; self.update = function () { self.x += self.vx; self.y += self.vy; }; return self; }); // Güçlendirici (PowerUp) kutusu var PowerUp = Container.expand(function () { var self = Container.call(this); var powerGfx = self.attachAsset('powerUp', { anchorX: 0.5, anchorY: 0.5 }); self.radius = powerGfx.width * 0.5; self.type = "power"; // Yeni powerup efektleri eklendi var effects = ["rapid", // Hızlı ateş (fire rate) "triple", // Üçlü atış "shield", // Kalkan "heal", // Can doldur "wallBounce", // Duvar sekme "reflect", // Düşman mermisi sektirme "slow", // Zaman yavaşlatma (tüm düşmanlar yavaşlar) "magnet", // Magnet (yakındaki coin/powerup çeker) "randomizer", // Randomizer (tüm düşmanların tipi değişir) "superHeal", // Süper can: max canı artır ve doldur "freezeBullets", // Düşman mermilerini dondur "coinRain", // Ekrana coin yağmuru "enemyClear", // Tüm düşmanları yok et "scoreBoost" // Skor 2x (15s) ]; self.effect = effects[Math.floor(Math.random() * effects.length)]; self.update = function () { // Hafifçe döndür powerGfx.rotation += 0.08; }; return self; }); // PowerUpCombo: Birleşmiş poweruplar için özel kutu var PowerUpCombo = Container.expand(function () { var self = Container.call(this); var powerGfx = self.attachAsset('powerUp', { anchorX: 0.5, anchorY: 0.5 }); self.radius = powerGfx.width * 0.6; self.type = "powerCombo"; self.effects = []; // ["rapid", "triple", ...] self.update = function () { // Hafifçe döndür ve renk değiştir (her efekt için farklı renkler) powerGfx.rotation += 0.12; // Renkleri birleştir: efekt sayısına göre tint değiştir if (self.effects.indexOf("slow") !== -1 && self.effects.length === 1) { powerGfx.tint = 0x66ccff; // Mavi (slow) } else if (self.effects.indexOf("magnet") !== -1 && self.effects.length === 1) { powerGfx.tint = 0xff00ff; // Magnet için mor } else if (self.effects.indexOf("randomizer") !== -1 && self.effects.length === 1) { powerGfx.tint = 0x00ffcc; // Randomizer için turkuaz } else if (self.effects.length === 2) { powerGfx.tint = 0xFFD700; // Altın } else if (self.effects.length >= 3) { powerGfx.tint = 0xFF44FF; // Pembe } else { powerGfx.tint = 0xFFFFFF; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x0074D9 }); /**** * Game Code ****/ // Space background images (add your own image asset IDs as needed) // --- SPACE BACKGROUND --- // Global değişkenler // Space backgrounds as assets var spaceBackgrounds = [{ id: 'spacebg1', width: 2048, height: 2732, assetId: '682e6b2ad10b0c0b481370a1' }, { id: 'spacebg2', width: 2048, height: 2732, assetId: '682e6b3fd10b0c0b481370a2' }, { id: 'spacebg3', width: 2048, height: 2732, assetId: '682e6b4ad10b0c0b481370a3' }]; // Register background assets (engine will load them automatically) for (var i = 0; i < spaceBackgrounds.length; i++) {} // Pick a random background var selectedBg = spaceBackgrounds[Math.floor(Math.random() * spaceBackgrounds.length)]; var bgSprite = LK.getAsset(selectedBg.id, { anchorX: 0, anchorY: 0 }); bgSprite.x = 0; bgSprite.y = 0; bgSprite.width = 2048; bgSprite.height = 2732; game.addChildAt(bgSprite, 0); // Add as the bottom-most layer // Coin asset var player; var enemies = []; var playerBullets = []; var enemyBullets = []; var powerUps = []; var coins = []; // Coin objects var coinCount = 0; // Collected coin count var coinTxt = new Text2('₵ ' + coinCount, { size: 70, fill: 0xFFD700, font: "Impact" }); coinTxt.anchor.set(0.5, 0); LK.gui.top.addChild(coinTxt); coinTxt.y = 340; var powerActive = false; var powerTimer = 0; var dragNode = null; var lastPlayerPos = { x: 0, y: 0 }; var score = 0; var level = 1; var gameTick = 0; var spawnTimer = 0; var isGameOver = false; // Combo variables var comboCount = 0; var comboTimer = 0; var maxComboTime = 120; // 2 seconds (120 frames) var maxCombo = 0; // Combo GUI var comboTxt = new Text2('', { size: 80, fill: 0xFFFA00, font: "Impact" }); comboTxt.anchor.set(0.5, 0); LK.gui.top.addChild(comboTxt); comboTxt.y = 260; // Health bar variables // Permanent max health and max attack upgrades RESET storage.permMaxHealthUp = 0; storage.permMaxAttackUp = 0; // Permanent max health upgrade from storage var permHealthUp = typeof storage.permMaxHealthUp === "number" ? storage.permMaxHealthUp : 0; var playerMaxHealth = 10 + permHealthUp; var playerHealth = playerMaxHealth; // Health bar GUI var healthTxt = new Text2('Health: ' + playerHealth, { size: 70, fill: 0xFF4444 }); healthTxt.anchor.set(0.5, 0); LK.gui.top.addChild(healthTxt); healthTxt.y = 180; // --- HOW TO PLAY POPUP (before game starts) --- var howToPlayTxt = new Text2("Nasıl Oynanır?\n\n" + "- Parmağınızı ekrana basılı tutup karakterinizi ARENADA sürükleyin.\n" + "- Düşmanlardan ve mermilerden kaçın, otomatik ateşle düşmanları yok edin!\n" + "- Güçlendiricileri (PowerUp) ve altınları toplayın.\n" + "- Kombo yaparak daha fazla puan kazanın.\n" + "- Sol üstte istatistiklerinizi takip edin.\n\n" + "Başlamak için ekrana dokunun!", { size: 70, fill: "#fff", font: "Impact", align: "center", wordWrap: true, wordWrapWidth: 1600 }); howToPlayTxt.anchor.set(0.5, 0.5); howToPlayTxt.x = 2048 / 2; howToPlayTxt.y = 2732 / 2; howToPlayTxt.background = { color: 0x222244, alpha: 0.92, padding: 60, radius: 48 }; LK.gui.center.addChild(howToPlayTxt); // Oyuncu dokununca başlat var howToPlayActive = true; game.down = function (x, y, obj) { if (howToPlayActive) { howToPlayActive = false; howToPlayTxt.visible = false; startGame(); } else { // If player is tapped, start dragging var px = player.x, py = player.y; var dx = x - px, dy = y - py; var dist = Math.sqrt(dx * dx + dy * dy); // User-friendly: If tapped on player, start dragging, otherwise do nothing if (dist < player.radius + 80) { // wider area, easier drag dragNode = player; lastPlayerPos.x = x; lastPlayerPos.y = y; // When drag starts, don't fire, prevent accidental fire // Drag threshold: set a flag to check if drag distance exceeds a threshold before firing dragNode._dragStarted = false; dragNode._dragStartX = x; dragNode._dragStartY = y; dragNode._dragStartTime = Date.now(); } else { // (Removed: tap-to-shoot code is now gone) } } }; // --- OYUNU BAŞLAT --- function startGame() { // Oyun değişkenlerini sıfırla isInMainMenu = false; // Oyun başlarken menüden çık score = 0; level = 1; // Apply permanent max health upgrade from storage var permHealthUp = typeof storage.permMaxHealthUp === "number" ? storage.permMaxHealthUp : 0; playerMaxHealth = 10 + permHealthUp; playerHealth = playerMaxHealth; enemies = []; playerBullets = []; enemyBullets = []; powerUps = []; coins = []; powerActive = false; powerTimer = 0; comboCount = 0; comboTimer = 0; maxCombo = 0; isGameOver = false; gameTick = 0; spawnTimer = 0; dragNode = null; lastPlayerPos = { x: 0, y: 0 }; // Apply permanent max attack upgrade from storage var permAttackUp = typeof storage.permMaxAttackUp === "number" ? storage.permMaxAttackUp : 0; if (typeof player !== "undefined") { player._permAttackUp = permAttackUp; } // Ultra power effect text clear if (typeof setUltraPowerEffectText === "function") setUltraPowerEffectText(''); if (typeof currentUltraPowerEffect !== "undefined") currentUltraPowerEffect = ""; // GUI güncelle updateScoreAndLevel(); updateStatsPanel(); if (typeof coinTxt !== "undefined") coinTxt.setText('₵ ' + (typeof storage.coins === "number" ? storage.coins : 0)); if (typeof player !== "undefined") { if (typeof player.maxHealth !== "undefined") player.maxHealth = playerMaxHealth; if (typeof player.health !== "undefined") player.health = playerHealth; } // Oyuncu konumunu sıfırla if (typeof player !== "undefined") { player.x = 2048 / 2; player.y = 2732 / 2; } } // Play background music (loops by default) LK.playMusic('musicId'); // PowerUp oluşturucu function spawnPowerUp() { var p = new PowerUp(); // Güvenli alan içinde rastgele konum p.x = 200 + Math.random() * 1648; p.y = 200 + Math.random() * 2332; powerUps.push(p); game.addChild(p); } // Coin oluşturucu function spawnCoin(x, y) { var c = new Coin(); // Eğer x, y verilmişse oraya koy, yoksa rastgele if (typeof x === "number" && typeof y === "number") { c.x = x; c.y = y; } else { c.x = 200 + Math.random() * 1648; c.y = 200 + Math.random() * 2332; } coins.push(c); game.addChild(c); } // Score and level display var scoreTxt = new Text2('Score: 0', { size: 90, fill: "#fff" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); var levelTxt = new Text2('Level: 1', { size: 60, fill: "#fff" }); levelTxt.anchor.set(0.5, 0); LK.gui.top.addChild(levelTxt); levelTxt.y = 100; // Eğlenceli: Arena event popup var eventPopupTxt = new Text2('', { size: 70, fill: 0xFFFA00, font: "Impact" }); eventPopupTxt.anchor.set(0.5, 0.5); eventPopupTxt.visible = false; LK.gui.center.addChild(eventPopupTxt); // Arena event popup function (already in English, nothing to change) function showArenaEventPopup(msg) { eventPopupTxt.setText(msg); eventPopupTxt.visible = true; eventPopupTxt.alpha = 1; tween(eventPopupTxt, { alpha: 0 }, { duration: 1200, onFinish: function onFinish() { eventPopupTxt.visible = false; } }); } // Oyuncu oluştur player = new Player(); game.addChild(player); player.x = 2048 / 2; player.y = 2732 / 2; // Apply permanent max attack upgrade from storage on initial load var permAttackUp = typeof storage.permMaxAttackUp === "number" ? storage.permMaxAttackUp : 0; player._permAttackUp = permAttackUp; // Düşman oluşturucu function spawnEnemy() { var t = Math.random(); var e; if (t < 0.4) { e = new Enemy(); } else if (t < 0.7) { e = new Enemy2(); } else { e = new Enemy3(); } // --- FUNNY SPEECH BUBBLE ON SPAWN (with emojis) --- var funnySpawnLines = ["👽 Boo! Did I scare you?", "😂 I'm too cute to shoot!", "🍕 Pizza time! Wait, no pizza?", "🦄 I'm a unicorn in disguise!", "💩 Oops, wrong galaxy!", "🤡 Who invited the clown?", "🕺 Dance battle, anyone?", "🐸 Ribbit! Oh wait, I'm not a frog.", "🚀 To the moon! ...or not.", "😜 Catch me if you can!", "🥸 This is my serious face.", "🧀 Say cheese!", "🦖 Rawr! I'm a tiny dino.", "👾 Insert coin to continue!", "🦆 Quack! Wrong sound?", "🍔 I want a burger!", "🧠 Brain freeze!", "🦷 I floss daily.", "🦀 Crab rave time!", "🦉 Hoot hoot! Night shift."]; if (typeof e._showSpeech === "function") { var spawnLine = funnySpawnLines[Math.floor(Math.random() * funnySpawnLines.length)]; e._showSpeech(spawnLine); } // Enemies get stronger: health increases with level and score if (typeof e.maxHealth !== "undefined") { // Her 3 level'da +1 can, her 20 skor'da +1 can var extraHealth = Math.floor(level / 3) + Math.floor(score / 20); e.maxHealth += extraHealth; e.health = e.maxHealth; } // Randomly spawn from edge var edge = Math.floor(Math.random() * 4); if (edge === 0) { // top e.x = 200 + Math.random() * 1648; e.y = -100; } else if (edge === 1) { // right e.x = 2148; e.y = 200 + Math.random() * 2332; } else if (edge === 2) { // bottom e.x = 200 + Math.random() * 1648; e.y = 2832; } else { // left e.x = -100; e.y = 200 + Math.random() * 2332; } enemies.push(e); game.addChild(e); } // Düşman mermisi oluşturucu function spawnEnemyBullet(sx, sy, tx, ty) { var b = new EnemyBullet(); b.x = sx; b.y = sy; var dx = tx - sx; var dy = ty - sy; var dist = Math.sqrt(dx * dx + dy * dy); var speed = 9 + level * 1; // Düşman mermisi hızı azaltıldı b.vx = dx / dist * speed; b.vy = dy / dist * speed; enemyBullets.push(b); game.addChild(b); } // Oyuncu mermisi oluşturucu function spawnPlayerBullet(sx, sy, tx, ty) { var b = new PlayerBullet(); b.x = sx; b.y = sy; var dx = tx - sx; var dy = ty - sy; var dist = Math.sqrt(dx * dx + dy * dy); var speed = 32; b.vx = dx / dist * speed; b.vy = dy / dist * speed; playerBullets.push(b); game.addChild(b); LK.getSound('shoot').play(); } // Skor ve seviye güncelle function updateScoreAndLevel() { if (typeof scoreTxt !== "undefined" && scoreTxt && typeof scoreTxt.setText === "function") { if (scoreTxt._lastScore !== score) { scoreTxt.setText('Score: ' + score); scoreTxt._lastScore = score; } } if (typeof levelTxt !== "undefined" && levelTxt && typeof levelTxt.setText === "function") { if (levelTxt._lastLevel !== level) { levelTxt.setText('Level: ' + level); levelTxt._lastLevel = level; } } if (typeof healthTxt !== "undefined" && healthTxt && typeof healthTxt.setText === "function") { if (healthTxt._lastHealth !== playerHealth) { healthTxt.setText('Health: ' + playerHealth); healthTxt._lastHealth = playerHealth; } } updateComboText(); } // Kombo GUI güncelle function updateComboText() { if (comboCount > 1) { if (comboTxt._lastCombo !== comboCount) { comboTxt.setText("COMBO x" + comboCount + "!"); comboTxt.visible = true; comboTxt.alpha = 1; comboTxt._lastCombo = comboCount; } } else { if (comboTxt.visible) { comboTxt.visible = false; comboTxt._lastCombo = 0; } } } // Oyun zorluğunu artır function increaseDifficulty() { level++; updateScoreAndLevel(); } // Oyun bitti function gameOver() { if (isGameOver) return; isGameOver = true; // --- STATISTICS: Update high score and max combo at game over --- if (score > storage.highScore) { storage.highScore = score; } if (maxCombo > storage.maxCombo) { storage.maxCombo = maxCombo; } updateStatsPanel(); LK.effects.flashScreen(0xff0000, 1000); LK.getSound('hit').play(); LK.showGameOver(); } // Oyun kazandı function youWin() { showArenaEventPopup("YOU WIN! 🎉"); LK.effects.flashScreen(0x00ffcc, 1000); LK.showYouWin(); } // Sürükleme ve ateş etme function handleMove(x, y, obj) { if (dragNode) { // Apply movement delta var dx = x - lastPlayerPos.x; var dy = y - lastPlayerPos.y; dragNode.x += dx; dragNode.y += dy; // User-friendly: Prevent player from going out of bounds var minX = dragNode.radius + 20; var maxX = 2048 - dragNode.radius - 20; var minY = dragNode.radius + 20; var maxY = 2732 - dragNode.radius - 20; if (dragNode.x < minX) dragNode.x = minX; if (dragNode.x > maxX) dragNode.x = maxX; if (dragNode.y < minY) dragNode.y = minY; if (dragNode.y > maxY) dragNode.y = maxY; lastPlayerPos.x = x; lastPlayerPos.y = y; } } // Out of bounds check function isOutOfBounds(obj) { return obj.x < -200 || obj.x > 2248 || obj.y < -200 || obj.y > 2932; } // Oyun ana döngüsü game.update = function () { if (isGameOver) return; gameTick++; // Fun: Random arena events (e.g. meteor shower, bonus rain, enemy freeze) // Every 15 seconds, a random event may trigger if (gameTick % 900 === 0 && gameTick > 0) { var eventType = Math.floor(Math.random() * 3); if (eventType === 0) { // Meteor shower: 10 fast bullets fall from the top for (var m = 0; m < 10; m++) { var b = new EnemyBullet(); b.x = 200 + Math.random() * 1648; b.y = -80 - m * 60; b.vx = 0; b.vy = 32 + Math.random() * 8; enemyBullets.push(b); game.addChild(b); } // Short effect LK.effects.flashScreen(0xffa500, 400); showArenaEventPopup("Meteor Shower!"); } else if (eventType === 1) { // Bonus rain: 5 powerUps drop at once for (var p = 0; p < 5; p++) { var pu = new PowerUp(); pu.x = 200 + Math.random() * 1648; pu.y = 200 + Math.random() * 2332; powerUps.push(pu); game.addChild(pu); } LK.effects.flashScreen(0x00ffcc, 400); showArenaEventPopup("Bonus Rain!"); } else if (eventType === 2) { // Enemies freeze for 3 seconds for (var i = 0; i < enemies.length; i++) { enemies[i]._frozen = 180; // 3 seconds } LK.effects.flashScreen(0x66ccff, 400); showArenaEventPopup("Enemies Frozen!"); } } // Düşmanları dondurma efekti uygula for (var i = 0; i < enemies.length; i++) { if (enemies[i]._frozen && enemies[i]._frozen > 0) { enemies[i]._frozen--; continue; // update çağrılmasın, düşman hareket etmesin } } // Oyuncu update player.update(); // Oyuncu canını playerHealth ile senkronize et if (typeof player.health !== "undefined" && typeof playerHealth !== "undefined" && player.health !== playerHealth) { player.health = playerHealth; } if (typeof player.maxHealth !== "undefined" && typeof playerMaxHealth !== "undefined" && player.maxHealth !== playerMaxHealth) { player.maxHealth = playerMaxHealth; } // --- Attack Speed Bonus: Stacks with powerups --- if (typeof player._attackSpeedBonus === "undefined") player._attackSpeedBonus = 0; // Otomatik ateş etme (her 10 frame'de bir, rapid fire veya attack speed bonus varsa daha hızlı) var baseShootInterval = 10; var rapidFireInterval = powerActive ? 4 : baseShootInterval; var attackSpeedInterval = Math.max(2, rapidFireInterval - player._attackSpeedBonus * 2); var shootInterval = attackSpeedInterval; if (!isGameOver && gameTick % shootInterval === 0 && enemies.length > 0) { // En yakın düşmanı bul var minDist = Infinity; var targetEnemy = null; for (var i = 0; i < enemies.length; i++) { var e = enemies[i]; var dx = e.x - player.x; var dy = e.y - player.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < minDist) { minDist = dist; targetEnemy = e; } } if (targetEnemy) { // --- Otomatik nişan geliştirme: Düşmanın hareketini tahmin et --- // Düşmanın bir sonraki pozisyonunu tahmin etmek için basit linear prediction var bulletSpeed = 32; var ex = targetEnemy.x; var ey = targetEnemy.y; var evx = 0, evy = 0; // Tahmini hız: son pozisyonları varsa kullan if (typeof targetEnemy._lastX === "number" && typeof targetEnemy._lastY === "number") { evx = targetEnemy.x - targetEnemy._lastX; evy = targetEnemy.y - targetEnemy._lastY; } // Hedefe olan mesafe var dx = ex - player.x; var dy = ey - player.y; var dist = Math.sqrt(dx * dx + dy * dy); // Zaman tahmini (kaç frame sonra mermi ulaşır) var t = dist / bulletSpeed; // Tahmini hedef pozisyonu var predictedX = ex + evx * t; var predictedY = ey + evy * t; // Triple shot powerup varsa üçlü mermi ateşle if (player._tripleShot && player._tripleShot > 0) { for (var s = -1; s <= 1; s++) { var angle = Math.atan2(predictedY - player.y, predictedX - player.x) + s * 0.18; var tx = player.x + Math.cos(angle) * 1000; var ty = player.y + Math.sin(angle) * 1000; spawnPlayerBullet(player.x, player.y, tx, ty); } } else { spawnPlayerBullet(player.x, player.y, predictedX, predictedY); } } } // Düşman update for (var i = enemies.length - 1; i >= 0; i--) { var e = enemies[i]; // Skip update if enemy is destroyed or out of bounds if (!e || typeof e.destroyed !== "undefined" && e.destroyed) { if (e && e._healthBar) { e._healthBar.destroy(); } enemies.splice(i, 1); continue; } if (isOutOfBounds(e)) { if (e._healthBar) { e._healthBar.destroy(); } e.destroy(); enemies.splice(i, 1); continue; } // --- Otomatik nişan için: Son pozisyonu kaydet --- e._lastX = typeof e.x === "number" ? e.x : 0; e._lastY = typeof e.y === "number" ? e.y : 0; if (typeof e.update === "function") e.update(); // Can barı çizimi (her düşmanın üstünde) - optimize: sadece health değiştiyse güncelle if (!e._healthBar) { e._healthBar = new Text2('', { size: 64, fill: 0xFF4444, font: "Impact" }); e._healthBar.anchor.set(0.5, 1); game.addChild(e._healthBar); } if (typeof e.health !== "undefined" && typeof e.maxHealth !== "undefined") { if (e._healthBar._lastHealth !== e.health || e._healthBar._lastMaxHealth !== e.maxHealth) { e._healthBar.setText("♥ " + e.health + "/" + e.maxHealth); e._healthBar._lastHealth = e.health; e._healthBar._lastMaxHealth = e.maxHealth; } e._healthBar.x = e.x; e._healthBar.y = e.y - e.radius - 18; e._healthBar.visible = true; } else { e._healthBar.visible = false; } // Çarpışma: oyuncu & düşman if (player.intersects(e)) { if (player._shield && player._shield > 0) { player._shield--; LK.effects.flashObject(player, 0x00ffff, 400); if (player._shield === 0) { showArenaEventPopup("Shield Broken!"); } else { showArenaEventPopup("Shield: " + player._shield + " hits left!"); } } else { playerHealth--; if (typeof player.health !== "undefined") player.health = playerHealth; updateScoreAndLevel(); LK.effects.flashObject(player, 0xff4444, 400); LK.getSound('hit').play(); if (playerHealth <= 0) { gameOver(); return; } } // Düşmanı yok et, can azalınca if (typeof e.takeDamage === "function") { e.takeDamage(e.health); // Tüm canı gitmeli if (e._shouldRemove) { if (e._healthBar) { e._healthBar.destroy(); } // COIN: Düşman öldüğünde coin spawn et var baseCoinChance = 0.7; var extraChance = Math.min(comboCount * 0.10, 0.5); if (Math.random() < baseCoinChance + extraChance) { spawnCoin(e.x, e.y); } // --- PowerUp drop şansı: %20 + kombo başına %4, max %40 --- var basePowerUpChance = 0.20; var extraPowerUpChance = Math.min(comboCount * 0.04, 0.20); if (Math.random() < basePowerUpChance + extraPowerUpChance) { spawnPowerUp(); if (powerUps.length > 0) { var pu = powerUps[powerUps.length - 1]; pu.x = e.x; pu.y = e.y; } } enemies.splice(i, 1); // KOMBO: Düşman öldürdüyse kombo başlat if (typeof e._killedByPlayer === "undefined" || e._killedByPlayer) { comboCount++; comboTimer = maxComboTime; if (comboCount > maxCombo) maxCombo = comboCount; if (comboCount > storage.maxCombo) { storage.maxCombo = comboCount; updateStatsPanel(); } storage.totalEnemiesKilled = (typeof storage.totalEnemiesKilled === "number" ? storage.totalEnemiesKilled : 0) + 1; updateStatsPanel(); updateComboText(); } continue; } } else { e.destroy(); if (e._healthBar) { e._healthBar.destroy(); } // COIN: Düşman öldüğünde coin spawn et var baseCoinChance = 0.7; var extraChance = Math.min(comboCount * 0.10, 0.5); if (Math.random() < baseCoinChance + extraChance) { spawnCoin(e.x, e.y); } // --- PowerUp drop şansı: %20 + kombo başına %4, max %40 --- var basePowerUpChance = 0.20; var extraPowerUpChance = Math.min(comboCount * 0.04, 0.20); if (Math.random() < basePowerUpChance + extraPowerUpChance) { spawnPowerUp(); if (powerUps.length > 0) { var pu = powerUps[powerUps.length - 1]; pu.x = e.x; pu.y = e.y; } } enemies.splice(i, 1); comboCount++; comboTimer = maxComboTime; if (comboCount > maxCombo) maxCombo = comboCount; if (comboCount > storage.maxCombo) { storage.maxCombo = comboCount; updateStatsPanel(); } storage.totalEnemiesKilled = (typeof storage.totalEnemiesKilled === "number" ? storage.totalEnemiesKilled : 0) + 1; updateStatsPanel(); updateComboText(); continue; } } } // Oyuncu mermisi update for (var i = playerBullets.length - 1; i >= 0; i--) { var b = playerBullets[i]; // Skip update if bullet is destroyed or out of bounds if (!b || typeof b.destroyed !== "undefined" && b.destroyed) { playerBullets.splice(i, 1); continue; } if (isOutOfBounds(b)) { b.destroy(); playerBullets.splice(i, 1); continue; } if (typeof b.update === "function") b.update(); var hit = false; // Düşmanlara çarpma for (var j = enemies.length - 1; j >= 0; j--) { var e = enemies[j]; if (b.intersects(e)) { LK.getSound('hit').play(); if (typeof e.takeDamage === "function") { e._killedByPlayer = true; var permAttackUp = typeof player._permAttackUp === "number" ? player._permAttackUp : 0; var bulletDamage = 2 + permAttackUp; e.takeDamage(bulletDamage); if (e._shouldRemove) { enemies.splice(j, 1); } } hit = true; break; } } // WALL BOUNCE: Eğer aktifse, mermi kenara çarptıysa sekmeli var wallBounceActive = player._wallBounce && player._wallBounce > 0; if (!hit && wallBounceActive) { var bounced = false; if (b.x < b.radius + 10 && b.vx < 0) { b.x = b.radius + 10; b.vx *= -1; bounced = true; } if (b.x > 2048 - b.radius - 10 && b.vx > 0) { b.x = 2048 - b.radius - 10; b.vx *= -1; bounced = true; } if (b.y < b.radius + 10 && b.vy < 0) { b.y = b.radius + 10; b.vy *= -1; bounced = true; } if (b.y > 2732 - b.radius - 10 && b.vy > 0) { b.y = 2732 - b.radius - 10; b.vy *= -1; bounced = true; } // Eğer sekmediyse ve hala out of bounds ise yok et if (!bounced && isOutOfBounds(b)) { b.destroy(); playerBullets.splice(i, 1); continue; } if (hit) { b.destroy(); playerBullets.splice(i, 1); continue; } } else { if (hit || isOutOfBounds(b)) { b.destroy(); playerBullets.splice(i, 1); continue; } } } // Düşman mermisi update for (var i = enemyBullets.length - 1; i >= 0; i--) { var b = enemyBullets[i]; // Skip update if bullet is destroyed or out of bounds if (!b || typeof b.destroyed !== "undefined" && b.destroyed) { enemyBullets.splice(i, 1); continue; } if (isOutOfBounds(b)) { b.destroy(); enemyBullets.splice(i, 1); continue; } if (typeof b.update === "function") b.update(); // Oyuncuya çarpma var reflectActive = player._reflect && player._reflect > 0; if (b.intersects(player)) { if (reflectActive) { // Reflect: Düşman mermisi oyuncuya çarptığında geri sektir var newB = new PlayerBullet(); newB.x = b.x; newB.y = b.y; var mag = Math.sqrt(b.vx * b.vx + b.vy * b.vy); if (mag === 0) mag = 1; newB.vx = -b.vx / mag * 32; newB.vy = -b.vy / mag * 32; playerBullets.push(newB); game.addChild(newB); LK.effects.flashObject(player, 0x00ffcc, 200); showArenaEventPopup("Reflected!"); b.destroy(); enemyBullets.splice(i, 1); continue; } else if (player._shield && player._shield > 0) { player._shield--; LK.effects.flashObject(player, 0x00ffff, 400); if (player._shield === 0) { showArenaEventPopup("Shield Broken!"); } else { showArenaEventPopup("Shield: " + player._shield + " hits left!"); } } else { playerHealth--; if (typeof player.health !== "undefined") player.health = playerHealth; updateScoreAndLevel(); LK.effects.flashObject(player, 0xff4444, 400); LK.getSound('hit').play(); if (playerHealth <= 0) { b.destroy(); enemyBullets.splice(i, 1); gameOver(); return; } } b.destroy(); enemyBullets.splice(i, 1); continue; } if (isOutOfBounds(b)) { b.destroy(); enemyBullets.splice(i, 1); continue; } } // KOMBO zamanlayıcı: Kombo süresi dolarsa sıfırla if (comboCount > 0) { comboTimer--; if (comboTimer <= 0) { // Show fun popup for max combo if it was a big combo if (comboCount >= 5) { showArenaEventPopup("AWESOME COMBO x" + comboCount + "!"); LK.effects.flashScreen(0xffe100, 400); } else if (comboCount >= 3) { showArenaEventPopup("Combo x" + comboCount + "!"); } comboCount = 0; updateComboText(); } } // Fun popup: Level up if (typeof lastLevel === "undefined") { lastLevel = level; } if (level > lastLevel) { showArenaEventPopup("LEVEL UP! Level " + level); LK.effects.flashScreen(0x00ff00, 400); lastLevel = level; } // Fun popup: Coin milestone if (typeof lastCoinMilestone === "undefined") { lastCoinMilestone = 0; } if (coinCount >= lastCoinMilestone + 10) { showArenaEventPopup("Coin Collector! ₵" + coinCount); LK.effects.flashScreen(0xffd700, 300); lastCoinMilestone = coinCount - coinCount % 10; } // PowerUp update ve çarpışma // --- PowerUp birleşme ve combo mekaniği --- for (var i = powerUps.length - 1; i >= 0; i--) { var p = powerUps[i]; // Skip update if powerup is destroyed or out of bounds if (!p || typeof p.destroyed !== "undefined" && p.destroyed) { powerUps.splice(i, 1); continue; } if (isOutOfBounds(p)) { p.destroy(); powerUps.splice(i, 1); continue; } p.update(); // Magnet veya Super Magnet aktifse, powerupları çek var magnetActive = player._magnet && player._magnet > 0; var superMagnetActive = player._superMagnetShot && player._superMagnetShot > 0; if (magnetActive || superMagnetActive) { var distToPlayer = Math.sqrt((p.x - player.x) * (p.x - player.x) + (p.y - player.y) * (p.y - player.y)); var pullRadius = superMagnetActive ? 800 : 400; if (distToPlayer < pullRadius) { // PowerUp oyuncuya doğru çekilsin var pullSpeed = superMagnetActive ? 60 : 30; var dx = player.x - p.x; var dy = player.y - p.y; var d = Math.sqrt(dx * dx + dy * dy); if (d > 1) { p.x += dx / d * pullSpeed; p.y += dy / d * pullSpeed; } } } // PowerUp-PowerUp çarpışması: Birleşme for (var j = i - 1; j >= 0; j--) { var p2 = powerUps[j]; if (p !== p2 && p.intersects(p2)) { // İki powerup birleşirse: PowerUpCombo oluştur var combo = new PowerUpCombo(); combo.x = (p.x + p2.x) / 2; combo.y = (p.y + p2.y) / 2; combo.effects = []; // Farklı efektleri ekle (tekrar yok) if (p.effect && combo.effects.indexOf(p.effect) === -1) combo.effects.push(p.effect); if (p2.effect && combo.effects.indexOf(p2.effect) === -1) combo.effects.push(p2.effect); // Eğer p veya p2 zaten combo ise, efektlerini ekle if (p.effects && Array.isArray(p.effects)) { for (var ce = 0; ce < p.effects.length; ce++) { if (combo.effects.indexOf(p.effects[ce]) === -1) combo.effects.push(p.effects[ce]); } } if (p2.effects && Array.isArray(p2.effects)) { for (var ce2 = 0; ce2 < p2.effects.length; ce2++) { if (combo.effects.indexOf(p2.effects[ce2]) === -1) combo.effects.push(p2.effects[ce2]); } } // Sınır: En fazla 3 efektli combo if (combo.effects.length > 3) combo.effects = combo.effects.slice(0, 3); powerUps.splice(i, 1); powerUps.splice(j, 1); p.destroy(); p2.destroy(); powerUps.push(combo); game.addChild(combo); // Combo birleşme popup showArenaEventPopup("PowerUp Combo!"); break; } } // Oyuncu ile çarpışma if (player.intersects(p)) { // PowerUp veya PowerUpCombo alındı var effectsToApply = []; if (p.effect) { effectsToApply = [p.effect]; } else if (p.effects && Array.isArray(p.effects)) { effectsToApply = p.effects.slice(); } var popupMsg = []; var comboRapid = false, comboMagnet = false; // --- PowerUp efektlerini uygula --- for (var ef = 0; ef < effectsToApply.length; ef++) { var effect = effectsToApply[ef]; if (effect === "rapid") { // --- Attack Speed Bonus: Stackable --- if (typeof player._attackSpeedBonus !== "number") player._attackSpeedBonus = 0; player._attackSpeedBonus += 1; powerActive = true; powerTimer = 600; popupMsg.push("RAPID FIRE! (10s)"); comboRapid = true; } else if (effect === "triple") { player._tripleShot = 600; popupMsg.push("TRIPLE SHOT! (10s)"); } else if (effect === "shield") { player._shield = 5; popupMsg.push("Shield (5 hits)!"); } else if (effect === "heal") { playerHealth = playerMaxHealth; if (typeof player.health !== "undefined") player.health = playerHealth; updateScoreAndLevel(); popupMsg.push("Full Health!"); } else if (effect === "wallBounce") { player._wallBounce = 600; popupMsg.push("WALL BOUNCE! (10s)"); } else if (effect === "reflect") { player._reflect = 600; popupMsg.push("REFLECT ENEMY BULLETS! (10s)"); } else if (effect === "slow") { // Zaman yavaşlatma: tüm düşmanlar yavaşlar for (var si = 0; si < enemies.length; si++) { enemies[si]._frozen = 180; // 3 saniye yavaşlat } popupMsg.push("TIME SLOW! (3s)"); LK.effects.flashScreen(0x66ccff, 400); } else if (effect === "magnet") { // Magnet: yakındaki coin ve powerupları çek comboMagnet = true; popupMsg.push("MAGNET! (5s)"); player._magnet = 300; // 5 saniye } else if (effect === "randomizer") { // Randomizer: tüm düşmanların tipi değişir for (var ri = 0; ri < enemies.length; ri++) { var e = enemies[ri]; var t = Math.random(); var newE; if (t < 0.4) newE = new Enemy();else if (t < 0.7) newE = new Enemy2();else newE = new Enemy3(); newE.x = e.x; newE.y = e.y; newE.maxHealth = e.maxHealth; newE.health = e.health; newE._frozen = e._frozen; newE._healthBar = e._healthBar; newE._visHealthBar = e._visHealthBar; newE._visHealthBarBg = e._visHealthBarBg; newE._visHealthBarFg = e._visHealthBarFg; enemies[ri].destroy(); enemies[ri] = newE; game.addChild(newE); } popupMsg.push("RANDOMIZER! (All enemies changed)"); LK.effects.flashScreen(0x00ffcc, 400); } else if (effect === "superHeal") { // Süper can: hem canı doldur hem max canı 2 artır playerMaxHealth += 2; playerHealth = playerMaxHealth; if (typeof player.maxHealth !== "undefined") player.maxHealth = playerMaxHealth; if (typeof player.health !== "undefined") player.health = playerHealth; updateScoreAndLevel(); popupMsg.push("SUPER HEAL! (+2 Max Health)"); } else if (effect === "freezeBullets") { // Freeze all enemy bullets for 3 seconds for (var bi = 0; bi < enemyBullets.length; bi++) { enemyBullets[bi]._frozen = 180; } popupMsg.push("FREEZE ENEMY BULLETS! (3s)"); LK.effects.flashScreen(0x00eaff, 400); } else if (effect === "coinRain") { // Spawn 10 coins at random locations for (var ci = 0; ci < 10; ci++) { spawnCoin(); } popupMsg.push("COIN RAIN!"); LK.effects.flashScreen(0xffd700, 400); } else if (effect === "enemyClear") { // Destroy all enemies on screen for (var ei = enemies.length - 1; ei >= 0; ei--) { if (enemies[ei]._healthBar) enemies[ei]._healthBar.destroy(); if (enemies[ei]._visHealthBar) enemies[ei]._visHealthBar.destroy(); enemies[ei].destroy(); enemies.splice(ei, 1); } popupMsg.push("ENEMY CLEAR!"); LK.effects.flashScreen(0xff4444, 600); } else if (effect === "scoreBoost") { // 2x skor için 15 saniye player._scoreBoost = 900; popupMsg.push("SCORE BOOST! (15s)"); } } // --- PowerUp Kombinasyonları: Rapid + Magnet = Süper Çekim Ateşi --- if (comboRapid && comboMagnet) { player._superMagnetShot = 600; // 10 saniye süper çekim ateşi popupMsg.push("SUPER MAGNET SHOT! (10s)"); LK.effects.flashScreen(0xff00ff, 600); } // --- PowerUp efektleri bitti --- LK.effects.flashObject(player, 0x00ffcc, 400); showArenaEventPopup("PowerUp: " + popupMsg.join(" + ")); p.destroy(); powerUps.splice(i, 1); } else if (isOutOfBounds(p)) { p.destroy(); powerUps.splice(i, 1); } } // Coin update ve toplama for (var i = coins.length - 1; i >= 0; i--) { var c = coins[i]; // Skip update if coin is destroyed or out of bounds if (!c || typeof c.destroyed !== "undefined" && c.destroyed) { coins.splice(i, 1); continue; } if (isOutOfBounds(c)) { c.destroy(); coins.splice(i, 1); continue; } c.update(); // Magnet veya Super Magnet aktifse, coinleri çek var magnetActive = player._magnet && player._magnet > 0; var superMagnetActive = player._superMagnetShot && player._superMagnetShot > 0; if (magnetActive || superMagnetActive) { var distToPlayer = Math.sqrt((c.x - player.x) * (c.x - player.x) + (c.y - player.y) * (c.y - player.y)); var pullRadius = superMagnetActive ? 800 : 400; if (distToPlayer < pullRadius) { // Coin oyuncuya doğru çekilsin var pullSpeed = superMagnetActive ? 60 : 30; var dx = player.x - c.x; var dy = player.y - c.y; var d = Math.sqrt(dx * dx + dy * dy); if (d > 1) { c.x += dx / d * pullSpeed; c.y += dy / d * pullSpeed; } } } if (player.intersects(c)) { coinCount++; coinTxt.setText('₵ ' + coinCount); // COIN: Save permanently storage.coins = coinCount; LK.effects.flashObject(player, 0xFFD700, 200); // Fun popup: First coin if (coinCount === 1) { showArenaEventPopup("First Coin Collected!"); LK.effects.flashScreen(0xffd700, 300); } c.destroy(); coins.splice(i, 1); } else if (isOutOfBounds(c)) { c.destroy(); coins.splice(i, 1); } } // PowerUp etkisi süresi if (powerActive) { powerTimer--; if (powerTimer <= 0) { powerActive = false; // --- Attack Speed Bonus: Remove one stack when rapid fire ends --- if (typeof player._attackSpeedBonus === "number" && player._attackSpeedBonus > 0) { player._attackSpeedBonus -= 1; if (player._attackSpeedBonus < 0) player._attackSpeedBonus = 0; } } } // Triple shot süresi azalt if (player._tripleShot && player._tripleShot > 0) { player._tripleShot--; if (player._tripleShot <= 0) player._tripleShot = 0; } // Wall bounce süresi azalt if (player._wallBounce && player._wallBounce > 0) { player._wallBounce--; if (player._wallBounce <= 0) player._wallBounce = 0; } // Reflect süresi azalt if (player._reflect && player._reflect > 0) { player._reflect--; if (player._reflect <= 0) player._reflect = 0; } // Magnet süresi azalt if (player._magnet && player._magnet > 0) { player._magnet--; if (player._magnet <= 0) player._magnet = 0; } // Super Magnet Shot süresi azalt if (player._superMagnetShot && player._superMagnetShot > 0) { player._superMagnetShot--; if (player._superMagnetShot <= 0) player._superMagnetShot = 0; } // Score Boost süresi azalt if (player._scoreBoost && player._scoreBoost > 0) { player._scoreBoost--; if (player._scoreBoost <= 0) player._scoreBoost = 0; } // Freeze enemy bullets süresi azalt for (var bi = 0; bi < enemyBullets.length; bi++) { if (enemyBullets[bi]._frozen && enemyBullets[bi]._frozen > 0) { enemyBullets[bi]._frozen--; // Dondurulmuşsa hareket etmesin enemyBullets[bi].vx = 0; enemyBullets[bi].vy = 0; } } // PowerUp spawn (her 6 saniyede bir) if (gameTick % 360 === 0) { spawnPowerUp(); } // COIN: Sık sık rastgele coin spawn et (her 60 frame'de bir, %60 olasılıkla) if (gameTick % 60 === 0) { if (Math.random() < 0.6) { spawnCoin(); } } // Düşman spawn // --- Düşmanlar çok çıksın: skor arttıkça daha sık spawn --- // spawnInterval: skor arttıkça daha hızlı (min 8 frame) var spawnInterval = Math.max(60 - level * 2 - Math.floor(score / 10), 8); // Aynı anda birden fazla düşman spawn: skor arttıkça daha fazla var enemySpawnCount = 1 + Math.floor(score / 30); if (gameTick % spawnInterval === 0) { for (var s = 0; s < enemySpawnCount; s++) { spawnEnemy(); } } }; // Sürükleme başlat game.down = function (x, y, obj) { // If player is tapped, start dragging var px = player.x, py = player.y; var dx = x - px, dy = y - py; var dist = Math.sqrt(dx * dx + dy * dy); // User-friendly: If tapped on player, start dragging, otherwise do nothing if (dist < player.radius + 80) { // wider area, easier drag dragNode = player; lastPlayerPos.x = x; lastPlayerPos.y = y; // When drag starts, don't fire, prevent accidental fire // Drag threshold: set a flag to check if drag distance exceeds a threshold before firing dragNode._dragStarted = false; dragNode._dragStartX = x; dragNode._dragStartY = y; dragNode._dragStartTime = Date.now(); } else { // (Removed: tap-to-shoot code is now gone) } }; // Sürükleme bırak game.up = function (x, y, obj) { if (dragNode && typeof dragNode._dragStarted !== "undefined") { // If drag didn't start and released quickly, fire (tap-to-shoot) var dragDx = x - dragNode._dragStartX; var dragDy = y - dragNode._dragStartY; var dragDist = Math.sqrt(dragDx * dragDx + dragDy * dragDy); var dragTime = Date.now() - (dragNode._dragStartTime || 0); if (!dragNode._dragStarted && dragDist < 24 && dragTime < 200) { spawnPlayerBullet(player.x, player.y, x, y); LK.getSound('shoot').play(); } dragNode._dragStarted = false; dragNode._dragStartX = 0; dragNode._dragStartY = 0; dragNode._dragStartTime = 0; } dragNode = null; // User-friendly: Update last position when drag is released lastPlayerPos.x = 0; lastPlayerPos.y = 0; }; // Sürükleme hareketi: Oyuncu mouse ile birlikte hareket etsin game.move = function (x, y, obj) { // Oyuncu mouse ile birlikte hareket etsin if (player) { // Kullanıcı dostu: Oyuncunun ekran dışına çıkmasını engelle var minX = player.radius + 20; var maxX = 2048 - player.radius - 20; var minY = player.radius + 20; var maxY = 2732 - player.radius - 20; player.x = x; player.y = y; if (player.x < minX) player.x = minX; if (player.x > maxX) player.x = maxX; if (player.y < minY) player.y = minY; if (player.y > maxY) player.y = maxY; } }; // At game start, reset score, level, and health score = 0; level = 1; playerHealth = playerMaxHealth; // --- STATISTICS: Persistent High Score, Max Combo, Total Enemies Killed --- storage.highScore = typeof storage.highScore === "number" ? storage.highScore : 0; storage.maxCombo = typeof storage.maxCombo === "number" ? storage.maxCombo : 0; storage.totalEnemiesKilled = typeof storage.totalEnemiesKilled === "number" ? storage.totalEnemiesKilled : 0; // COIN: Load persistent coin count coinCount = typeof storage.coins === "number" ? storage.coins : 0; if (typeof coinTxt !== "undefined" && coinTxt._lastCoinCount !== coinCount) { coinTxt.setText('₵ ' + coinCount); coinTxt._lastCoinCount = coinCount; } if (typeof player !== "undefined") { if (typeof player.maxHealth !== "undefined") player.maxHealth = playerMaxHealth; if (typeof player.health !== "undefined") player.health = playerHealth; } // --- STATISTICS GUI --- // Oyuncuya istatistikleri gösteren panel (sol üstte, büyük ve kolay okunur, menü ikonundan uzak) var statsPanel = new Container(); LK.gui.topLeft.addChild(statsPanel); // Sol üstte, menü ikonundan uzak durmak için 110px sağa ve 10px aşağıya kaydır statsPanel.x = 110; statsPanel.y = 10; // High Score var statsHighScoreTxt = new Text2('High Score: ' + storage.highScore, { size: 48, fill: 0xFFD700, font: "Impact" }); statsHighScoreTxt.anchor.set(0, 0); statsHighScoreTxt.x = 0; statsHighScoreTxt.y = 0; statsPanel.addChild(statsHighScoreTxt); // Max Combo var statsMaxComboTxt = new Text2('Max Combo: ' + storage.maxCombo, { size: 48, fill: 0xFFFA00, font: "Impact" }); statsMaxComboTxt.anchor.set(0, 0); statsMaxComboTxt.x = 0; statsMaxComboTxt.y = 60; statsPanel.addChild(statsMaxComboTxt); // Total Enemies Killed var statsEnemiesKilledTxt = new Text2('Enemies Killed: ' + storage.totalEnemiesKilled, { size: 48, fill: 0xFF4444, font: "Impact" }); statsEnemiesKilledTxt.anchor.set(0, 0); statsEnemiesKilledTxt.x = 0; statsEnemiesKilledTxt.y = 120; statsPanel.addChild(statsEnemiesKilledTxt); // Paneli güncelleyen fonksiyon function updateStatsPanel() { if (typeof statsHighScoreTxt !== "undefined") statsHighScoreTxt.setText('High Score: ' + storage.highScore); if (typeof statsMaxComboTxt !== "undefined") statsMaxComboTxt.setText('Max Combo: ' + storage.maxCombo); if (typeof statsEnemiesKilledTxt !== "undefined") statsEnemiesKilledTxt.setText('Enemies Killed: ' + storage.totalEnemiesKilled); } updateStatsPanel(); // --- NEW: Random PowerUp Shop Button --- // Spend 30 coins to get a random powerup effect var randomPowerBtn = new Text2('Random PowerUp (30₵)', { size: 60, fill: 0x00BFFF, // Bright blue for high visibility font: "Impact" }); randomPowerBtn.anchor.set(0.5, 0); LK.gui.top.addChild(randomPowerBtn); randomPowerBtn.y = 420; randomPowerBtn.interactive = true; randomPowerBtn.buttonMode = true; randomPowerBtn.visible = true; randomPowerBtn.down = function (x, y, obj) { if (coinCount >= 30) { coinCount -= 30; storage.coins = coinCount; if (typeof coinTxt !== "undefined") coinTxt.setText('₵ ' + coinCount); // Pick a random effect var effects = ["rapid", "triple", "heal", "wallBounce", "reflect", "shield", "slow", "magnet", "superHeal", "freezeBullets", "coinRain", "enemyClear", "scoreBoost"]; var effect = effects[Math.floor(Math.random() * effects.length)]; var popupMsg = ""; if (effect === "rapid") { // --- Attack Speed Bonus: Stackable --- if (typeof player._attackSpeedBonus !== "number") player._attackSpeedBonus = 0; player._attackSpeedBonus += 1; powerActive = true; powerTimer = 600; popupMsg = "RAPID FIRE! (10s)"; } else if (effect === "triple") { player._tripleShot = 600; popupMsg = "TRIPLE SHOT! (10s)"; } else if (effect === "heal") { playerHealth = playerMaxHealth; if (typeof player.health !== "undefined") player.health = playerHealth; updateScoreAndLevel(); popupMsg = "Full Health!"; } else if (effect === "wallBounce") { player._wallBounce = 600; popupMsg = "WALL BOUNCE! (10s)"; } else if (effect === "reflect") { player._reflect = 600; popupMsg = "REFLECT ENEMY BULLETS! (10s)"; } else if (effect === "shield") { player._shield = 5; popupMsg = "Shield (5 hits)!"; } else if (effect === "slow") { for (var si = 0; si < enemies.length; si++) { enemies[si]._frozen = 180; } popupMsg = "TIME SLOW! (3s)"; LK.effects.flashScreen(0x66ccff, 400); } else if (effect === "magnet") { player._magnet = 300; popupMsg = "MAGNET! (5s)"; } else if (effect === "superHeal") { playerMaxHealth += 2; playerHealth = playerMaxHealth; if (typeof player.maxHealth !== "undefined") player.maxHealth = playerMaxHealth; if (typeof player.health !== "undefined") player.health = playerHealth; updateScoreAndLevel(); popupMsg = "SUPER HEAL! (+2 Max Health)"; } else if (effect === "freezeBullets") { for (var bi = 0; bi < enemyBullets.length; bi++) { enemyBullets[bi]._frozen = 180; } popupMsg = "FREEZE ENEMY BULLETS! (3s)"; LK.effects.flashScreen(0x00eaff, 400); } else if (effect === "coinRain") { for (var ci = 0; ci < 10; ci++) { spawnCoin(); } popupMsg = "COIN RAIN!"; LK.effects.flashScreen(0xffd700, 400); } else if (effect === "enemyClear") { for (var ei = enemies.length - 1; ei >= 0; ei--) { if (enemies[ei]._healthBar) enemies[ei]._healthBar.destroy(); if (enemies[ei]._visHealthBar) enemies[ei]._visHealthBar.destroy(); enemies[ei].destroy(); enemies.splice(ei, 1); } popupMsg = "ENEMY CLEAR!"; LK.effects.flashScreen(0xff4444, 600); } else if (effect === "scoreBoost") { player._scoreBoost = 900; popupMsg = "SCORE BOOST! (15s)"; } LK.effects.flashObject(player, 0xFFD700, 400); // Coin color flash showArenaEventPopup("PowerUp: " + popupMsg); } else { showArenaEventPopup("Not enough coins!"); } }; // --- NEW: Random Permanent Ultra Power Button (red) --- var ultraPowerBtn = new Text2('Random ULTRA Power (100₵)', { size: 60, fill: 0xFF2222, // Red font: "Impact" }); ultraPowerBtn.anchor.set(0.5, 0); LK.gui.top.addChild(ultraPowerBtn); ultraPowerBtn.y = randomPowerBtn.y + 90; ultraPowerBtn.interactive = true; ultraPowerBtn.buttonMode = true; ultraPowerBtn.visible = true; // --- NEW: Permanent Upgrade Shop (bottom left) --- var permUpgradeBtn = new Text2('+1 Max Health (250₵)', { size: 60, fill: 0x00ff88, font: "Impact" }); permUpgradeBtn.anchor.set(0, 1); // bottom left LK.gui.bottomLeft.addChild(permUpgradeBtn); permUpgradeBtn.y = 0; permUpgradeBtn.x = 0; permUpgradeBtn.interactive = true; permUpgradeBtn.buttonMode = true; permUpgradeBtn.visible = true; // --- NEW: Permanent Max Attack Upgrade Button (bottom right, above health) --- var permAttackUpgradeBtn = new Text2('+1 Max Attack (250₵)', { size: 60, fill: 0xff8800, font: "Impact" }); permAttackUpgradeBtn.anchor.set(1, 1); LK.gui.bottomRight.addChild(permAttackUpgradeBtn); permAttackUpgradeBtn.y = permUpgradeBtn.y - 90; permAttackUpgradeBtn.x = 0; permAttackUpgradeBtn.interactive = true; permAttackUpgradeBtn.buttonMode = true; permAttackUpgradeBtn.visible = true; // Show current permanent upgrades (bottom left, above button) var permUpgradeInfoTxt = new Text2('', { size: 48, fill: 0xffffff, font: "Impact" }); permUpgradeInfoTxt.anchor.set(0, 1); // bottom left LK.gui.bottomLeft.addChild(permUpgradeInfoTxt); permUpgradeInfoTxt.y = permUpgradeBtn.y + 80; permUpgradeInfoTxt.x = 0; // Show current permanent attack upgrades (bottom right, above attack button) var permAttackUpgradeInfoTxt = new Text2('', { size: 48, fill: 0xff8800, font: "Impact" }); permAttackUpgradeInfoTxt.anchor.set(1, 1); LK.gui.bottomRight.addChild(permAttackUpgradeInfoTxt); permAttackUpgradeInfoTxt.y = permAttackUpgradeBtn.y + 80; permAttackUpgradeInfoTxt.x = 0; // Helper to update permanent upgrade info function updatePermUpgradeInfo() { var healthUp = typeof storage.permMaxHealthUp === "number" ? storage.permMaxHealthUp : 0; if (healthUp > 0) { // If maxed (let's say 10 is max), show MAXED and use green color, add background if (healthUp >= 10) { permUpgradeInfoTxt.setText("Max Health +" + healthUp + " (MAXED, permanent)"); permUpgradeInfoTxt.fill = 0x00ff00; permUpgradeInfoTxt.size = 36; permUpgradeInfoTxt.background = { color: 0x222222, alpha: 0.95, padding: 18, radius: 18 }; } else { permUpgradeInfoTxt.setText("Max Health +" + healthUp + " (permanent)"); permUpgradeInfoTxt.fill = 0xffffff; permUpgradeInfoTxt.size = 36; permUpgradeInfoTxt.background = { color: 0x222222, alpha: 0.8, padding: 12, radius: 12 }; } permUpgradeInfoTxt.visible = true; } else { permUpgradeInfoTxt.setText(""); permUpgradeInfoTxt.visible = false; permUpgradeInfoTxt.background = undefined; } var attackUp = typeof storage.permMaxAttackUp === "number" ? storage.permMaxAttackUp : 0; if (attackUp > 0) { // If maxed (let's say 10 is max), show MAXED and use orange color, add background if (attackUp >= 10) { permAttackUpgradeInfoTxt.setText("Max Attack +" + attackUp + " (MAXED, permanent)"); permAttackUpgradeInfoTxt.fill = 0xff8800; permAttackUpgradeInfoTxt.size = 36; permAttackUpgradeInfoTxt.background = { color: 0x222222, alpha: 0.95, padding: 18, radius: 18 }; } else { permAttackUpgradeInfoTxt.setText("Max Attack +" + attackUp + " (permanent)"); permAttackUpgradeInfoTxt.fill = 0xff8800; permAttackUpgradeInfoTxt.size = 36; permAttackUpgradeInfoTxt.background = { color: 0x222222, alpha: 0.8, padding: 12, radius: 12 }; } permAttackUpgradeInfoTxt.visible = true; } else { permAttackUpgradeInfoTxt.setText(""); permAttackUpgradeInfoTxt.visible = false; permAttackUpgradeInfoTxt.background = undefined; } } updatePermUpgradeInfo(); permUpgradeBtn.down = function (x, y, obj) { // Always update coinCount from storage before checking coinCount = typeof storage.coins === "number" ? storage.coins : coinCount; var healthUp = typeof storage.permMaxHealthUp === "number" ? storage.permMaxHealthUp : 0; if (coinCount >= 250) { coinCount -= 250; storage.coins = coinCount; if (typeof coinTxt !== "undefined") coinTxt.setText('₵ ' + coinCount); // Increase permanent max health healthUp++; storage.permMaxHealthUp = healthUp; updatePermUpgradeInfo(); LK.effects.flashScreen(0x00ff88, 400); // Apply immediately to player playerMaxHealth = 10 + healthUp; playerHealth = playerMaxHealth; if (typeof player !== "undefined") { if (typeof player.maxHealth !== "undefined") player.maxHealth = playerMaxHealth; if (typeof player.health !== "undefined") player.health = playerHealth; } updateScoreAndLevel(); } else { showArenaEventPopup("Not enough coins!"); } }; // Permanent Max Attack Upgrade Button logic permAttackUpgradeBtn.down = function (x, y, obj) { coinCount = typeof storage.coins === "number" ? storage.coins : coinCount; var attackUp = typeof storage.permMaxAttackUp === "number" ? storage.permMaxAttackUp : 0; if (coinCount >= 250) { coinCount -= 250; storage.coins = coinCount; if (typeof coinTxt !== "undefined") coinTxt.setText('₵ ' + coinCount); // Increase permanent max attack attackUp++; storage.permMaxAttackUp = attackUp; updatePermUpgradeInfo(); LK.effects.flashScreen(0xff8800, 400); // Apply immediately to player (if you want, e.g. set player._permAttackUp = attackUp) if (typeof player !== "undefined") { player._permAttackUp = attackUp; } } else { showArenaEventPopup("Not enough coins!"); } }; // --- ULTRA POWER EFFECT TEXT (top-right, red, bold) --- var ultraPowerEffectTxt = new Text2('', { size: 60, fill: 0xFF2222, font: "Impact", fontWeight: "bold" }); ultraPowerEffectTxt.anchor.set(1, 0); // right-top LK.gui.topRight.addChild(ultraPowerEffectTxt); ultraPowerEffectTxt.y = 0; ultraPowerEffectTxt.x = 0; // LK.gui.topRight is already at the right edge // Helper to set ultra power effect text var ultraPowerEffectTimeout = null; function setUltraPowerEffectText(txt) { if (typeof ultraPowerEffectTxt !== "undefined" && ultraPowerEffectTxt && typeof ultraPowerEffectTxt.setText === "function") { ultraPowerEffectTxt.setText(txt || ''); ultraPowerEffectTxt.visible = !!txt; // Hide after 2.5 seconds if text is set if (ultraPowerEffectTimeout) { LK.clearTimeout(ultraPowerEffectTimeout); ultraPowerEffectTimeout = null; } if (txt) { ultraPowerEffectTimeout = LK.setTimeout(function () { ultraPowerEffectTxt.setText(''); ultraPowerEffectTxt.visible = false; ultraPowerEffectTimeout = null; }, 5000); } } } // On game start, clear ultra power effect text setUltraPowerEffectText(''); // Track the current ultra power effect var currentUltraPowerEffect = ""; // Update the text when ultra power is bought ultraPowerBtn.down = function (x, y, obj) { // Always update coinCount from storage before checking coinCount = typeof storage.coins === "number" ? storage.coins : coinCount; if (coinCount >= 100) { coinCount -= 100; storage.coins = coinCount; if (typeof coinTxt !== "undefined") coinTxt.setText('₵ ' + coinCount); // Pick a random ultra-strong permanent effect var ultraEffects = ["superScoreBoost", "permaTriple", "permaRapid", "permaWallBounce", "permaReflect"]; var effect = ultraEffects[Math.floor(Math.random() * ultraEffects.length)]; var popupMsg = ""; var effectLabel = ""; if (effect === "superScoreBoost") { player._superScoreBoost = true; player._scoreBoost = 1; popupMsg = "PERMANENT: 10x Score!"; effectLabel = "10x Score!"; } else if (effect === "permaTriple") { player._tripleShot = 999999; popupMsg = "PERMANENT: Triple Shot!"; effectLabel = "Triple Shot!"; } else if (effect === "permaRapid") { // --- Attack Speed Bonus: Permanent --- if (typeof player._attackSpeedBonus !== "number") player._attackSpeedBonus = 0; player._attackSpeedBonus += 5; // Permanent big bonus powerActive = true; powerTimer = 999999; popupMsg = "PERMANENT: Rapid Fire!"; effectLabel = "Rapid Fire!"; } else if (effect === "permaWallBounce") { player._wallBounce = 999999; popupMsg = "PERMANENT: Wall Bounce!"; effectLabel = "Wall Bounce!"; } else if (effect === "permaReflect") { player._reflect = 999999; popupMsg = "PERMANENT: Reflect!"; effectLabel = "Reflect!"; } LK.effects.flashObject(player, 0xFF2222, 600); showArenaEventPopup("ULTRA Power: " + popupMsg); // Show effect label at top-right currentUltraPowerEffect = effectLabel; setUltraPowerEffectText(effectLabel); } else { showArenaEventPopup("Not enough coins!"); } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
// Coin (altın) kutusu
var Coin = Container.expand(function () {
var self = Container.call(this);
var coinGfx = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = coinGfx.width * 0.5;
self.update = function () {
// Hafifçe döndür
coinGfx.rotation += 0.12;
};
return self;
});
// Düşman karakteri (AI) - Enemy1: Kendini iyileştirme yeteneği
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGfx = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = enemyGfx.width * 0.5;
self.type = 1;
self.speed = 3 + Math.random() * 2;
self.dir = Math.random() * Math.PI * 2;
self.shootCooldown = 60 + Math.floor(Math.random() * 60);
self.targetX = 0;
self.targetY = 0;
self.maxHealth = 3 + Math.floor(Math.random() * 2); // 3-4 can
self.health = self.maxHealth;
// --- YENİ: Kendini iyileştirme özelliği ---
self.healCooldown = 180 + Math.floor(Math.random() * 120); // 3-5 saniyede bir
// --- KOMİK KONUŞMA BALONU ---
// Funny lines (ENGLISH + EMOJIS)
self._funnyLines = ["You can't catch me! 🏃♂️💨", "That tickles! 😂", "I'm about to explode! 💥", "Alien or comedian? 👽🤡", "Look, I'm dancing! 🕺", "Don't shoot, I'm friendly! ✌️", "Tea break time! 🍵", "Beep bop! Error! 🤖", "Are you a hero or a clown? 🦸♂️🤡", "Leveling up soon! ⏫", "Oops, wrong galaxy! 💫", "Pizza delivery! 🍕", "I want a burger! 🍔", "Insert coin to continue! 👾", "Dance battle, anyone? 💃", "Quack! Wrong sound? 🦆", "Say cheese! 🧀", "Rawr! I'm a tiny dino. 🦖", "Brain freeze! 🧠❄️", "Crab rave time! 🦀🎶", "Hoot hoot! Night shift. 🦉", "I floss daily. 🦷", "To the moon! 🚀", "Catch me if you can! 😜", "This is my serious face. 🥸"];
self._speechBubble = null;
self._speechTimer = 0;
self._showSpeech = function (text) {
// Eski balon varsa sil
if (self._speechBubble) {
self._speechBubble.destroy();
self._speechBubble = null;
}
var bubble = new Text2(text, {
size: 48,
fill: 0xffffff,
font: "Impact"
});
bubble.anchor.set(0.5, 1);
bubble.x = self.x;
bubble.y = self.y - self.radius - 60;
bubble.alpha = 1;
game.addChild(bubble);
self._speechBubble = bubble;
// Balonu 1.2 saniyede kaybolacak şekilde animasyonla
tween(bubble, {
alpha: 0
}, {
duration: 1200,
onFinish: function onFinish() {
if (bubble) bubble.visible = false;
if (self._speechBubble === bubble) self._speechBubble = null;
}
});
};
self.takeDamage = function (amount) {
self.health -= amount;
LK.effects.flashObject(self, 0xffff00, 200);
// Komik konuşma: Hasar alınca %60 ihtimalle konuşsun
if (Math.random() < 0.6) {
var line = self._funnyLines[Math.floor(Math.random() * self._funnyLines.length)];
self._showSpeech(line);
}
if (self.health <= 0) {
// Destroy health bar if exists
if (self._healthBar) {
self._healthBar.destroy();
self._healthBar = null;
}
// Destroy visible health bar if exists
if (self._visHealthBar) {
self._visHealthBar.destroy();
self._visHealthBar = null;
self._visHealthBarBg = null;
self._visHealthBarFg = null;
}
self.destroy();
// Skor boost varsa 2 puan ver
if (player._superScoreBoost && player._scoreBoost > 0) {
score += 10 + (comboCount > 1 ? comboCount : 0);
} else if (player._scoreBoost && player._scoreBoost > 0) {
score += 2 + (comboCount > 1 ? comboCount : 0);
} else {
score += 1 + (comboCount > 1 ? comboCount : 0);
}
updateScoreAndLevel();
if (score > 0 && score % 10 === 0) {
increaseDifficulty();
}
// Remove from enemies array in main loop
self._shouldRemove = true;
}
};
self.update = function () {
if (self._frozen && self._frozen > 0) {
// Donmuşsa titret
self.x += Math.sin(self._frozen) * 2;
self.y += Math.cos(self._frozen) * 2;
return;
}
// --- YENİ: Kendini iyileştirme ---
if (self.healCooldown > 0) {
self.healCooldown--;
} else {
if (self.health < self.maxHealth) {
self.health++;
LK.effects.flashObject(self, 0x00ff00, 200);
}
self.healCooldown = 180 + Math.floor(Math.random() * 120);
}
// Basit AI: Oyuncuya doğru hareket et
var dx = player.x - self.x;
var dy = player.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 1) {
self.x += dx / dist * self.speed;
self.y += dy / dist * self.speed;
}
// Ateş etme
if (self.shootCooldown > 0) {
self.shootCooldown--;
} else {
self.shootCooldown = 90 + Math.floor(Math.random() * 60);
spawnEnemyBullet(self.x, self.y, player.x, player.y);
}
// --- KOMİK KONUŞMA: Rastgele aralıklarla konuşsun ---
// Her update'de sayaç azalt, 0 olunca konuş
if (self._speechTimer > 0) {
self._speechTimer--;
} else if (Math.random() < 0.01) {
// %1 ihtimalle her frame
var line = self._funnyLines[Math.floor(Math.random() * self._funnyLines.length)];
self._showSpeech(line);
self._speechTimer = 180 + Math.floor(Math.random() * 120); // 3-5 saniye bekle
}
// --- HEALTH BAR (rectangle) ---
// Create health bar if not exists
if (!self._visHealthBar) {
self._visHealthBar = new Container();
self._visHealthBarBg = new Container();
self._visHealthBarFg = new Container();
self._visHealthBar.addChild(self._visHealthBarBg);
self._visHealthBar.addChild(self._visHealthBarFg);
game.addChild(self._visHealthBar);
}
if (self._visHealthBar) {
// Position above enemy
self._visHealthBar.x = self.x;
self._visHealthBar.y = self.y - self.radius - 28;
// Health percent
var hp = Math.max(0, self.health) / self.maxHealth;
// Clamp width
var fgWidth = Math.max(24, 180 * hp);
self._visHealthBarFg.width = fgWidth;
// Color: green > yellow > red
if (hp > 0.6) {
self._visHealthBarFg.tint = 0x00ff00;
} else if (hp > 0.3) {
self._visHealthBarFg.tint = 0xffe100;
} else {
self._visHealthBarFg.tint = 0xff4444;
}
self._visHealthBar.visible = true;
}
// Konuşma balonunu takip ettir
if (self._speechBubble) {
self._speechBubble.x = self.x;
self._speechBubble.y = self.y - self.radius - 60;
}
};
return self;
});
// Düşman karakteri 2 (dairesel hareket, elips) - Enemy2: Kalkan oluşturma yeteneği
var Enemy2 = Container.expand(function () {
var self = Container.call(this);
var enemyGfx = self.attachAsset('enemy2', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = enemyGfx.width * 0.5;
self.type = 2;
self.angle = Math.random() * Math.PI * 2;
// Enemy2: Orbit around a random point in the arena, not the player
self.centerX = 200 + Math.random() * 1648;
self.centerY = 200 + Math.random() * 2332;
self.orbitRadius = 400 + Math.random() * 200;
self.speed = 0.012 + Math.random() * 0.008;
self.shootCooldown = 120 + Math.floor(Math.random() * 60);
self.maxHealth = 4 + Math.floor(Math.random() * 2); // 4-5 can
self.health = self.maxHealth;
// --- YENİ: Kalkan özelliği ---
self.shield = 0;
self.shieldCooldown = 240 + Math.floor(Math.random() * 120); // 4-6 saniyede bir
self.takeDamage = function (amount) {
if (self.shield > 0) {
self.shield--;
LK.effects.flashObject(self, 0x00ffff, 200);
return;
}
self.health -= amount;
LK.effects.flashObject(self, 0xffff00, 200);
if (self.health <= 0) {
// Destroy health bar if exists
if (self._healthBar) {
self._healthBar.destroy();
self._healthBar = null;
}
// Destroy visible health bar if exists
if (self._visHealthBar) {
self._visHealthBar.destroy();
self._visHealthBar = null;
self._visHealthBarBg = null;
self._visHealthBarFg = null;
}
self.destroy();
if (player._scoreBoost && player._scoreBoost > 0) {
score += 2 + (comboCount > 1 ? comboCount : 0);
} else {
score += 1 + (comboCount > 1 ? comboCount : 0);
}
updateScoreAndLevel();
if (score > 0 && score % 10 === 0) {
increaseDifficulty();
}
self._shouldRemove = true;
}
};
self.update = function () {
if (self._frozen && self._frozen > 0) {
self.x += Math.sin(self._frozen) * 2;
self.y += Math.cos(self._frozen) * 2;
return;
}
// --- YENİ: Kalkan oluşturma ---
if (self.shieldCooldown > 0) {
self.shieldCooldown--;
} else {
self.shield = 2; // 2 vuruşluk kalkan
self.shieldCooldown = 240 + Math.floor(Math.random() * 120);
LK.effects.flashObject(self, 0x00ffff, 200);
}
// Kalkan efekti için: kalkanı varsa hafif mavi tint
if (self.shield > 0 && enemyGfx) {
enemyGfx.alpha = 0.7;
} else if (enemyGfx) {
enemyGfx.alpha = 1.0;
}
self.angle += self.speed;
self.x = self.centerX + Math.cos(self.angle) * self.orbitRadius;
self.y = self.centerY + Math.sin(self.angle) * self.orbitRadius;
// Ateş etme
if (self.shootCooldown > 0) {
self.shootCooldown--;
} else {
self.shootCooldown = 120 + Math.floor(Math.random() * 60);
spawnEnemyBullet(self.x, self.y, player.x, player.y);
}
// --- HEALTH BAR (rectangle) ---
// Create health bar if not exists
if (!self._visHealthBar) {
self._visHealthBar = new Container();
self._visHealthBarBg = new Container();
self._visHealthBarFg = new Container();
self._visHealthBar.addChild(self._visHealthBarBg);
self._visHealthBar.addChild(self._visHealthBarFg);
game.addChild(self._visHealthBar);
}
if (self._visHealthBar) {
// Position above enemy
self._visHealthBar.x = self.x;
self._visHealthBar.y = self.y - self.radius - 28;
// Health percent
var hp = Math.max(0, self.health) / self.maxHealth;
// Clamp width
var fgWidth = Math.max(24, 180 * hp);
self._visHealthBarFg.width = fgWidth;
// Color: green > yellow > red
if (hp > 0.6) {
self._visHealthBarFg.tint = 0x00ff00;
} else if (hp > 0.3) {
self._visHealthBarFg.tint = 0xffe100;
} else {
self._visHealthBarFg.tint = 0xff4444;
}
self._visHealthBar.visible = true;
}
};
return self;
});
// Düşman karakteri 3 (rastgele zıplama, mor kutu) - Enemy3: Ölünce ikiye bölünme yeteneği
var Enemy3 = Container.expand(function () {
var self = Container.call(this);
var enemyGfx = self.attachAsset('enemy3', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = enemyGfx.width * 0.5;
self.type = 3;
self.jumpTimer = 60 + Math.floor(Math.random() * 60);
self.targetX = 200 + Math.random() * 1648;
self.targetY = 200 + Math.random() * 2332;
self.speed = 12 + Math.random() * 6;
self.shootCooldown = 100 + Math.floor(Math.random() * 60);
self.maxHealth = 2 + Math.floor(Math.random() * 2); // 2-3 can
self.health = self.maxHealth;
self.takeDamage = function (amount) {
self.health -= amount;
LK.effects.flashObject(self, 0xffff00, 200);
if (self.health <= 0) {
// Destroy health bar if exists
if (self._healthBar) {
self._healthBar.destroy();
self._healthBar = null;
}
// Destroy visible health bar if exists
if (self._visHealthBar) {
self._visHealthBar.destroy();
self._visHealthBar = null;
self._visHealthBarBg = null;
self._visHealthBarFg = null;
}
// Splitting on death removed
self.destroy();
if (player._scoreBoost && player._scoreBoost > 0) {
score += 2 + (comboCount > 1 ? comboCount : 0);
} else {
score += 1 + (comboCount > 1 ? comboCount : 0);
}
updateScoreAndLevel();
if (score > 0 && score % 10 === 0) {
increaseDifficulty();
}
self._shouldRemove = true;
}
};
self.update = function () {
if (self._frozen && self._frozen > 0) {
self.x += Math.sin(self._frozen) * 2;
self.y += Math.cos(self._frozen) * 2;
return;
}
self.jumpTimer--;
if (self.jumpTimer <= 0) {
self.targetX = 200 + Math.random() * 1648;
self.targetY = 200 + Math.random() * 2332;
self.jumpTimer = 60 + Math.floor(Math.random() * 60);
}
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 1) {
self.x += dx / dist * self.speed;
self.y += dy / dist * self.speed;
}
// Ateş etme
if (self.shootCooldown > 0) {
self.shootCooldown--;
} else {
self.shootCooldown = 100 + Math.floor(Math.random() * 60);
spawnEnemyBullet(self.x, self.y, player.x, player.y);
}
// --- HEALTH BAR (rectangle) ---
// Create health bar if not exists
if (!self._visHealthBar) {
self._visHealthBar = new Container();
self._visHealthBarBg = new Container();
self._visHealthBarFg = new Container();
self._visHealthBar.addChild(self._visHealthBarBg);
self._visHealthBar.addChild(self._visHealthBarFg);
game.addChild(self._visHealthBar);
}
if (self._visHealthBar) {
// Position above enemy
self._visHealthBar.x = self.x;
self._visHealthBar.y = self.y - self.radius - 28;
// Health percent
var hp = Math.max(0, self.health) / self.maxHealth;
// Clamp width
var fgWidth = Math.max(24, 180 * hp);
self._visHealthBarFg.width = fgWidth;
// Color: green > yellow > red
if (hp > 0.6) {
self._visHealthBarFg.tint = 0x00ff00;
} else if (hp > 0.3) {
self._visHealthBarFg.tint = 0xffe100;
} else {
self._visHealthBarFg.tint = 0xff4444;
}
self._visHealthBar.visible = true;
}
};
return self;
});
// Düşman mermisi
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGfx = self.attachAsset('enemyBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = bulletGfx.width * 0.5;
self.vx = 0;
self.vy = 0;
self.update = function () {
self.x += self.vx;
self.y += self.vy;
};
return self;
});
// Oyuncu karakteri
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGfx = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = playerGfx.width * 0.5;
self.shootCooldown = 0;
// Oyuncuya can ekle
self.maxHealth = typeof playerMaxHealth !== "undefined" ? playerMaxHealth : 5;
self.health = typeof playerHealth !== "undefined" ? playerHealth : self.maxHealth;
self.update = function () {
if (self.shootCooldown > 0) self.shootCooldown--;
};
return self;
});
// Oyuncu mermisi
var PlayerBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGfx = self.attachAsset('playerBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = bulletGfx.width * 0.5;
self.vx = 0;
self.vy = 0;
self.update = function () {
self.x += self.vx;
self.y += self.vy;
};
return self;
});
// Güçlendirici (PowerUp) kutusu
var PowerUp = Container.expand(function () {
var self = Container.call(this);
var powerGfx = self.attachAsset('powerUp', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = powerGfx.width * 0.5;
self.type = "power";
// Yeni powerup efektleri eklendi
var effects = ["rapid",
// Hızlı ateş (fire rate)
"triple",
// Üçlü atış
"shield",
// Kalkan
"heal",
// Can doldur
"wallBounce",
// Duvar sekme
"reflect",
// Düşman mermisi sektirme
"slow",
// Zaman yavaşlatma (tüm düşmanlar yavaşlar)
"magnet",
// Magnet (yakındaki coin/powerup çeker)
"randomizer",
// Randomizer (tüm düşmanların tipi değişir)
"superHeal",
// Süper can: max canı artır ve doldur
"freezeBullets",
// Düşman mermilerini dondur
"coinRain",
// Ekrana coin yağmuru
"enemyClear",
// Tüm düşmanları yok et
"scoreBoost" // Skor 2x (15s)
];
self.effect = effects[Math.floor(Math.random() * effects.length)];
self.update = function () {
// Hafifçe döndür
powerGfx.rotation += 0.08;
};
return self;
});
// PowerUpCombo: Birleşmiş poweruplar için özel kutu
var PowerUpCombo = Container.expand(function () {
var self = Container.call(this);
var powerGfx = self.attachAsset('powerUp', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = powerGfx.width * 0.6;
self.type = "powerCombo";
self.effects = []; // ["rapid", "triple", ...]
self.update = function () {
// Hafifçe döndür ve renk değiştir (her efekt için farklı renkler)
powerGfx.rotation += 0.12;
// Renkleri birleştir: efekt sayısına göre tint değiştir
if (self.effects.indexOf("slow") !== -1 && self.effects.length === 1) {
powerGfx.tint = 0x66ccff; // Mavi (slow)
} else if (self.effects.indexOf("magnet") !== -1 && self.effects.length === 1) {
powerGfx.tint = 0xff00ff; // Magnet için mor
} else if (self.effects.indexOf("randomizer") !== -1 && self.effects.length === 1) {
powerGfx.tint = 0x00ffcc; // Randomizer için turkuaz
} else if (self.effects.length === 2) {
powerGfx.tint = 0xFFD700; // Altın
} else if (self.effects.length >= 3) {
powerGfx.tint = 0xFF44FF; // Pembe
} else {
powerGfx.tint = 0xFFFFFF;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x0074D9
});
/****
* Game Code
****/
// Space background images (add your own image asset IDs as needed)
// --- SPACE BACKGROUND ---
// Global değişkenler
// Space backgrounds as assets
var spaceBackgrounds = [{
id: 'spacebg1',
width: 2048,
height: 2732,
assetId: '682e6b2ad10b0c0b481370a1'
}, {
id: 'spacebg2',
width: 2048,
height: 2732,
assetId: '682e6b3fd10b0c0b481370a2'
}, {
id: 'spacebg3',
width: 2048,
height: 2732,
assetId: '682e6b4ad10b0c0b481370a3'
}];
// Register background assets (engine will load them automatically)
for (var i = 0; i < spaceBackgrounds.length; i++) {}
// Pick a random background
var selectedBg = spaceBackgrounds[Math.floor(Math.random() * spaceBackgrounds.length)];
var bgSprite = LK.getAsset(selectedBg.id, {
anchorX: 0,
anchorY: 0
});
bgSprite.x = 0;
bgSprite.y = 0;
bgSprite.width = 2048;
bgSprite.height = 2732;
game.addChildAt(bgSprite, 0); // Add as the bottom-most layer
// Coin asset
var player;
var enemies = [];
var playerBullets = [];
var enemyBullets = [];
var powerUps = [];
var coins = []; // Coin objects
var coinCount = 0; // Collected coin count
var coinTxt = new Text2('₵ ' + coinCount, {
size: 70,
fill: 0xFFD700,
font: "Impact"
});
coinTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(coinTxt);
coinTxt.y = 340;
var powerActive = false;
var powerTimer = 0;
var dragNode = null;
var lastPlayerPos = {
x: 0,
y: 0
};
var score = 0;
var level = 1;
var gameTick = 0;
var spawnTimer = 0;
var isGameOver = false;
// Combo variables
var comboCount = 0;
var comboTimer = 0;
var maxComboTime = 120; // 2 seconds (120 frames)
var maxCombo = 0;
// Combo GUI
var comboTxt = new Text2('', {
size: 80,
fill: 0xFFFA00,
font: "Impact"
});
comboTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(comboTxt);
comboTxt.y = 260;
// Health bar variables
// Permanent max health and max attack upgrades RESET
storage.permMaxHealthUp = 0;
storage.permMaxAttackUp = 0;
// Permanent max health upgrade from storage
var permHealthUp = typeof storage.permMaxHealthUp === "number" ? storage.permMaxHealthUp : 0;
var playerMaxHealth = 10 + permHealthUp;
var playerHealth = playerMaxHealth;
// Health bar GUI
var healthTxt = new Text2('Health: ' + playerHealth, {
size: 70,
fill: 0xFF4444
});
healthTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(healthTxt);
healthTxt.y = 180;
// --- HOW TO PLAY POPUP (before game starts) ---
var howToPlayTxt = new Text2("Nasıl Oynanır?\n\n" + "- Parmağınızı ekrana basılı tutup karakterinizi ARENADA sürükleyin.\n" + "- Düşmanlardan ve mermilerden kaçın, otomatik ateşle düşmanları yok edin!\n" + "- Güçlendiricileri (PowerUp) ve altınları toplayın.\n" + "- Kombo yaparak daha fazla puan kazanın.\n" + "- Sol üstte istatistiklerinizi takip edin.\n\n" + "Başlamak için ekrana dokunun!", {
size: 70,
fill: "#fff",
font: "Impact",
align: "center",
wordWrap: true,
wordWrapWidth: 1600
});
howToPlayTxt.anchor.set(0.5, 0.5);
howToPlayTxt.x = 2048 / 2;
howToPlayTxt.y = 2732 / 2;
howToPlayTxt.background = {
color: 0x222244,
alpha: 0.92,
padding: 60,
radius: 48
};
LK.gui.center.addChild(howToPlayTxt);
// Oyuncu dokununca başlat
var howToPlayActive = true;
game.down = function (x, y, obj) {
if (howToPlayActive) {
howToPlayActive = false;
howToPlayTxt.visible = false;
startGame();
} else {
// If player is tapped, start dragging
var px = player.x,
py = player.y;
var dx = x - px,
dy = y - py;
var dist = Math.sqrt(dx * dx + dy * dy);
// User-friendly: If tapped on player, start dragging, otherwise do nothing
if (dist < player.radius + 80) {
// wider area, easier drag
dragNode = player;
lastPlayerPos.x = x;
lastPlayerPos.y = y;
// When drag starts, don't fire, prevent accidental fire
// Drag threshold: set a flag to check if drag distance exceeds a threshold before firing
dragNode._dragStarted = false;
dragNode._dragStartX = x;
dragNode._dragStartY = y;
dragNode._dragStartTime = Date.now();
} else {
// (Removed: tap-to-shoot code is now gone)
}
}
};
// --- OYUNU BAŞLAT ---
function startGame() {
// Oyun değişkenlerini sıfırla
isInMainMenu = false; // Oyun başlarken menüden çık
score = 0;
level = 1;
// Apply permanent max health upgrade from storage
var permHealthUp = typeof storage.permMaxHealthUp === "number" ? storage.permMaxHealthUp : 0;
playerMaxHealth = 10 + permHealthUp;
playerHealth = playerMaxHealth;
enemies = [];
playerBullets = [];
enemyBullets = [];
powerUps = [];
coins = [];
powerActive = false;
powerTimer = 0;
comboCount = 0;
comboTimer = 0;
maxCombo = 0;
isGameOver = false;
gameTick = 0;
spawnTimer = 0;
dragNode = null;
lastPlayerPos = {
x: 0,
y: 0
};
// Apply permanent max attack upgrade from storage
var permAttackUp = typeof storage.permMaxAttackUp === "number" ? storage.permMaxAttackUp : 0;
if (typeof player !== "undefined") {
player._permAttackUp = permAttackUp;
}
// Ultra power effect text clear
if (typeof setUltraPowerEffectText === "function") setUltraPowerEffectText('');
if (typeof currentUltraPowerEffect !== "undefined") currentUltraPowerEffect = "";
// GUI güncelle
updateScoreAndLevel();
updateStatsPanel();
if (typeof coinTxt !== "undefined") coinTxt.setText('₵ ' + (typeof storage.coins === "number" ? storage.coins : 0));
if (typeof player !== "undefined") {
if (typeof player.maxHealth !== "undefined") player.maxHealth = playerMaxHealth;
if (typeof player.health !== "undefined") player.health = playerHealth;
}
// Oyuncu konumunu sıfırla
if (typeof player !== "undefined") {
player.x = 2048 / 2;
player.y = 2732 / 2;
}
}
// Play background music (loops by default)
LK.playMusic('musicId');
// PowerUp oluşturucu
function spawnPowerUp() {
var p = new PowerUp();
// Güvenli alan içinde rastgele konum
p.x = 200 + Math.random() * 1648;
p.y = 200 + Math.random() * 2332;
powerUps.push(p);
game.addChild(p);
}
// Coin oluşturucu
function spawnCoin(x, y) {
var c = new Coin();
// Eğer x, y verilmişse oraya koy, yoksa rastgele
if (typeof x === "number" && typeof y === "number") {
c.x = x;
c.y = y;
} else {
c.x = 200 + Math.random() * 1648;
c.y = 200 + Math.random() * 2332;
}
coins.push(c);
game.addChild(c);
}
// Score and level display
var scoreTxt = new Text2('Score: 0', {
size: 90,
fill: "#fff"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var levelTxt = new Text2('Level: 1', {
size: 60,
fill: "#fff"
});
levelTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(levelTxt);
levelTxt.y = 100;
// Eğlenceli: Arena event popup
var eventPopupTxt = new Text2('', {
size: 70,
fill: 0xFFFA00,
font: "Impact"
});
eventPopupTxt.anchor.set(0.5, 0.5);
eventPopupTxt.visible = false;
LK.gui.center.addChild(eventPopupTxt);
// Arena event popup function (already in English, nothing to change)
function showArenaEventPopup(msg) {
eventPopupTxt.setText(msg);
eventPopupTxt.visible = true;
eventPopupTxt.alpha = 1;
tween(eventPopupTxt, {
alpha: 0
}, {
duration: 1200,
onFinish: function onFinish() {
eventPopupTxt.visible = false;
}
});
}
// Oyuncu oluştur
player = new Player();
game.addChild(player);
player.x = 2048 / 2;
player.y = 2732 / 2;
// Apply permanent max attack upgrade from storage on initial load
var permAttackUp = typeof storage.permMaxAttackUp === "number" ? storage.permMaxAttackUp : 0;
player._permAttackUp = permAttackUp;
// Düşman oluşturucu
function spawnEnemy() {
var t = Math.random();
var e;
if (t < 0.4) {
e = new Enemy();
} else if (t < 0.7) {
e = new Enemy2();
} else {
e = new Enemy3();
}
// --- FUNNY SPEECH BUBBLE ON SPAWN (with emojis) ---
var funnySpawnLines = ["👽 Boo! Did I scare you?", "😂 I'm too cute to shoot!", "🍕 Pizza time! Wait, no pizza?", "🦄 I'm a unicorn in disguise!", "💩 Oops, wrong galaxy!", "🤡 Who invited the clown?", "🕺 Dance battle, anyone?", "🐸 Ribbit! Oh wait, I'm not a frog.", "🚀 To the moon! ...or not.", "😜 Catch me if you can!", "🥸 This is my serious face.", "🧀 Say cheese!", "🦖 Rawr! I'm a tiny dino.", "👾 Insert coin to continue!", "🦆 Quack! Wrong sound?", "🍔 I want a burger!", "🧠 Brain freeze!", "🦷 I floss daily.", "🦀 Crab rave time!", "🦉 Hoot hoot! Night shift."];
if (typeof e._showSpeech === "function") {
var spawnLine = funnySpawnLines[Math.floor(Math.random() * funnySpawnLines.length)];
e._showSpeech(spawnLine);
}
// Enemies get stronger: health increases with level and score
if (typeof e.maxHealth !== "undefined") {
// Her 3 level'da +1 can, her 20 skor'da +1 can
var extraHealth = Math.floor(level / 3) + Math.floor(score / 20);
e.maxHealth += extraHealth;
e.health = e.maxHealth;
}
// Randomly spawn from edge
var edge = Math.floor(Math.random() * 4);
if (edge === 0) {
// top
e.x = 200 + Math.random() * 1648;
e.y = -100;
} else if (edge === 1) {
// right
e.x = 2148;
e.y = 200 + Math.random() * 2332;
} else if (edge === 2) {
// bottom
e.x = 200 + Math.random() * 1648;
e.y = 2832;
} else {
// left
e.x = -100;
e.y = 200 + Math.random() * 2332;
}
enemies.push(e);
game.addChild(e);
}
// Düşman mermisi oluşturucu
function spawnEnemyBullet(sx, sy, tx, ty) {
var b = new EnemyBullet();
b.x = sx;
b.y = sy;
var dx = tx - sx;
var dy = ty - sy;
var dist = Math.sqrt(dx * dx + dy * dy);
var speed = 9 + level * 1; // Düşman mermisi hızı azaltıldı
b.vx = dx / dist * speed;
b.vy = dy / dist * speed;
enemyBullets.push(b);
game.addChild(b);
}
// Oyuncu mermisi oluşturucu
function spawnPlayerBullet(sx, sy, tx, ty) {
var b = new PlayerBullet();
b.x = sx;
b.y = sy;
var dx = tx - sx;
var dy = ty - sy;
var dist = Math.sqrt(dx * dx + dy * dy);
var speed = 32;
b.vx = dx / dist * speed;
b.vy = dy / dist * speed;
playerBullets.push(b);
game.addChild(b);
LK.getSound('shoot').play();
}
// Skor ve seviye güncelle
function updateScoreAndLevel() {
if (typeof scoreTxt !== "undefined" && scoreTxt && typeof scoreTxt.setText === "function") {
if (scoreTxt._lastScore !== score) {
scoreTxt.setText('Score: ' + score);
scoreTxt._lastScore = score;
}
}
if (typeof levelTxt !== "undefined" && levelTxt && typeof levelTxt.setText === "function") {
if (levelTxt._lastLevel !== level) {
levelTxt.setText('Level: ' + level);
levelTxt._lastLevel = level;
}
}
if (typeof healthTxt !== "undefined" && healthTxt && typeof healthTxt.setText === "function") {
if (healthTxt._lastHealth !== playerHealth) {
healthTxt.setText('Health: ' + playerHealth);
healthTxt._lastHealth = playerHealth;
}
}
updateComboText();
}
// Kombo GUI güncelle
function updateComboText() {
if (comboCount > 1) {
if (comboTxt._lastCombo !== comboCount) {
comboTxt.setText("COMBO x" + comboCount + "!");
comboTxt.visible = true;
comboTxt.alpha = 1;
comboTxt._lastCombo = comboCount;
}
} else {
if (comboTxt.visible) {
comboTxt.visible = false;
comboTxt._lastCombo = 0;
}
}
}
// Oyun zorluğunu artır
function increaseDifficulty() {
level++;
updateScoreAndLevel();
}
// Oyun bitti
function gameOver() {
if (isGameOver) return;
isGameOver = true;
// --- STATISTICS: Update high score and max combo at game over ---
if (score > storage.highScore) {
storage.highScore = score;
}
if (maxCombo > storage.maxCombo) {
storage.maxCombo = maxCombo;
}
updateStatsPanel();
LK.effects.flashScreen(0xff0000, 1000);
LK.getSound('hit').play();
LK.showGameOver();
}
// Oyun kazandı
function youWin() {
showArenaEventPopup("YOU WIN! 🎉");
LK.effects.flashScreen(0x00ffcc, 1000);
LK.showYouWin();
}
// Sürükleme ve ateş etme
function handleMove(x, y, obj) {
if (dragNode) {
// Apply movement delta
var dx = x - lastPlayerPos.x;
var dy = y - lastPlayerPos.y;
dragNode.x += dx;
dragNode.y += dy;
// User-friendly: Prevent player from going out of bounds
var minX = dragNode.radius + 20;
var maxX = 2048 - dragNode.radius - 20;
var minY = dragNode.radius + 20;
var maxY = 2732 - dragNode.radius - 20;
if (dragNode.x < minX) dragNode.x = minX;
if (dragNode.x > maxX) dragNode.x = maxX;
if (dragNode.y < minY) dragNode.y = minY;
if (dragNode.y > maxY) dragNode.y = maxY;
lastPlayerPos.x = x;
lastPlayerPos.y = y;
}
}
// Out of bounds check
function isOutOfBounds(obj) {
return obj.x < -200 || obj.x > 2248 || obj.y < -200 || obj.y > 2932;
}
// Oyun ana döngüsü
game.update = function () {
if (isGameOver) return;
gameTick++;
// Fun: Random arena events (e.g. meteor shower, bonus rain, enemy freeze)
// Every 15 seconds, a random event may trigger
if (gameTick % 900 === 0 && gameTick > 0) {
var eventType = Math.floor(Math.random() * 3);
if (eventType === 0) {
// Meteor shower: 10 fast bullets fall from the top
for (var m = 0; m < 10; m++) {
var b = new EnemyBullet();
b.x = 200 + Math.random() * 1648;
b.y = -80 - m * 60;
b.vx = 0;
b.vy = 32 + Math.random() * 8;
enemyBullets.push(b);
game.addChild(b);
}
// Short effect
LK.effects.flashScreen(0xffa500, 400);
showArenaEventPopup("Meteor Shower!");
} else if (eventType === 1) {
// Bonus rain: 5 powerUps drop at once
for (var p = 0; p < 5; p++) {
var pu = new PowerUp();
pu.x = 200 + Math.random() * 1648;
pu.y = 200 + Math.random() * 2332;
powerUps.push(pu);
game.addChild(pu);
}
LK.effects.flashScreen(0x00ffcc, 400);
showArenaEventPopup("Bonus Rain!");
} else if (eventType === 2) {
// Enemies freeze for 3 seconds
for (var i = 0; i < enemies.length; i++) {
enemies[i]._frozen = 180; // 3 seconds
}
LK.effects.flashScreen(0x66ccff, 400);
showArenaEventPopup("Enemies Frozen!");
}
}
// Düşmanları dondurma efekti uygula
for (var i = 0; i < enemies.length; i++) {
if (enemies[i]._frozen && enemies[i]._frozen > 0) {
enemies[i]._frozen--;
continue; // update çağrılmasın, düşman hareket etmesin
}
}
// Oyuncu update
player.update();
// Oyuncu canını playerHealth ile senkronize et
if (typeof player.health !== "undefined" && typeof playerHealth !== "undefined" && player.health !== playerHealth) {
player.health = playerHealth;
}
if (typeof player.maxHealth !== "undefined" && typeof playerMaxHealth !== "undefined" && player.maxHealth !== playerMaxHealth) {
player.maxHealth = playerMaxHealth;
}
// --- Attack Speed Bonus: Stacks with powerups ---
if (typeof player._attackSpeedBonus === "undefined") player._attackSpeedBonus = 0;
// Otomatik ateş etme (her 10 frame'de bir, rapid fire veya attack speed bonus varsa daha hızlı)
var baseShootInterval = 10;
var rapidFireInterval = powerActive ? 4 : baseShootInterval;
var attackSpeedInterval = Math.max(2, rapidFireInterval - player._attackSpeedBonus * 2);
var shootInterval = attackSpeedInterval;
if (!isGameOver && gameTick % shootInterval === 0 && enemies.length > 0) {
// En yakın düşmanı bul
var minDist = Infinity;
var targetEnemy = null;
for (var i = 0; i < enemies.length; i++) {
var e = enemies[i];
var dx = e.x - player.x;
var dy = e.y - player.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < minDist) {
minDist = dist;
targetEnemy = e;
}
}
if (targetEnemy) {
// --- Otomatik nişan geliştirme: Düşmanın hareketini tahmin et ---
// Düşmanın bir sonraki pozisyonunu tahmin etmek için basit linear prediction
var bulletSpeed = 32;
var ex = targetEnemy.x;
var ey = targetEnemy.y;
var evx = 0,
evy = 0;
// Tahmini hız: son pozisyonları varsa kullan
if (typeof targetEnemy._lastX === "number" && typeof targetEnemy._lastY === "number") {
evx = targetEnemy.x - targetEnemy._lastX;
evy = targetEnemy.y - targetEnemy._lastY;
}
// Hedefe olan mesafe
var dx = ex - player.x;
var dy = ey - player.y;
var dist = Math.sqrt(dx * dx + dy * dy);
// Zaman tahmini (kaç frame sonra mermi ulaşır)
var t = dist / bulletSpeed;
// Tahmini hedef pozisyonu
var predictedX = ex + evx * t;
var predictedY = ey + evy * t;
// Triple shot powerup varsa üçlü mermi ateşle
if (player._tripleShot && player._tripleShot > 0) {
for (var s = -1; s <= 1; s++) {
var angle = Math.atan2(predictedY - player.y, predictedX - player.x) + s * 0.18;
var tx = player.x + Math.cos(angle) * 1000;
var ty = player.y + Math.sin(angle) * 1000;
spawnPlayerBullet(player.x, player.y, tx, ty);
}
} else {
spawnPlayerBullet(player.x, player.y, predictedX, predictedY);
}
}
}
// Düşman update
for (var i = enemies.length - 1; i >= 0; i--) {
var e = enemies[i];
// Skip update if enemy is destroyed or out of bounds
if (!e || typeof e.destroyed !== "undefined" && e.destroyed) {
if (e && e._healthBar) {
e._healthBar.destroy();
}
enemies.splice(i, 1);
continue;
}
if (isOutOfBounds(e)) {
if (e._healthBar) {
e._healthBar.destroy();
}
e.destroy();
enemies.splice(i, 1);
continue;
}
// --- Otomatik nişan için: Son pozisyonu kaydet ---
e._lastX = typeof e.x === "number" ? e.x : 0;
e._lastY = typeof e.y === "number" ? e.y : 0;
if (typeof e.update === "function") e.update();
// Can barı çizimi (her düşmanın üstünde) - optimize: sadece health değiştiyse güncelle
if (!e._healthBar) {
e._healthBar = new Text2('', {
size: 64,
fill: 0xFF4444,
font: "Impact"
});
e._healthBar.anchor.set(0.5, 1);
game.addChild(e._healthBar);
}
if (typeof e.health !== "undefined" && typeof e.maxHealth !== "undefined") {
if (e._healthBar._lastHealth !== e.health || e._healthBar._lastMaxHealth !== e.maxHealth) {
e._healthBar.setText("♥ " + e.health + "/" + e.maxHealth);
e._healthBar._lastHealth = e.health;
e._healthBar._lastMaxHealth = e.maxHealth;
}
e._healthBar.x = e.x;
e._healthBar.y = e.y - e.radius - 18;
e._healthBar.visible = true;
} else {
e._healthBar.visible = false;
}
// Çarpışma: oyuncu & düşman
if (player.intersects(e)) {
if (player._shield && player._shield > 0) {
player._shield--;
LK.effects.flashObject(player, 0x00ffff, 400);
if (player._shield === 0) {
showArenaEventPopup("Shield Broken!");
} else {
showArenaEventPopup("Shield: " + player._shield + " hits left!");
}
} else {
playerHealth--;
if (typeof player.health !== "undefined") player.health = playerHealth;
updateScoreAndLevel();
LK.effects.flashObject(player, 0xff4444, 400);
LK.getSound('hit').play();
if (playerHealth <= 0) {
gameOver();
return;
}
}
// Düşmanı yok et, can azalınca
if (typeof e.takeDamage === "function") {
e.takeDamage(e.health); // Tüm canı gitmeli
if (e._shouldRemove) {
if (e._healthBar) {
e._healthBar.destroy();
}
// COIN: Düşman öldüğünde coin spawn et
var baseCoinChance = 0.7;
var extraChance = Math.min(comboCount * 0.10, 0.5);
if (Math.random() < baseCoinChance + extraChance) {
spawnCoin(e.x, e.y);
}
// --- PowerUp drop şansı: %20 + kombo başına %4, max %40 ---
var basePowerUpChance = 0.20;
var extraPowerUpChance = Math.min(comboCount * 0.04, 0.20);
if (Math.random() < basePowerUpChance + extraPowerUpChance) {
spawnPowerUp();
if (powerUps.length > 0) {
var pu = powerUps[powerUps.length - 1];
pu.x = e.x;
pu.y = e.y;
}
}
enemies.splice(i, 1);
// KOMBO: Düşman öldürdüyse kombo başlat
if (typeof e._killedByPlayer === "undefined" || e._killedByPlayer) {
comboCount++;
comboTimer = maxComboTime;
if (comboCount > maxCombo) maxCombo = comboCount;
if (comboCount > storage.maxCombo) {
storage.maxCombo = comboCount;
updateStatsPanel();
}
storage.totalEnemiesKilled = (typeof storage.totalEnemiesKilled === "number" ? storage.totalEnemiesKilled : 0) + 1;
updateStatsPanel();
updateComboText();
}
continue;
}
} else {
e.destroy();
if (e._healthBar) {
e._healthBar.destroy();
}
// COIN: Düşman öldüğünde coin spawn et
var baseCoinChance = 0.7;
var extraChance = Math.min(comboCount * 0.10, 0.5);
if (Math.random() < baseCoinChance + extraChance) {
spawnCoin(e.x, e.y);
}
// --- PowerUp drop şansı: %20 + kombo başına %4, max %40 ---
var basePowerUpChance = 0.20;
var extraPowerUpChance = Math.min(comboCount * 0.04, 0.20);
if (Math.random() < basePowerUpChance + extraPowerUpChance) {
spawnPowerUp();
if (powerUps.length > 0) {
var pu = powerUps[powerUps.length - 1];
pu.x = e.x;
pu.y = e.y;
}
}
enemies.splice(i, 1);
comboCount++;
comboTimer = maxComboTime;
if (comboCount > maxCombo) maxCombo = comboCount;
if (comboCount > storage.maxCombo) {
storage.maxCombo = comboCount;
updateStatsPanel();
}
storage.totalEnemiesKilled = (typeof storage.totalEnemiesKilled === "number" ? storage.totalEnemiesKilled : 0) + 1;
updateStatsPanel();
updateComboText();
continue;
}
}
}
// Oyuncu mermisi update
for (var i = playerBullets.length - 1; i >= 0; i--) {
var b = playerBullets[i];
// Skip update if bullet is destroyed or out of bounds
if (!b || typeof b.destroyed !== "undefined" && b.destroyed) {
playerBullets.splice(i, 1);
continue;
}
if (isOutOfBounds(b)) {
b.destroy();
playerBullets.splice(i, 1);
continue;
}
if (typeof b.update === "function") b.update();
var hit = false;
// Düşmanlara çarpma
for (var j = enemies.length - 1; j >= 0; j--) {
var e = enemies[j];
if (b.intersects(e)) {
LK.getSound('hit').play();
if (typeof e.takeDamage === "function") {
e._killedByPlayer = true;
var permAttackUp = typeof player._permAttackUp === "number" ? player._permAttackUp : 0;
var bulletDamage = 2 + permAttackUp;
e.takeDamage(bulletDamage);
if (e._shouldRemove) {
enemies.splice(j, 1);
}
}
hit = true;
break;
}
}
// WALL BOUNCE: Eğer aktifse, mermi kenara çarptıysa sekmeli
var wallBounceActive = player._wallBounce && player._wallBounce > 0;
if (!hit && wallBounceActive) {
var bounced = false;
if (b.x < b.radius + 10 && b.vx < 0) {
b.x = b.radius + 10;
b.vx *= -1;
bounced = true;
}
if (b.x > 2048 - b.radius - 10 && b.vx > 0) {
b.x = 2048 - b.radius - 10;
b.vx *= -1;
bounced = true;
}
if (b.y < b.radius + 10 && b.vy < 0) {
b.y = b.radius + 10;
b.vy *= -1;
bounced = true;
}
if (b.y > 2732 - b.radius - 10 && b.vy > 0) {
b.y = 2732 - b.radius - 10;
b.vy *= -1;
bounced = true;
}
// Eğer sekmediyse ve hala out of bounds ise yok et
if (!bounced && isOutOfBounds(b)) {
b.destroy();
playerBullets.splice(i, 1);
continue;
}
if (hit) {
b.destroy();
playerBullets.splice(i, 1);
continue;
}
} else {
if (hit || isOutOfBounds(b)) {
b.destroy();
playerBullets.splice(i, 1);
continue;
}
}
}
// Düşman mermisi update
for (var i = enemyBullets.length - 1; i >= 0; i--) {
var b = enemyBullets[i];
// Skip update if bullet is destroyed or out of bounds
if (!b || typeof b.destroyed !== "undefined" && b.destroyed) {
enemyBullets.splice(i, 1);
continue;
}
if (isOutOfBounds(b)) {
b.destroy();
enemyBullets.splice(i, 1);
continue;
}
if (typeof b.update === "function") b.update();
// Oyuncuya çarpma
var reflectActive = player._reflect && player._reflect > 0;
if (b.intersects(player)) {
if (reflectActive) {
// Reflect: Düşman mermisi oyuncuya çarptığında geri sektir
var newB = new PlayerBullet();
newB.x = b.x;
newB.y = b.y;
var mag = Math.sqrt(b.vx * b.vx + b.vy * b.vy);
if (mag === 0) mag = 1;
newB.vx = -b.vx / mag * 32;
newB.vy = -b.vy / mag * 32;
playerBullets.push(newB);
game.addChild(newB);
LK.effects.flashObject(player, 0x00ffcc, 200);
showArenaEventPopup("Reflected!");
b.destroy();
enemyBullets.splice(i, 1);
continue;
} else if (player._shield && player._shield > 0) {
player._shield--;
LK.effects.flashObject(player, 0x00ffff, 400);
if (player._shield === 0) {
showArenaEventPopup("Shield Broken!");
} else {
showArenaEventPopup("Shield: " + player._shield + " hits left!");
}
} else {
playerHealth--;
if (typeof player.health !== "undefined") player.health = playerHealth;
updateScoreAndLevel();
LK.effects.flashObject(player, 0xff4444, 400);
LK.getSound('hit').play();
if (playerHealth <= 0) {
b.destroy();
enemyBullets.splice(i, 1);
gameOver();
return;
}
}
b.destroy();
enemyBullets.splice(i, 1);
continue;
}
if (isOutOfBounds(b)) {
b.destroy();
enemyBullets.splice(i, 1);
continue;
}
}
// KOMBO zamanlayıcı: Kombo süresi dolarsa sıfırla
if (comboCount > 0) {
comboTimer--;
if (comboTimer <= 0) {
// Show fun popup for max combo if it was a big combo
if (comboCount >= 5) {
showArenaEventPopup("AWESOME COMBO x" + comboCount + "!");
LK.effects.flashScreen(0xffe100, 400);
} else if (comboCount >= 3) {
showArenaEventPopup("Combo x" + comboCount + "!");
}
comboCount = 0;
updateComboText();
}
}
// Fun popup: Level up
if (typeof lastLevel === "undefined") {
lastLevel = level;
}
if (level > lastLevel) {
showArenaEventPopup("LEVEL UP! Level " + level);
LK.effects.flashScreen(0x00ff00, 400);
lastLevel = level;
}
// Fun popup: Coin milestone
if (typeof lastCoinMilestone === "undefined") {
lastCoinMilestone = 0;
}
if (coinCount >= lastCoinMilestone + 10) {
showArenaEventPopup("Coin Collector! ₵" + coinCount);
LK.effects.flashScreen(0xffd700, 300);
lastCoinMilestone = coinCount - coinCount % 10;
}
// PowerUp update ve çarpışma
// --- PowerUp birleşme ve combo mekaniği ---
for (var i = powerUps.length - 1; i >= 0; i--) {
var p = powerUps[i];
// Skip update if powerup is destroyed or out of bounds
if (!p || typeof p.destroyed !== "undefined" && p.destroyed) {
powerUps.splice(i, 1);
continue;
}
if (isOutOfBounds(p)) {
p.destroy();
powerUps.splice(i, 1);
continue;
}
p.update();
// Magnet veya Super Magnet aktifse, powerupları çek
var magnetActive = player._magnet && player._magnet > 0;
var superMagnetActive = player._superMagnetShot && player._superMagnetShot > 0;
if (magnetActive || superMagnetActive) {
var distToPlayer = Math.sqrt((p.x - player.x) * (p.x - player.x) + (p.y - player.y) * (p.y - player.y));
var pullRadius = superMagnetActive ? 800 : 400;
if (distToPlayer < pullRadius) {
// PowerUp oyuncuya doğru çekilsin
var pullSpeed = superMagnetActive ? 60 : 30;
var dx = player.x - p.x;
var dy = player.y - p.y;
var d = Math.sqrt(dx * dx + dy * dy);
if (d > 1) {
p.x += dx / d * pullSpeed;
p.y += dy / d * pullSpeed;
}
}
}
// PowerUp-PowerUp çarpışması: Birleşme
for (var j = i - 1; j >= 0; j--) {
var p2 = powerUps[j];
if (p !== p2 && p.intersects(p2)) {
// İki powerup birleşirse: PowerUpCombo oluştur
var combo = new PowerUpCombo();
combo.x = (p.x + p2.x) / 2;
combo.y = (p.y + p2.y) / 2;
combo.effects = [];
// Farklı efektleri ekle (tekrar yok)
if (p.effect && combo.effects.indexOf(p.effect) === -1) combo.effects.push(p.effect);
if (p2.effect && combo.effects.indexOf(p2.effect) === -1) combo.effects.push(p2.effect);
// Eğer p veya p2 zaten combo ise, efektlerini ekle
if (p.effects && Array.isArray(p.effects)) {
for (var ce = 0; ce < p.effects.length; ce++) {
if (combo.effects.indexOf(p.effects[ce]) === -1) combo.effects.push(p.effects[ce]);
}
}
if (p2.effects && Array.isArray(p2.effects)) {
for (var ce2 = 0; ce2 < p2.effects.length; ce2++) {
if (combo.effects.indexOf(p2.effects[ce2]) === -1) combo.effects.push(p2.effects[ce2]);
}
}
// Sınır: En fazla 3 efektli combo
if (combo.effects.length > 3) combo.effects = combo.effects.slice(0, 3);
powerUps.splice(i, 1);
powerUps.splice(j, 1);
p.destroy();
p2.destroy();
powerUps.push(combo);
game.addChild(combo);
// Combo birleşme popup
showArenaEventPopup("PowerUp Combo!");
break;
}
}
// Oyuncu ile çarpışma
if (player.intersects(p)) {
// PowerUp veya PowerUpCombo alındı
var effectsToApply = [];
if (p.effect) {
effectsToApply = [p.effect];
} else if (p.effects && Array.isArray(p.effects)) {
effectsToApply = p.effects.slice();
}
var popupMsg = [];
var comboRapid = false,
comboMagnet = false;
// --- PowerUp efektlerini uygula ---
for (var ef = 0; ef < effectsToApply.length; ef++) {
var effect = effectsToApply[ef];
if (effect === "rapid") {
// --- Attack Speed Bonus: Stackable ---
if (typeof player._attackSpeedBonus !== "number") player._attackSpeedBonus = 0;
player._attackSpeedBonus += 1;
powerActive = true;
powerTimer = 600;
popupMsg.push("RAPID FIRE! (10s)");
comboRapid = true;
} else if (effect === "triple") {
player._tripleShot = 600;
popupMsg.push("TRIPLE SHOT! (10s)");
} else if (effect === "shield") {
player._shield = 5;
popupMsg.push("Shield (5 hits)!");
} else if (effect === "heal") {
playerHealth = playerMaxHealth;
if (typeof player.health !== "undefined") player.health = playerHealth;
updateScoreAndLevel();
popupMsg.push("Full Health!");
} else if (effect === "wallBounce") {
player._wallBounce = 600;
popupMsg.push("WALL BOUNCE! (10s)");
} else if (effect === "reflect") {
player._reflect = 600;
popupMsg.push("REFLECT ENEMY BULLETS! (10s)");
} else if (effect === "slow") {
// Zaman yavaşlatma: tüm düşmanlar yavaşlar
for (var si = 0; si < enemies.length; si++) {
enemies[si]._frozen = 180; // 3 saniye yavaşlat
}
popupMsg.push("TIME SLOW! (3s)");
LK.effects.flashScreen(0x66ccff, 400);
} else if (effect === "magnet") {
// Magnet: yakındaki coin ve powerupları çek
comboMagnet = true;
popupMsg.push("MAGNET! (5s)");
player._magnet = 300; // 5 saniye
} else if (effect === "randomizer") {
// Randomizer: tüm düşmanların tipi değişir
for (var ri = 0; ri < enemies.length; ri++) {
var e = enemies[ri];
var t = Math.random();
var newE;
if (t < 0.4) newE = new Enemy();else if (t < 0.7) newE = new Enemy2();else newE = new Enemy3();
newE.x = e.x;
newE.y = e.y;
newE.maxHealth = e.maxHealth;
newE.health = e.health;
newE._frozen = e._frozen;
newE._healthBar = e._healthBar;
newE._visHealthBar = e._visHealthBar;
newE._visHealthBarBg = e._visHealthBarBg;
newE._visHealthBarFg = e._visHealthBarFg;
enemies[ri].destroy();
enemies[ri] = newE;
game.addChild(newE);
}
popupMsg.push("RANDOMIZER! (All enemies changed)");
LK.effects.flashScreen(0x00ffcc, 400);
} else if (effect === "superHeal") {
// Süper can: hem canı doldur hem max canı 2 artır
playerMaxHealth += 2;
playerHealth = playerMaxHealth;
if (typeof player.maxHealth !== "undefined") player.maxHealth = playerMaxHealth;
if (typeof player.health !== "undefined") player.health = playerHealth;
updateScoreAndLevel();
popupMsg.push("SUPER HEAL! (+2 Max Health)");
} else if (effect === "freezeBullets") {
// Freeze all enemy bullets for 3 seconds
for (var bi = 0; bi < enemyBullets.length; bi++) {
enemyBullets[bi]._frozen = 180;
}
popupMsg.push("FREEZE ENEMY BULLETS! (3s)");
LK.effects.flashScreen(0x00eaff, 400);
} else if (effect === "coinRain") {
// Spawn 10 coins at random locations
for (var ci = 0; ci < 10; ci++) {
spawnCoin();
}
popupMsg.push("COIN RAIN!");
LK.effects.flashScreen(0xffd700, 400);
} else if (effect === "enemyClear") {
// Destroy all enemies on screen
for (var ei = enemies.length - 1; ei >= 0; ei--) {
if (enemies[ei]._healthBar) enemies[ei]._healthBar.destroy();
if (enemies[ei]._visHealthBar) enemies[ei]._visHealthBar.destroy();
enemies[ei].destroy();
enemies.splice(ei, 1);
}
popupMsg.push("ENEMY CLEAR!");
LK.effects.flashScreen(0xff4444, 600);
} else if (effect === "scoreBoost") {
// 2x skor için 15 saniye
player._scoreBoost = 900;
popupMsg.push("SCORE BOOST! (15s)");
}
}
// --- PowerUp Kombinasyonları: Rapid + Magnet = Süper Çekim Ateşi ---
if (comboRapid && comboMagnet) {
player._superMagnetShot = 600; // 10 saniye süper çekim ateşi
popupMsg.push("SUPER MAGNET SHOT! (10s)");
LK.effects.flashScreen(0xff00ff, 600);
}
// --- PowerUp efektleri bitti ---
LK.effects.flashObject(player, 0x00ffcc, 400);
showArenaEventPopup("PowerUp: " + popupMsg.join(" + "));
p.destroy();
powerUps.splice(i, 1);
} else if (isOutOfBounds(p)) {
p.destroy();
powerUps.splice(i, 1);
}
}
// Coin update ve toplama
for (var i = coins.length - 1; i >= 0; i--) {
var c = coins[i];
// Skip update if coin is destroyed or out of bounds
if (!c || typeof c.destroyed !== "undefined" && c.destroyed) {
coins.splice(i, 1);
continue;
}
if (isOutOfBounds(c)) {
c.destroy();
coins.splice(i, 1);
continue;
}
c.update();
// Magnet veya Super Magnet aktifse, coinleri çek
var magnetActive = player._magnet && player._magnet > 0;
var superMagnetActive = player._superMagnetShot && player._superMagnetShot > 0;
if (magnetActive || superMagnetActive) {
var distToPlayer = Math.sqrt((c.x - player.x) * (c.x - player.x) + (c.y - player.y) * (c.y - player.y));
var pullRadius = superMagnetActive ? 800 : 400;
if (distToPlayer < pullRadius) {
// Coin oyuncuya doğru çekilsin
var pullSpeed = superMagnetActive ? 60 : 30;
var dx = player.x - c.x;
var dy = player.y - c.y;
var d = Math.sqrt(dx * dx + dy * dy);
if (d > 1) {
c.x += dx / d * pullSpeed;
c.y += dy / d * pullSpeed;
}
}
}
if (player.intersects(c)) {
coinCount++;
coinTxt.setText('₵ ' + coinCount);
// COIN: Save permanently
storage.coins = coinCount;
LK.effects.flashObject(player, 0xFFD700, 200);
// Fun popup: First coin
if (coinCount === 1) {
showArenaEventPopup("First Coin Collected!");
LK.effects.flashScreen(0xffd700, 300);
}
c.destroy();
coins.splice(i, 1);
} else if (isOutOfBounds(c)) {
c.destroy();
coins.splice(i, 1);
}
}
// PowerUp etkisi süresi
if (powerActive) {
powerTimer--;
if (powerTimer <= 0) {
powerActive = false;
// --- Attack Speed Bonus: Remove one stack when rapid fire ends ---
if (typeof player._attackSpeedBonus === "number" && player._attackSpeedBonus > 0) {
player._attackSpeedBonus -= 1;
if (player._attackSpeedBonus < 0) player._attackSpeedBonus = 0;
}
}
}
// Triple shot süresi azalt
if (player._tripleShot && player._tripleShot > 0) {
player._tripleShot--;
if (player._tripleShot <= 0) player._tripleShot = 0;
}
// Wall bounce süresi azalt
if (player._wallBounce && player._wallBounce > 0) {
player._wallBounce--;
if (player._wallBounce <= 0) player._wallBounce = 0;
}
// Reflect süresi azalt
if (player._reflect && player._reflect > 0) {
player._reflect--;
if (player._reflect <= 0) player._reflect = 0;
}
// Magnet süresi azalt
if (player._magnet && player._magnet > 0) {
player._magnet--;
if (player._magnet <= 0) player._magnet = 0;
}
// Super Magnet Shot süresi azalt
if (player._superMagnetShot && player._superMagnetShot > 0) {
player._superMagnetShot--;
if (player._superMagnetShot <= 0) player._superMagnetShot = 0;
}
// Score Boost süresi azalt
if (player._scoreBoost && player._scoreBoost > 0) {
player._scoreBoost--;
if (player._scoreBoost <= 0) player._scoreBoost = 0;
}
// Freeze enemy bullets süresi azalt
for (var bi = 0; bi < enemyBullets.length; bi++) {
if (enemyBullets[bi]._frozen && enemyBullets[bi]._frozen > 0) {
enemyBullets[bi]._frozen--;
// Dondurulmuşsa hareket etmesin
enemyBullets[bi].vx = 0;
enemyBullets[bi].vy = 0;
}
}
// PowerUp spawn (her 6 saniyede bir)
if (gameTick % 360 === 0) {
spawnPowerUp();
}
// COIN: Sık sık rastgele coin spawn et (her 60 frame'de bir, %60 olasılıkla)
if (gameTick % 60 === 0) {
if (Math.random() < 0.6) {
spawnCoin();
}
}
// Düşman spawn
// --- Düşmanlar çok çıksın: skor arttıkça daha sık spawn ---
// spawnInterval: skor arttıkça daha hızlı (min 8 frame)
var spawnInterval = Math.max(60 - level * 2 - Math.floor(score / 10), 8);
// Aynı anda birden fazla düşman spawn: skor arttıkça daha fazla
var enemySpawnCount = 1 + Math.floor(score / 30);
if (gameTick % spawnInterval === 0) {
for (var s = 0; s < enemySpawnCount; s++) {
spawnEnemy();
}
}
};
// Sürükleme başlat
game.down = function (x, y, obj) {
// If player is tapped, start dragging
var px = player.x,
py = player.y;
var dx = x - px,
dy = y - py;
var dist = Math.sqrt(dx * dx + dy * dy);
// User-friendly: If tapped on player, start dragging, otherwise do nothing
if (dist < player.radius + 80) {
// wider area, easier drag
dragNode = player;
lastPlayerPos.x = x;
lastPlayerPos.y = y;
// When drag starts, don't fire, prevent accidental fire
// Drag threshold: set a flag to check if drag distance exceeds a threshold before firing
dragNode._dragStarted = false;
dragNode._dragStartX = x;
dragNode._dragStartY = y;
dragNode._dragStartTime = Date.now();
} else {
// (Removed: tap-to-shoot code is now gone)
}
};
// Sürükleme bırak
game.up = function (x, y, obj) {
if (dragNode && typeof dragNode._dragStarted !== "undefined") {
// If drag didn't start and released quickly, fire (tap-to-shoot)
var dragDx = x - dragNode._dragStartX;
var dragDy = y - dragNode._dragStartY;
var dragDist = Math.sqrt(dragDx * dragDx + dragDy * dragDy);
var dragTime = Date.now() - (dragNode._dragStartTime || 0);
if (!dragNode._dragStarted && dragDist < 24 && dragTime < 200) {
spawnPlayerBullet(player.x, player.y, x, y);
LK.getSound('shoot').play();
}
dragNode._dragStarted = false;
dragNode._dragStartX = 0;
dragNode._dragStartY = 0;
dragNode._dragStartTime = 0;
}
dragNode = null;
// User-friendly: Update last position when drag is released
lastPlayerPos.x = 0;
lastPlayerPos.y = 0;
};
// Sürükleme hareketi: Oyuncu mouse ile birlikte hareket etsin
game.move = function (x, y, obj) {
// Oyuncu mouse ile birlikte hareket etsin
if (player) {
// Kullanıcı dostu: Oyuncunun ekran dışına çıkmasını engelle
var minX = player.radius + 20;
var maxX = 2048 - player.radius - 20;
var minY = player.radius + 20;
var maxY = 2732 - player.radius - 20;
player.x = x;
player.y = y;
if (player.x < minX) player.x = minX;
if (player.x > maxX) player.x = maxX;
if (player.y < minY) player.y = minY;
if (player.y > maxY) player.y = maxY;
}
};
// At game start, reset score, level, and health
score = 0;
level = 1;
playerHealth = playerMaxHealth;
// --- STATISTICS: Persistent High Score, Max Combo, Total Enemies Killed ---
storage.highScore = typeof storage.highScore === "number" ? storage.highScore : 0;
storage.maxCombo = typeof storage.maxCombo === "number" ? storage.maxCombo : 0;
storage.totalEnemiesKilled = typeof storage.totalEnemiesKilled === "number" ? storage.totalEnemiesKilled : 0;
// COIN: Load persistent coin count
coinCount = typeof storage.coins === "number" ? storage.coins : 0;
if (typeof coinTxt !== "undefined" && coinTxt._lastCoinCount !== coinCount) {
coinTxt.setText('₵ ' + coinCount);
coinTxt._lastCoinCount = coinCount;
}
if (typeof player !== "undefined") {
if (typeof player.maxHealth !== "undefined") player.maxHealth = playerMaxHealth;
if (typeof player.health !== "undefined") player.health = playerHealth;
}
// --- STATISTICS GUI ---
// Oyuncuya istatistikleri gösteren panel (sol üstte, büyük ve kolay okunur, menü ikonundan uzak)
var statsPanel = new Container();
LK.gui.topLeft.addChild(statsPanel);
// Sol üstte, menü ikonundan uzak durmak için 110px sağa ve 10px aşağıya kaydır
statsPanel.x = 110;
statsPanel.y = 10;
// High Score
var statsHighScoreTxt = new Text2('High Score: ' + storage.highScore, {
size: 48,
fill: 0xFFD700,
font: "Impact"
});
statsHighScoreTxt.anchor.set(0, 0);
statsHighScoreTxt.x = 0;
statsHighScoreTxt.y = 0;
statsPanel.addChild(statsHighScoreTxt);
// Max Combo
var statsMaxComboTxt = new Text2('Max Combo: ' + storage.maxCombo, {
size: 48,
fill: 0xFFFA00,
font: "Impact"
});
statsMaxComboTxt.anchor.set(0, 0);
statsMaxComboTxt.x = 0;
statsMaxComboTxt.y = 60;
statsPanel.addChild(statsMaxComboTxt);
// Total Enemies Killed
var statsEnemiesKilledTxt = new Text2('Enemies Killed: ' + storage.totalEnemiesKilled, {
size: 48,
fill: 0xFF4444,
font: "Impact"
});
statsEnemiesKilledTxt.anchor.set(0, 0);
statsEnemiesKilledTxt.x = 0;
statsEnemiesKilledTxt.y = 120;
statsPanel.addChild(statsEnemiesKilledTxt);
// Paneli güncelleyen fonksiyon
function updateStatsPanel() {
if (typeof statsHighScoreTxt !== "undefined") statsHighScoreTxt.setText('High Score: ' + storage.highScore);
if (typeof statsMaxComboTxt !== "undefined") statsMaxComboTxt.setText('Max Combo: ' + storage.maxCombo);
if (typeof statsEnemiesKilledTxt !== "undefined") statsEnemiesKilledTxt.setText('Enemies Killed: ' + storage.totalEnemiesKilled);
}
updateStatsPanel();
// --- NEW: Random PowerUp Shop Button ---
// Spend 30 coins to get a random powerup effect
var randomPowerBtn = new Text2('Random PowerUp (30₵)', {
size: 60,
fill: 0x00BFFF,
// Bright blue for high visibility
font: "Impact"
});
randomPowerBtn.anchor.set(0.5, 0);
LK.gui.top.addChild(randomPowerBtn);
randomPowerBtn.y = 420;
randomPowerBtn.interactive = true;
randomPowerBtn.buttonMode = true;
randomPowerBtn.visible = true;
randomPowerBtn.down = function (x, y, obj) {
if (coinCount >= 30) {
coinCount -= 30;
storage.coins = coinCount;
if (typeof coinTxt !== "undefined") coinTxt.setText('₵ ' + coinCount);
// Pick a random effect
var effects = ["rapid", "triple", "heal", "wallBounce", "reflect", "shield", "slow", "magnet", "superHeal", "freezeBullets", "coinRain", "enemyClear", "scoreBoost"];
var effect = effects[Math.floor(Math.random() * effects.length)];
var popupMsg = "";
if (effect === "rapid") {
// --- Attack Speed Bonus: Stackable ---
if (typeof player._attackSpeedBonus !== "number") player._attackSpeedBonus = 0;
player._attackSpeedBonus += 1;
powerActive = true;
powerTimer = 600;
popupMsg = "RAPID FIRE! (10s)";
} else if (effect === "triple") {
player._tripleShot = 600;
popupMsg = "TRIPLE SHOT! (10s)";
} else if (effect === "heal") {
playerHealth = playerMaxHealth;
if (typeof player.health !== "undefined") player.health = playerHealth;
updateScoreAndLevel();
popupMsg = "Full Health!";
} else if (effect === "wallBounce") {
player._wallBounce = 600;
popupMsg = "WALL BOUNCE! (10s)";
} else if (effect === "reflect") {
player._reflect = 600;
popupMsg = "REFLECT ENEMY BULLETS! (10s)";
} else if (effect === "shield") {
player._shield = 5;
popupMsg = "Shield (5 hits)!";
} else if (effect === "slow") {
for (var si = 0; si < enemies.length; si++) {
enemies[si]._frozen = 180;
}
popupMsg = "TIME SLOW! (3s)";
LK.effects.flashScreen(0x66ccff, 400);
} else if (effect === "magnet") {
player._magnet = 300;
popupMsg = "MAGNET! (5s)";
} else if (effect === "superHeal") {
playerMaxHealth += 2;
playerHealth = playerMaxHealth;
if (typeof player.maxHealth !== "undefined") player.maxHealth = playerMaxHealth;
if (typeof player.health !== "undefined") player.health = playerHealth;
updateScoreAndLevel();
popupMsg = "SUPER HEAL! (+2 Max Health)";
} else if (effect === "freezeBullets") {
for (var bi = 0; bi < enemyBullets.length; bi++) {
enemyBullets[bi]._frozen = 180;
}
popupMsg = "FREEZE ENEMY BULLETS! (3s)";
LK.effects.flashScreen(0x00eaff, 400);
} else if (effect === "coinRain") {
for (var ci = 0; ci < 10; ci++) {
spawnCoin();
}
popupMsg = "COIN RAIN!";
LK.effects.flashScreen(0xffd700, 400);
} else if (effect === "enemyClear") {
for (var ei = enemies.length - 1; ei >= 0; ei--) {
if (enemies[ei]._healthBar) enemies[ei]._healthBar.destroy();
if (enemies[ei]._visHealthBar) enemies[ei]._visHealthBar.destroy();
enemies[ei].destroy();
enemies.splice(ei, 1);
}
popupMsg = "ENEMY CLEAR!";
LK.effects.flashScreen(0xff4444, 600);
} else if (effect === "scoreBoost") {
player._scoreBoost = 900;
popupMsg = "SCORE BOOST! (15s)";
}
LK.effects.flashObject(player, 0xFFD700, 400); // Coin color flash
showArenaEventPopup("PowerUp: " + popupMsg);
} else {
showArenaEventPopup("Not enough coins!");
}
};
// --- NEW: Random Permanent Ultra Power Button (red) ---
var ultraPowerBtn = new Text2('Random ULTRA Power (100₵)', {
size: 60,
fill: 0xFF2222,
// Red
font: "Impact"
});
ultraPowerBtn.anchor.set(0.5, 0);
LK.gui.top.addChild(ultraPowerBtn);
ultraPowerBtn.y = randomPowerBtn.y + 90;
ultraPowerBtn.interactive = true;
ultraPowerBtn.buttonMode = true;
ultraPowerBtn.visible = true;
// --- NEW: Permanent Upgrade Shop (bottom left) ---
var permUpgradeBtn = new Text2('+1 Max Health (250₵)', {
size: 60,
fill: 0x00ff88,
font: "Impact"
});
permUpgradeBtn.anchor.set(0, 1); // bottom left
LK.gui.bottomLeft.addChild(permUpgradeBtn);
permUpgradeBtn.y = 0;
permUpgradeBtn.x = 0;
permUpgradeBtn.interactive = true;
permUpgradeBtn.buttonMode = true;
permUpgradeBtn.visible = true;
// --- NEW: Permanent Max Attack Upgrade Button (bottom right, above health) ---
var permAttackUpgradeBtn = new Text2('+1 Max Attack (250₵)', {
size: 60,
fill: 0xff8800,
font: "Impact"
});
permAttackUpgradeBtn.anchor.set(1, 1);
LK.gui.bottomRight.addChild(permAttackUpgradeBtn);
permAttackUpgradeBtn.y = permUpgradeBtn.y - 90;
permAttackUpgradeBtn.x = 0;
permAttackUpgradeBtn.interactive = true;
permAttackUpgradeBtn.buttonMode = true;
permAttackUpgradeBtn.visible = true;
// Show current permanent upgrades (bottom left, above button)
var permUpgradeInfoTxt = new Text2('', {
size: 48,
fill: 0xffffff,
font: "Impact"
});
permUpgradeInfoTxt.anchor.set(0, 1); // bottom left
LK.gui.bottomLeft.addChild(permUpgradeInfoTxt);
permUpgradeInfoTxt.y = permUpgradeBtn.y + 80;
permUpgradeInfoTxt.x = 0;
// Show current permanent attack upgrades (bottom right, above attack button)
var permAttackUpgradeInfoTxt = new Text2('', {
size: 48,
fill: 0xff8800,
font: "Impact"
});
permAttackUpgradeInfoTxt.anchor.set(1, 1);
LK.gui.bottomRight.addChild(permAttackUpgradeInfoTxt);
permAttackUpgradeInfoTxt.y = permAttackUpgradeBtn.y + 80;
permAttackUpgradeInfoTxt.x = 0;
// Helper to update permanent upgrade info
function updatePermUpgradeInfo() {
var healthUp = typeof storage.permMaxHealthUp === "number" ? storage.permMaxHealthUp : 0;
if (healthUp > 0) {
// If maxed (let's say 10 is max), show MAXED and use green color, add background
if (healthUp >= 10) {
permUpgradeInfoTxt.setText("Max Health +" + healthUp + " (MAXED, permanent)");
permUpgradeInfoTxt.fill = 0x00ff00;
permUpgradeInfoTxt.size = 36;
permUpgradeInfoTxt.background = {
color: 0x222222,
alpha: 0.95,
padding: 18,
radius: 18
};
} else {
permUpgradeInfoTxt.setText("Max Health +" + healthUp + " (permanent)");
permUpgradeInfoTxt.fill = 0xffffff;
permUpgradeInfoTxt.size = 36;
permUpgradeInfoTxt.background = {
color: 0x222222,
alpha: 0.8,
padding: 12,
radius: 12
};
}
permUpgradeInfoTxt.visible = true;
} else {
permUpgradeInfoTxt.setText("");
permUpgradeInfoTxt.visible = false;
permUpgradeInfoTxt.background = undefined;
}
var attackUp = typeof storage.permMaxAttackUp === "number" ? storage.permMaxAttackUp : 0;
if (attackUp > 0) {
// If maxed (let's say 10 is max), show MAXED and use orange color, add background
if (attackUp >= 10) {
permAttackUpgradeInfoTxt.setText("Max Attack +" + attackUp + " (MAXED, permanent)");
permAttackUpgradeInfoTxt.fill = 0xff8800;
permAttackUpgradeInfoTxt.size = 36;
permAttackUpgradeInfoTxt.background = {
color: 0x222222,
alpha: 0.95,
padding: 18,
radius: 18
};
} else {
permAttackUpgradeInfoTxt.setText("Max Attack +" + attackUp + " (permanent)");
permAttackUpgradeInfoTxt.fill = 0xff8800;
permAttackUpgradeInfoTxt.size = 36;
permAttackUpgradeInfoTxt.background = {
color: 0x222222,
alpha: 0.8,
padding: 12,
radius: 12
};
}
permAttackUpgradeInfoTxt.visible = true;
} else {
permAttackUpgradeInfoTxt.setText("");
permAttackUpgradeInfoTxt.visible = false;
permAttackUpgradeInfoTxt.background = undefined;
}
}
updatePermUpgradeInfo();
permUpgradeBtn.down = function (x, y, obj) {
// Always update coinCount from storage before checking
coinCount = typeof storage.coins === "number" ? storage.coins : coinCount;
var healthUp = typeof storage.permMaxHealthUp === "number" ? storage.permMaxHealthUp : 0;
if (coinCount >= 250) {
coinCount -= 250;
storage.coins = coinCount;
if (typeof coinTxt !== "undefined") coinTxt.setText('₵ ' + coinCount);
// Increase permanent max health
healthUp++;
storage.permMaxHealthUp = healthUp;
updatePermUpgradeInfo();
LK.effects.flashScreen(0x00ff88, 400);
// Apply immediately to player
playerMaxHealth = 10 + healthUp;
playerHealth = playerMaxHealth;
if (typeof player !== "undefined") {
if (typeof player.maxHealth !== "undefined") player.maxHealth = playerMaxHealth;
if (typeof player.health !== "undefined") player.health = playerHealth;
}
updateScoreAndLevel();
} else {
showArenaEventPopup("Not enough coins!");
}
};
// Permanent Max Attack Upgrade Button logic
permAttackUpgradeBtn.down = function (x, y, obj) {
coinCount = typeof storage.coins === "number" ? storage.coins : coinCount;
var attackUp = typeof storage.permMaxAttackUp === "number" ? storage.permMaxAttackUp : 0;
if (coinCount >= 250) {
coinCount -= 250;
storage.coins = coinCount;
if (typeof coinTxt !== "undefined") coinTxt.setText('₵ ' + coinCount);
// Increase permanent max attack
attackUp++;
storage.permMaxAttackUp = attackUp;
updatePermUpgradeInfo();
LK.effects.flashScreen(0xff8800, 400);
// Apply immediately to player (if you want, e.g. set player._permAttackUp = attackUp)
if (typeof player !== "undefined") {
player._permAttackUp = attackUp;
}
} else {
showArenaEventPopup("Not enough coins!");
}
};
// --- ULTRA POWER EFFECT TEXT (top-right, red, bold) ---
var ultraPowerEffectTxt = new Text2('', {
size: 60,
fill: 0xFF2222,
font: "Impact",
fontWeight: "bold"
});
ultraPowerEffectTxt.anchor.set(1, 0); // right-top
LK.gui.topRight.addChild(ultraPowerEffectTxt);
ultraPowerEffectTxt.y = 0;
ultraPowerEffectTxt.x = 0; // LK.gui.topRight is already at the right edge
// Helper to set ultra power effect text
var ultraPowerEffectTimeout = null;
function setUltraPowerEffectText(txt) {
if (typeof ultraPowerEffectTxt !== "undefined" && ultraPowerEffectTxt && typeof ultraPowerEffectTxt.setText === "function") {
ultraPowerEffectTxt.setText(txt || '');
ultraPowerEffectTxt.visible = !!txt;
// Hide after 2.5 seconds if text is set
if (ultraPowerEffectTimeout) {
LK.clearTimeout(ultraPowerEffectTimeout);
ultraPowerEffectTimeout = null;
}
if (txt) {
ultraPowerEffectTimeout = LK.setTimeout(function () {
ultraPowerEffectTxt.setText('');
ultraPowerEffectTxt.visible = false;
ultraPowerEffectTimeout = null;
}, 5000);
}
}
}
// On game start, clear ultra power effect text
setUltraPowerEffectText('');
// Track the current ultra power effect
var currentUltraPowerEffect = "";
// Update the text when ultra power is bought
ultraPowerBtn.down = function (x, y, obj) {
// Always update coinCount from storage before checking
coinCount = typeof storage.coins === "number" ? storage.coins : coinCount;
if (coinCount >= 100) {
coinCount -= 100;
storage.coins = coinCount;
if (typeof coinTxt !== "undefined") coinTxt.setText('₵ ' + coinCount);
// Pick a random ultra-strong permanent effect
var ultraEffects = ["superScoreBoost", "permaTriple", "permaRapid", "permaWallBounce", "permaReflect"];
var effect = ultraEffects[Math.floor(Math.random() * ultraEffects.length)];
var popupMsg = "";
var effectLabel = "";
if (effect === "superScoreBoost") {
player._superScoreBoost = true;
player._scoreBoost = 1;
popupMsg = "PERMANENT: 10x Score!";
effectLabel = "10x Score!";
} else if (effect === "permaTriple") {
player._tripleShot = 999999;
popupMsg = "PERMANENT: Triple Shot!";
effectLabel = "Triple Shot!";
} else if (effect === "permaRapid") {
// --- Attack Speed Bonus: Permanent ---
if (typeof player._attackSpeedBonus !== "number") player._attackSpeedBonus = 0;
player._attackSpeedBonus += 5; // Permanent big bonus
powerActive = true;
powerTimer = 999999;
popupMsg = "PERMANENT: Rapid Fire!";
effectLabel = "Rapid Fire!";
} else if (effect === "permaWallBounce") {
player._wallBounce = 999999;
popupMsg = "PERMANENT: Wall Bounce!";
effectLabel = "Wall Bounce!";
} else if (effect === "permaReflect") {
player._reflect = 999999;
popupMsg = "PERMANENT: Reflect!";
effectLabel = "Reflect!";
}
LK.effects.flashObject(player, 0xFF2222, 600);
showArenaEventPopup("ULTRA Power: " + popupMsg);
// Show effect label at top-right
currentUltraPowerEffect = effectLabel;
setUltraPowerEffectText(effectLabel);
} else {
showArenaEventPopup("Not enough coins!");
}
};
powerup. In-Game asset. 2d. High contrast. No shadows
robot enemy. In-Game asset. 2d. High contrast. No shadows
green robot enemy. In-Game asset. 2d. High contrast. No shadows
purple robot enemy. In-Game asset. 2d. High contrast. No shadows
player robot. In-Game asset. 2d. High contrast. No shadows
robot ammo. In-Game asset. 2d. High contrast. No shadows
coin. In-Game asset. 2d. High contrast. No shadows
robot ammo very red very big. In-Game asset. 2d. High contrast. No shadows
2d space bg. In-Game asset. 2d. High contrast. No shadows