User prompt
oyuncuya can ekle
User prompt
bu şekilde değil daha güçlü powerup özellikleri ekle oyunucuyu çok güçlü yapmalı
User prompt
powerupa en az 50 farklı özellik ekle bunların çalışanları kalsın çalışmayanı ekleme
User prompt
ekrana çıkan yazıları biraz küçült
User prompt
bir hata var düşmana görsel olarak eklenen can düşman ölünce ekranda kalıyor
User prompt
düşmanlara özellik ekle ve düşmanlara can ekle
User prompt
powerup lardan ne aldığımızı yaz daha fazla powerup özelliği ekle ve daha eğlenceli bir oyun yap
User prompt
Please fix the bug: 'TypeError: tween.to is not a function' in or related to this line: 'tween.to(eventPopupTxt, {' Line Number: 286 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'TypeError: tween.to is not a function' in or related to this line: 'tween.to(eventPopupTxt, {' Line Number: 286
User prompt
eğlenceli bir oyun yap
User prompt
oyun sonsuz olsun
User prompt
powerı assete de ekle
User prompt
can barı ekle
User prompt
power ekle
User prompt
kullanıcı dosttu olsun profesyonel ol
User prompt
kontroller kullanıcı dostu olsun
User prompt
otamatik ateş etsin oyuncu
User prompt
oyuncu haraktet etmiyor
User prompt
haraktet etmiyor
Code edit (1 edits merged)
Please save this source code
User prompt
AI Arena: Yapay Zeka Savaşları
Initial prompt
yapay zekayla 2d oyun hakkında profesyonel fikir veren bir oyun yap
/**** * 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