User prompt
oyun boss sonrası ihtibariyle score arttıkça zorluk artar kesintisiz rakip gelmesi normal asker çıkması nadir olur daha tehlikeli rakipler
User prompt
lazer hep mausu takip etsşn basılı tutmak gerekmesin
User prompt
Please fix the bug: 'TypeError: Cannot read properties of null (reading 'x')' in or related to this line: 'var bdx = boss.x - CENTER_X;' Line Number: 518
User prompt
Please fix the bug: 'TypeError: storage.set is not a function' in or related to this line: 'storage.set('highScore', highScore);' Line Number: 569 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'storage.get is not a function' in or related to this line: 'var highScore = storage.get('highScore') || 0;' Line Number: 288 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
boss yenildikten sonra oyun devam etsin sonsuza dek en yüksek score yazsın skor tablosu
User prompt
müzik
User prompt
aksiyon dolu bir müzik
User prompt
👑 Boss Adı: Aetherion – Zihin Parçalayıcı 👤 Görünüm: Devasa, yarı saydam ve puslu bir figür. Gövdesi karanlık enerjiyle sarılı, içinden yıldız gibi parlayan noktalar akar. Başı sürekli sağa sola yavaşça döner, birden ışık patlamalarıyla sabitlenir. Etrafında dönen 4 mini kristal uydu gibi etrafında dolaşır (bunlar vurulabilir hedeflerdir). 🧠 Yetenekleri: Destek Bağlantısı – "Dört Bağ": Her kristal, sahadaki düşmanlara bağlanarak onları destekçi yapar. Bu bağlar vurulmadıkça bağlı düşmanlar ölümsüzdür. Oyuncu önce bu kristalleri lazerle vurmalı (her biri 3 saniye sürekli hasarla kırılır). Zihin Dalgası – "Dalga Patlaması": Her 10 saniyede bir, bulunduğu noktadan genişleyen mor bir halka salar. Bu halka lazer yönünü 2 saniyeliğine ters çevirir (kontrol karışır). Oyuncu bu dalgadan uzak durmalı veya zamanlamayı ezberlemeli. Işın Yön Saptırıcı: Lazerin boss’a isabet etmesini zorlaştırmak için, boss etrafında dönen bir enerji kalkanı vardır. Lazer bu kalkanla çarpıştığında yönü %15 sapar. Doğrudan vuruş zordur, oyuncu açıyı ayarlamak zorunda kalır. Kırmızı Takviye – “Karabüyü Yaratığı”: Boss %50 cana indiğinde, arenaya sadece bir kez özel bir yaratık çağırır: Işıkla değil sadece lazer dalgasıyla hasar alır. Oyuncu E ile aktif edilen lazer dalgayı doğru zamanlamada kullanmalı. ⚔️ Zayıf Noktası: Kristaller kırıldığında zırhı kalkar, bu sürede lazer tam güç vurur. Tüm yetenekleri iptal olur ve 10 saniye tamamen savunmasız kalır. 🎨 Özel Efektler: Kristaller yok olurken parçalanarak cam gibi dağılır. Boss öldüğünde tüm ekran 2 saniyeliğine parlayarak siyah beyaz olur, sonra normal renge döner. 🔥 Boss Dövüşü Stratejisi (Oyuncu İçin): Önce 4 kristali yok et. Işın dalgası geldiğinde yön değişimine dikkat et. Zihin dalgası zamanlarını ezberle. %50 cana indiğinde E tuşunu hazır tut. Tüm sistematik ilerleme ve doğru açı ile lazer yönlendirmesi ile boss’u yenebilirsin. bu boss çok yavaş olsun
User prompt
destekleyen sadece sıradanı destekleyebilir 2 destekleyen birbirini destekleyemez
User prompt
oyun 129da bitiyo bitmemeli
User prompt
500 score yapınca boss gelir artık sadece tek rakip gelir oda boss her vurunca farklı yönden gelir lazerden sağ sol kaçmaya çalıiır
User prompt
lazer mesafesi daha uzun
Code edit (1 edits merged)
Please save this source code
User prompt
Lazer Savunması: Büyücü Kuşatması
Initial prompt
Oyun Özeti - Tam Detaylı Karakter ve Kontrol: Oyuncu, ekranın tam ortasında sabit duran bir ana karakteri yönetir. Karakterin silahı, sürekli açık ve sınırsız menzile sahip bir lazer ışınıdır. Bu lazer, oyuncu tarafından ok tuşları (klavye) veya mobil cihazlarda basılı tutup sağa/sola kaydırarak döndürülür. Lazer sürekli ateş halindedir ve silahın kapatılıp açılması yoktur. Düşman Türleri ve Davranışları: Oyunda üç tür düşman vardır: Normal Düşmanlar (Turuncu): Karaktere doğru doğrudan ilerler. Arkaya geçmez, sadece ilerleyerek saldırmaya çalışır. Lazere Temas Etmiş Düşmanlar (Kırmızı): Normal düşmanlar lazerin ilk darbesiyle kırmızıya döner, ikinci lazer darbesinde silikleşerek 2 saniye içinde yok olur. Büyücüler (Mavi): En yakın normal düşmana destek verir. Büyücü ile desteklenen düşman arasında görünür bir çizgi vardır. Desteklenen düşman bu sayede ölmez, önce büyücü öldürülmelidir. Destekçi büyücü yok edilmeden desteklenen düşmana zarar verilemez. Lazer Etkisi ve Görsel Efektler: Lazer, düşmanlara temas ettiğinde onları yavaşlatır ve hasar verir. İki darbe sonrası düşmanlar silikleşerek yok olur. Silikleşme animasyonu 2 saniye sürer. Destekçilerin çizgisi, destek verdikleri düşmanı koruduklarını net şekilde gösterir. Oyun Amacı ve Strateji: Amaç, düşman dalgalarını lazerle temizlemek. Ancak destekçileri önce yok etmek gerekir; aksi halde desteklenen düşmanlar zarar görmez. Oyuncu lazer yönünü iyi kontrol ederek hem destekçileri hem normal düşmanları sırayla etkisiz hale getirmelidir. Kontroller: Lazer Yönü: Klavyede ok tuşlarıyla, mobilde basılı tutup kaydırarak. Sabit Konum: Karakter hareket etmez, sadece lazerin yönü değiştirilir. Ekstra Mekanikler: Düşmanlar karakterin arkasına geçemez, sadece doğrudan saldırır. Lazer her zaman açık ve otomatik ateş eder, oyuncu sadece yönünü ayarlar. Özet: Orta noktada sabit duran karakter, sürekli açık lazeri ok tuşları veya dokunmatik ile yönlendirerek farklı tür düşmanları (normal ve destekli büyücüler) yok etmeye çalışır. Büyücüler, en yakın düşmanı koruyup onları hasardan korur, bu yüzden önce büyücüyü yok etmek gereklidir. Lazer temasındaki düşmanlar kırmızıya dönüşür, ikinci darbe ile silikleşip 2 saniyede ölür. Amaç tüm düşmanları taktiksel olarak temizlemektir. İstersen daha kısa veya farklı tarzda da yapabilirim.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ // Boss enemy class var Boss = Container.expand(function () { var self = Container.call(this); self.isBoss = true; self.state = 0; // 0: alive, 1: fading self.bossAsset = self.attachAsset('enemy_shielded', { anchorX: 0.5, anchorY: 0.5 }); self.x = CENTER_X; self.y = CENTER_Y - 700; self.speed = 12; self.targetAngle = 0; self.moveTimer = 0; self.fadeTimer = 0; self.lastLaserHit = false; self.escapeDir = 1; // 1: right, -1: left // Set boss to a new random direction (left or right of laser) self.setNewDirection = function () { // Pick a side to escape: left or right of laser self.escapeDir = Math.random() < 0.5 ? 1 : -1; // Offset angle from laser self.targetAngle = laserAngle + Math.PI / 2 * self.escapeDir; // Clamp to [-PI, PI] if (self.targetAngle > Math.PI) self.targetAngle -= 2 * Math.PI; if (self.targetAngle < -Math.PI) self.targetAngle += 2 * Math.PI; // Set moveTimer for how long to move in this direction self.moveTimer = 30 + Math.floor(Math.random() * 30); }; self.setNewDirection(); self.update = function () { if (self.state === 1) { self.fadeTimer += 1; self.alpha = 1 - self.fadeTimer / 60; if (self.fadeTimer > 60) { self.destroy(); } return; } // Move away from laser direction var moveAngle = self.targetAngle; var moveDist = self.speed; self.x += Math.cos(moveAngle) * moveDist; self.y += Math.sin(moveAngle) * moveDist; // Clamp boss inside game area if (self.x < 200) self.x = 200; if (self.x > 1848) self.x = 1848; if (self.y < 200) self.y = 200; if (self.y > 2532) self.y = 2532; self.moveTimer -= 1; if (self.moveTimer <= 0) { self.setNewDirection(); } }; // Boss takes hit self.hitByLaser = function () { if (self.state === 0) { self.state = 1; self.fadeTimer = 0; LK.getSound('enemy_down').play(); } }; return self; }); // ENEMY STATES // 0: normal // 1: shielded (red) // 2: fading (about to die) var Enemy = Container.expand(function () { var self = Container.call(this); // Default: normal enemy self.state = 0; // 0: normal, 1: shielded, 2: fading self.isWizard = false; self.isProtected = false; // If protected by wizard self.protector = null; // Wizard protecting this enemy // Asset self.enemyAsset = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5 }); self.shieldAsset = null; // For shield effect // For movement self.speed = 2 + Math.random() * 1.5; // Slightly random speed self.angle = 0; // Will be set on spawn self.radius = 0; // Distance from center // For fade-out self.fadeTimer = 0; // For collision self.lastLaserHit = false; // For wizard self.isWizard = false; self.shieldedEnemy = null; // For wizard: the enemy it protects // Set state (change color/asset) self.setState = function (state) { self.state = state; if (self.isWizard) { // Always wizard asset if (self.enemyAsset) self.enemyAsset.destroy(); self.enemyAsset = self.attachAsset('wizard', { anchorX: 0.5, anchorY: 0.5 }); } else if (state === 0) { if (self.enemyAsset) self.enemyAsset.destroy(); self.enemyAsset = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5 }); } else if (state === 1) { if (self.enemyAsset) self.enemyAsset.destroy(); self.enemyAsset = self.attachAsset('enemy_shielded', { anchorX: 0.5, anchorY: 0.5 }); } else if (state === 2) { if (self.enemyAsset) self.enemyAsset.destroy(); self.enemyAsset = self.attachAsset('enemy_fading', { anchorX: 0.5, anchorY: 0.5 }); } }; // Show/hide shield self.setShield = function (on) { if (on && !self.shieldAsset) { self.shieldAsset = self.attachAsset('shield', { anchorX: 0.5, anchorY: 0.5 }); self.shieldAsset.alpha = 0.35; } else if (!on && self.shieldAsset) { self.shieldAsset.destroy(); self.shieldAsset = null; } }; // Called every tick self.update = function () { // Move towards center var dx = 1024 - self.x; var dy = 1366 - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { var moveDist = Math.min(self.speed, dist); self.x += dx / dist * moveDist; self.y += dy / dist * moveDist; } // Fading out if (self.state === 2) { self.fadeTimer += 1; if (self.fadeTimer > 30) { // Remove after fade self.destroy(); } else { self.alpha = 1 - self.fadeTimer / 30; } } }; // For wizard: assign protected enemy self.setShieldedEnemy = function (enemy) { self.shieldedEnemy = enemy; if (enemy) { enemy.isProtected = true; enemy.protector = self; enemy.setShield(true); } }; // For wizard: remove shield from protected enemy self.removeShieldedEnemy = function () { if (self.shieldedEnemy) { self.shieldedEnemy.isProtected = false; self.shieldedEnemy.protector = null; self.shieldedEnemy.setShield(false); self.shieldedEnemy = null; } }; // For protected enemy: called if wizard dies self.removeProtection = function () { self.isProtected = false; self.protector = null; self.setShield(false); }; return self; }); // --- Dangerous Enemy Types --- // Fast enemy: moves faster, dies in 1 hit, red color // Tank enemy: moves slow, takes 3 hits, purple color // Exploder enemy: explodes on death, orange color // Tank Enemy var TankEnemy = Enemy.expand(function () { var self = Enemy.call(this); self.tankHits = 0; // 0,1,2,3 (3rd is death) self.speed = 1.2 + Math.random() * 0.5; self.setState = function (state) { self.state = state; if (self.enemyAsset) self.enemyAsset.destroy(); if (self.tankHits === 0) { self.enemyAsset = self.attachAsset('enemy_tank', { anchorX: 0.5, anchorY: 0.5 }); } else if (self.tankHits === 1) { self.enemyAsset = self.attachAsset('enemy_tank_dmg1', { anchorX: 0.5, anchorY: 0.5 }); } else if (self.tankHits === 2) { self.enemyAsset = self.attachAsset('enemy_tank_dmg2', { anchorX: 0.5, anchorY: 0.5 }); } else { self.enemyAsset = self.attachAsset('enemy_fading', { anchorX: 0.5, anchorY: 0.5 }); } }; self.update = function () { var dx = 1024 - self.x; var dy = 1366 - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { var moveDist = Math.min(self.speed, dist); self.x += dx / dist * moveDist; self.y += dy / dist * moveDist; } if (self.state === 2) { self.fadeTimer += 1; if (self.fadeTimer > 40) { self.destroy(); } else { self.alpha = 1 - self.fadeTimer / 40; } } }; return self; }); // --- Dangerous Enemy Classes --- // Fast Enemy var FastEnemy = Enemy.expand(function () { var self = Enemy.call(this); self.speed = 5 + Math.random() * 2; self.setState = function (state) { self.state = state; if (self.enemyAsset) self.enemyAsset.destroy(); self.enemyAsset = self.attachAsset('enemy_fast', { anchorX: 0.5, anchorY: 0.5 }); }; // Only 1 hit to die self.update = function () { var dx = 1024 - self.x; var dy = 1366 - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { var moveDist = Math.min(self.speed, dist); self.x += dx / dist * moveDist; self.y += dy / dist * moveDist; } if (self.state === 2) { self.fadeTimer += 1; if (self.fadeTimer > 18) { self.destroy(); } else { self.alpha = 1 - self.fadeTimer / 18; } } }; return self; }); // Exploder Enemy var ExploderEnemy = Enemy.expand(function () { var self = Enemy.call(this); self.speed = 2.5 + Math.random() * 1.2; self.setState = function (state) { self.state = state; if (self.enemyAsset) self.enemyAsset.destroy(); self.enemyAsset = self.attachAsset('enemy_exploder', { anchorX: 0.5, anchorY: 0.5 }); }; self.update = function () { var dx = 1024 - self.x; var dy = 1366 - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { var moveDist = Math.min(self.speed, dist); self.x += dx / dist * moveDist; self.y += dy / dist * moveDist; } if (self.state === 2) { self.fadeTimer += 1; if (self.fadeTimer > 22) { self.destroy(); } else { self.alpha = 1 - self.fadeTimer / 22; } } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x181a1b }); /**** * Game Code ****/ // Exploder enemy: explodes on death, orange color // Tank enemy: moves slow, takes 3 hits, purple color // Fast enemy: moves faster, dies in 1 hit, red color // --- Dangerous Enemy Types --- // Center of screen // Main character (center) // Lazer beam (thin, long rectangle) // Enemy: normal // Enemy: shielded (first hit) // Enemy: fading (second hit) // Enemy: wizard // Shield effect (for protected enemies) // Sound for enemy destroyed var CENTER_X = 1024; var CENTER_Y = 1366; // Main character var hero = new Container(); var heroAsset = hero.attachAsset('hero', { anchorX: 0.5, anchorY: 0.5 }); hero.x = CENTER_X; hero.y = CENTER_Y; game.addChild(hero); // Laser var laser = new Container(); var laserAsset = laser.attachAsset('laser', { anchorX: 0.5, anchorY: 0 }); laser.x = CENTER_X; laser.y = CENTER_Y; laser.rotation = 0; game.addChild(laser); // Laser direction (in radians) var laserAngle = 0; // 0 = up var laserTargetAngle = 0; // For smooth tweening // Touch drag control // Remove dragging logic, always follow last touch/mouse position var lastPointer = { x: CENTER_X, y: CENTER_Y }; var enemies = []; var spawnWaveTimer = 0; var waveNumber = 1; // Boss var boss = null; var bossActive = false; var bossDefeated = false; // Score var score = 0; // Import storage plugin for persistent high score // Retrieve high score from storage, or 0 if not set var highScore = storage.highScore || 0; // Score text var scoreTxt = new Text2('0', { size: 120, fill: "#fff" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // High score text var highScoreTxt = new Text2('En Yüksek: ' + highScore, { size: 60, fill: 0xFFD700 }); highScoreTxt.anchor.set(0.5, 0); highScoreTxt.y = 110; // Place below the main score LK.gui.top.addChild(highScoreTxt); // Helper: spawn a single enemy at random angle/distance function spawnEnemy(type) { var enemy; if (type === 'wizard') { enemy = new Enemy(); enemy.isWizard = true; enemy.setState(0); } else if (type === 'fast') { enemy = new FastEnemy(); enemy.setState(0); } else if (type === 'tank') { enemy = new TankEnemy(); enemy.setState(0); } else if (type === 'exploder') { enemy = new ExploderEnemy(); enemy.setState(0); } else { enemy = new Enemy(); enemy.setState(0); } // Spawn at random angle, at edge of screen var angle = Math.random() * Math.PI * 2; var dist = 1200 + Math.random() * 400; enemy.x = CENTER_X + Math.cos(angle) * dist; enemy.y = CENTER_Y + Math.sin(angle) * dist; enemy.angle = angle; enemy.radius = dist; // Set speed for normal/wizard if (type === 'wizard') { enemy.speed = 2.5 + Math.random() * 1.2; } else if (type === 'normal') { enemy.speed = 2 + Math.random() * 1.5; } game.addChild(enemy); enemies.push(enemy); return enemy; } // Helper: assign wizards to protect nearest enemy function assignWizards() { // Get all wizards var wizards = []; var normalEnemies = []; for (var i = 0; i < enemies.length; ++i) { var e = enemies[i]; if (e.isWizard) wizards.push(e);else if (!e.isProtected) normalEnemies.push(e); } // For each wizard, find nearest unprotected normal enemy (not wizard, not protected, not fading) for (var j = 0; j < wizards.length; ++j) { var wiz = wizards[j]; // Remove old shield wiz.removeShieldedEnemy(); // Find nearest normal enemy (not wizard, not protected, not fading) var minDist = 99999; var nearest = null; for (var k = 0; k < enemies.length; ++k) { var e2 = enemies[k]; if (e2 === wiz) continue; if (e2.isWizard) continue; // Only shield normal enemies if (e2.isProtected) continue; if (e2.state === 2) continue; // Fading out var dx = wiz.x - e2.x; var dy = wiz.y - e2.y; var d = dx * dx + dy * dy; if (d < minDist) { minDist = d; nearest = e2; } } if (nearest) { wiz.setShieldedEnemy(nearest); } } } // Helper: spawn a wave of enemies function spawnWave() { // After boss is defeated, scale up difficulty and spawn more dangerous enemies var postBoss = bossDefeated && score >= 500; var baseEnemies = 3 + Math.floor(waveNumber * 0.7); var numEnemies = postBoss ? Math.floor(baseEnemies * (1.2 + (score - 500) / 1000)) : baseEnemies; var numWizards = postBoss ? Math.floor(numEnemies * 0.08) : Math.min(1 + Math.floor(waveNumber / 3), Math.floor(numEnemies / 3)); // Dangerous enemy ratios var fastRatio = postBoss ? Math.min(0.25 + (score - 500) / 2000, 0.45) : 0; var tankRatio = postBoss ? Math.min(0.18 + (score - 500) / 3000, 0.32) : 0; var exploderRatio = postBoss ? Math.min(0.12 + (score - 500) / 4000, 0.22) : 0; // Normal enemies become rare var normalRatio = 1 - (fastRatio + tankRatio + exploderRatio + numWizards / numEnemies); // Clamp if (normalRatio < 0.08) normalRatio = 0.08; // Build enemy type pool var pool = []; for (var i = 0; i < Math.floor(numEnemies * fastRatio); ++i) pool.push('fast'); for (var i = 0; i < Math.floor(numEnemies * tankRatio); ++i) pool.push('tank'); for (var i = 0; i < Math.floor(numEnemies * exploderRatio); ++i) pool.push('exploder'); for (var i = 0; i < Math.floor(numEnemies * normalRatio); ++i) pool.push('normal'); // Fill up to numEnemies while (pool.length < numEnemies) pool.push('normal'); // Shuffle pool for (var i = pool.length - 1; i > 0; --i) { var ri = Math.floor(Math.random() * (i + 1)); var tmp = pool[i]; pool[i] = pool[ri]; pool[ri] = tmp; } // Spawn wizards for (var i = 0; i < numWizards; ++i) { spawnEnemy('wizard'); } // Spawn from pool for (var j = 0; j < pool.length; ++j) { spawnEnemy(pool[j]); } assignWizards(); waveNumber += 1; } // Helper: check if a point is inside the laser beam function pointInLaser(px, py) { // Laser is a rectangle from (CENTER_X, CENTER_Y) in direction laserAngle, length = laserAsset.height var dx = px - CENTER_X; var dy = py - CENTER_Y; var len = Math.sqrt(dx * dx + dy * dy); if (len < 60) return false; // Don't hit at center var angleToPoint = Math.atan2(dy, dx); var diff = Math.abs(angleToPoint - laserAngle); // Normalize diff to [0, PI] while (diff > Math.PI) diff = Math.abs(diff - 2 * Math.PI); // If within 0.13 rad (~7.5 deg) of laser direction, and within laser length if (diff < 0.13 && len < laserAsset.height) { return true; } return false; } // Helper: remove enemy from array and game function removeEnemy(enemy) { // Remove shield if wizard if (enemy.isWizard) { enemy.removeShieldedEnemy(); } // Remove protection if protected if (enemy.isProtected && enemy.protector) { enemy.protector.removeShieldedEnemy(); } for (var i = enemies.length - 1; i >= 0; --i) { if (enemies[i] === enemy) { enemies.splice(i, 1); break; } } enemy.destroy(); } // Touch/drag controls game.down = function (x, y, obj) { // Ignore top left 100x100 for menu if (x < 100 && y < 100) return; // Always update last pointer position and angle lastPointer.x = x; lastPointer.y = y; var dx = x - CENTER_X; var dy = y - CENTER_Y; var angle = Math.atan2(dy, dx); if (angle > Math.PI) angle -= 2 * Math.PI; if (angle < -Math.PI) angle += 2 * Math.PI; laserTargetAngle = angle; }; game.move = function (x, y, obj) { // Always update last pointer position lastPointer.x = x; lastPointer.y = y; // Calculate angle from center to pointer var dx = x - CENTER_X; var dy = y - CENTER_Y; var angle = Math.atan2(dy, dx); // Clamp to [-PI, PI] if (angle > Math.PI) angle -= 2 * Math.PI; if (angle < -Math.PI) angle += 2 * Math.PI; laserTargetAngle = angle; }; game.up = function (x, y, obj) { // No drag state to reset, but update pointer and angle for consistency lastPointer.x = x; lastPointer.y = y; var dx = x - CENTER_X; var dy = y - CENTER_Y; var angle = Math.atan2(dy, dx); if (angle > Math.PI) angle -= 2 * Math.PI; if (angle < -Math.PI) angle += 2 * Math.PI; laserTargetAngle = angle; }; // Main update loop game.update = function () { // Smoothly rotate laser towards target angle var diff = laserTargetAngle - laserAngle; while (diff > Math.PI) diff -= 2 * Math.PI; while (diff < -Math.PI) diff += 2 * Math.PI; laserAngle += diff * 0.18; // Smooth // Clamp if (laserAngle > Math.PI) laserAngle -= 2 * Math.PI; if (laserAngle < -Math.PI) laserAngle += 2 * Math.PI; laser.rotation = laserAngle - Math.PI / 2; // Because asset is vertical // Boss phase logic if (!bossActive && score >= 500 && !bossDefeated) { // Remove all enemies for (var i = enemies.length - 1; i >= 0; --i) { enemies[i].destroy(); } enemies = []; // Spawn boss boss = new Boss(); boss.x = CENTER_X; boss.y = CENTER_Y - 700; game.addChild(boss); bossActive = true; } if (bossActive && boss && !bossDefeated) { boss.update(); // Boss collision with laser if (boss.state === 0 && pointInLaser(boss.x, boss.y)) { boss.hitByLaser(); score += 20; scoreTxt.setText(score); // Update high score if needed if (score > highScore) { highScore = score; storage.highScore = highScore; highScoreTxt.setText('En Yüksek: ' + highScore); } } // Remove boss if faded out if (boss.state === 1 && boss.fadeTimer > 60) { boss.destroy(); boss = null; bossActive = false; bossDefeated = true; // No win popup, continue game // Resume spawning waves waveNumber += 1; spawnWaveTimer = 0; // Optionally, you can spawn a new wave immediately or let the normal wave logic handle it // spawnWave(); // No return here, let the game continue } // Boss game over if reaches center if (boss) { var bdx = boss.x - CENTER_X; var bdy = boss.y - CENTER_Y; var bdist = Math.sqrt(bdx * bdx + bdy * bdy); if (bdist < 120 && boss.state === 0) { LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); return; } } return; // Only boss is active, skip rest } // Update all enemies for (var i = enemies.length - 1; i >= 0; --i) { var e = enemies[i]; e.update(); // Check if reached center (game over) var dx = e.x - CENTER_X; var dy = e.y - CENTER_Y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 100 && e.state !== 2) { // Game over LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); return; } } // Laser collision var anyLaserHit = false; for (var j = enemies.length - 1; j >= 0; --j) { var e2 = enemies[j]; if (e2.state === 2) continue; // Already dying if (pointInLaser(e2.x, e2.y)) { // If protected, can't be hit if (e2.isProtected) { // Show shield effect e2.setShield(true); continue; } // Wizards: die in one hit if (e2.isWizard) { e2.setState(2); e2.fadeTimer = 0; e2.removeShieldedEnemy(); LK.getSound('wizard_down').play(); score += 5; scoreTxt.setText(score); if (score > highScore) { highScore = score; storage.highScore = highScore; highScoreTxt.setText('En Yüksek: ' + highScore); } anyLaserHit = true; continue; } // Fast enemy: 1 hit to die if (e2 instanceof FastEnemy) { e2.setState(2); e2.fadeTimer = 0; LK.getSound('enemy_down').play(); score += 2; scoreTxt.setText(score); if (score > highScore) { highScore = score; storage.highScore = highScore; highScoreTxt.setText('En Yüksek: ' + highScore); } anyLaserHit = true; continue; } // Tank enemy: 3 hits to die if (e2 instanceof TankEnemy) { if (e2.state !== 2) { e2.tankHits += 1; if (e2.tankHits < 3) { e2.setState(0); LK.getSound('laser_hit').play(); } else { e2.setState(2); e2.fadeTimer = 0; LK.getSound('enemy_down').play(); score += 4; scoreTxt.setText(score); if (score > highScore) { highScore = score; storage.highScore = highScore; highScoreTxt.setText('En Yüksek: ' + highScore); } } anyLaserHit = true; continue; } } // Exploder enemy: 1 hit to die, but will explode (handled in removeEnemy) if (e2 instanceof ExploderEnemy) { e2.setState(2); e2.fadeTimer = 0; LK.getSound('enemy_down').play(); score += 3; scoreTxt.setText(score); if (score > highScore) { highScore = score; storage.highScore = highScore; highScoreTxt.setText('En Yüksek: ' + highScore); } anyLaserHit = true; continue; } // Normal enemy: 2 hits to die if (e2.state === 0) { e2.setState(1); LK.getSound('laser_hit').play(); anyLaserHit = true; } else if (e2.state === 1) { e2.setState(2); e2.fadeTimer = 0; LK.getSound('enemy_down').play(); score += 1; scoreTxt.setText(score); if (score > highScore) { highScore = score; storage.highScore = highScore; highScoreTxt.setText('En Yüksek: ' + highScore); } anyLaserHit = true; } } else { // Not hit, remove shield effect if any if (!e2.isWizard && !e2.isProtected) { e2.setShield(false); } } } // Remove dead enemies for (var k = enemies.length - 1; k >= 0; --k) { var e3 = enemies[k]; // Exploder enemy: explode on death if (e3 instanceof ExploderEnemy && e3.state === 2 && e3.fadeTimer === 22) { // Check if player is close to explosion var dx = e3.x - CENTER_X; var dy = e3.y - CENTER_Y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 220) { LK.effects.flashScreen(0xff6600, 1000); LK.showGameOver(); return; } // Optionally, damage other enemies in radius (not implemented for simplicity) } if (e3.state === 2 && (e3 instanceof FastEnemy && e3.fadeTimer > 18 || e3 instanceof TankEnemy && e3.fadeTimer > 40 || e3 instanceof ExploderEnemy && e3.fadeTimer > 22 || !(e3 instanceof FastEnemy) && !(e3 instanceof TankEnemy) && !(e3 instanceof ExploderEnemy) && e3.fadeTimer > 30)) { removeEnemy(e3); } } // If all enemies gone, spawn next wave var living = 0; for (var m = 0; m < enemies.length; ++m) { if (enemies[m].state !== 2) living += 1; } if (living === 0) { spawnWaveTimer += 1; if (spawnWaveTimer > 40) { spawnWave(); spawnWaveTimer = 0; } } else { spawnWaveTimer = 0; } // (Removed wave-based win condition so game continues indefinitely) }; // Start first wave spawnWave(); scoreTxt.setText(score); // Play action-packed background music LK.playMusic('action_bgmusic');
===================================================================
--- original.js
+++ change.js
@@ -189,8 +189,128 @@
self.setShield(false);
};
return self;
});
+// --- Dangerous Enemy Types ---
+// Fast enemy: moves faster, dies in 1 hit, red color
+// Tank enemy: moves slow, takes 3 hits, purple color
+// Exploder enemy: explodes on death, orange color
+// Tank Enemy
+var TankEnemy = Enemy.expand(function () {
+ var self = Enemy.call(this);
+ self.tankHits = 0; // 0,1,2,3 (3rd is death)
+ self.speed = 1.2 + Math.random() * 0.5;
+ self.setState = function (state) {
+ self.state = state;
+ if (self.enemyAsset) self.enemyAsset.destroy();
+ if (self.tankHits === 0) {
+ self.enemyAsset = self.attachAsset('enemy_tank', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ } else if (self.tankHits === 1) {
+ self.enemyAsset = self.attachAsset('enemy_tank_dmg1', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ } else if (self.tankHits === 2) {
+ self.enemyAsset = self.attachAsset('enemy_tank_dmg2', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ } else {
+ self.enemyAsset = self.attachAsset('enemy_fading', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ }
+ };
+ self.update = function () {
+ var dx = 1024 - self.x;
+ var dy = 1366 - self.y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist > 0) {
+ var moveDist = Math.min(self.speed, dist);
+ self.x += dx / dist * moveDist;
+ self.y += dy / dist * moveDist;
+ }
+ if (self.state === 2) {
+ self.fadeTimer += 1;
+ if (self.fadeTimer > 40) {
+ self.destroy();
+ } else {
+ self.alpha = 1 - self.fadeTimer / 40;
+ }
+ }
+ };
+ return self;
+});
+// --- Dangerous Enemy Classes ---
+// Fast Enemy
+var FastEnemy = Enemy.expand(function () {
+ var self = Enemy.call(this);
+ self.speed = 5 + Math.random() * 2;
+ self.setState = function (state) {
+ self.state = state;
+ if (self.enemyAsset) self.enemyAsset.destroy();
+ self.enemyAsset = self.attachAsset('enemy_fast', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ };
+ // Only 1 hit to die
+ self.update = function () {
+ var dx = 1024 - self.x;
+ var dy = 1366 - self.y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist > 0) {
+ var moveDist = Math.min(self.speed, dist);
+ self.x += dx / dist * moveDist;
+ self.y += dy / dist * moveDist;
+ }
+ if (self.state === 2) {
+ self.fadeTimer += 1;
+ if (self.fadeTimer > 18) {
+ self.destroy();
+ } else {
+ self.alpha = 1 - self.fadeTimer / 18;
+ }
+ }
+ };
+ return self;
+});
+// Exploder Enemy
+var ExploderEnemy = Enemy.expand(function () {
+ var self = Enemy.call(this);
+ self.speed = 2.5 + Math.random() * 1.2;
+ self.setState = function (state) {
+ self.state = state;
+ if (self.enemyAsset) self.enemyAsset.destroy();
+ self.enemyAsset = self.attachAsset('enemy_exploder', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ };
+ self.update = function () {
+ var dx = 1024 - self.x;
+ var dy = 1366 - self.y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist > 0) {
+ var moveDist = Math.min(self.speed, dist);
+ self.x += dx / dist * moveDist;
+ self.y += dy / dist * moveDist;
+ }
+ if (self.state === 2) {
+ self.fadeTimer += 1;
+ if (self.fadeTimer > 22) {
+ self.destroy();
+ } else {
+ self.alpha = 1 - self.fadeTimer / 22;
+ }
+ }
+ };
+ return self;
+});
/****
* Initialize Game
****/
@@ -200,8 +320,12 @@
/****
* Game Code
****/
+// Exploder enemy: explodes on death, orange color
+// Tank enemy: moves slow, takes 3 hits, purple color
+// Fast enemy: moves faster, dies in 1 hit, red color
+// --- Dangerous Enemy Types ---
// Center of screen
// Main character (center)
// Lazer beam (thin, long rectangle)
// Enemy: normal
@@ -268,19 +392,39 @@
highScoreTxt.y = 110; // Place below the main score
LK.gui.top.addChild(highScoreTxt);
// Helper: spawn a single enemy at random angle/distance
function spawnEnemy(type) {
- var enemy = new Enemy();
- enemy.isWizard = type === 'wizard';
- enemy.setState(enemy.isWizard ? 0 : 0);
+ var enemy;
+ if (type === 'wizard') {
+ enemy = new Enemy();
+ enemy.isWizard = true;
+ enemy.setState(0);
+ } else if (type === 'fast') {
+ enemy = new FastEnemy();
+ enemy.setState(0);
+ } else if (type === 'tank') {
+ enemy = new TankEnemy();
+ enemy.setState(0);
+ } else if (type === 'exploder') {
+ enemy = new ExploderEnemy();
+ enemy.setState(0);
+ } else {
+ enemy = new Enemy();
+ enemy.setState(0);
+ }
// Spawn at random angle, at edge of screen
var angle = Math.random() * Math.PI * 2;
var dist = 1200 + Math.random() * 400;
enemy.x = CENTER_X + Math.cos(angle) * dist;
enemy.y = CENTER_Y + Math.sin(angle) * dist;
enemy.angle = angle;
enemy.radius = dist;
- enemy.speed = 2 + Math.random() * 1.5 + (enemy.isWizard ? 0.5 : 0);
+ // Set speed for normal/wizard
+ if (type === 'wizard') {
+ enemy.speed = 2.5 + Math.random() * 1.2;
+ } else if (type === 'normal') {
+ enemy.speed = 2 + Math.random() * 1.5;
+ }
game.addChild(enemy);
enemies.push(enemy);
return enemy;
}
@@ -321,17 +465,43 @@
}
}
// Helper: spawn a wave of enemies
function spawnWave() {
- var numEnemies = 3 + Math.floor(waveNumber * 0.7);
- var numWizards = Math.min(1 + Math.floor(waveNumber / 3), Math.floor(numEnemies / 3));
+ // After boss is defeated, scale up difficulty and spawn more dangerous enemies
+ var postBoss = bossDefeated && score >= 500;
+ var baseEnemies = 3 + Math.floor(waveNumber * 0.7);
+ var numEnemies = postBoss ? Math.floor(baseEnemies * (1.2 + (score - 500) / 1000)) : baseEnemies;
+ var numWizards = postBoss ? Math.floor(numEnemies * 0.08) : Math.min(1 + Math.floor(waveNumber / 3), Math.floor(numEnemies / 3));
+ // Dangerous enemy ratios
+ var fastRatio = postBoss ? Math.min(0.25 + (score - 500) / 2000, 0.45) : 0;
+ var tankRatio = postBoss ? Math.min(0.18 + (score - 500) / 3000, 0.32) : 0;
+ var exploderRatio = postBoss ? Math.min(0.12 + (score - 500) / 4000, 0.22) : 0;
+ // Normal enemies become rare
+ var normalRatio = 1 - (fastRatio + tankRatio + exploderRatio + numWizards / numEnemies);
+ // Clamp
+ if (normalRatio < 0.08) normalRatio = 0.08;
+ // Build enemy type pool
+ var pool = [];
+ for (var i = 0; i < Math.floor(numEnemies * fastRatio); ++i) pool.push('fast');
+ for (var i = 0; i < Math.floor(numEnemies * tankRatio); ++i) pool.push('tank');
+ for (var i = 0; i < Math.floor(numEnemies * exploderRatio); ++i) pool.push('exploder');
+ for (var i = 0; i < Math.floor(numEnemies * normalRatio); ++i) pool.push('normal');
+ // Fill up to numEnemies
+ while (pool.length < numEnemies) pool.push('normal');
+ // Shuffle pool
+ for (var i = pool.length - 1; i > 0; --i) {
+ var ri = Math.floor(Math.random() * (i + 1));
+ var tmp = pool[i];
+ pool[i] = pool[ri];
+ pool[ri] = tmp;
+ }
// Spawn wizards
for (var i = 0; i < numWizards; ++i) {
spawnEnemy('wizard');
}
- // Spawn normal enemies
- for (var j = 0; j < numEnemies; ++j) {
- spawnEnemy('normal');
+ // Spawn from pool
+ for (var j = 0; j < pool.length; ++j) {
+ spawnEnemy(pool[j]);
}
assignWizards();
waveNumber += 1;
}
@@ -504,22 +674,73 @@
// Wizards: die in one hit
if (e2.isWizard) {
e2.setState(2);
e2.fadeTimer = 0;
- // Remove shield from protected enemy
e2.removeShieldedEnemy();
LK.getSound('wizard_down').play();
score += 5;
scoreTxt.setText(score);
- // Update high score if needed
if (score > highScore) {
highScore = score;
storage.highScore = highScore;
highScoreTxt.setText('En Yüksek: ' + highScore);
}
anyLaserHit = true;
continue;
}
+ // Fast enemy: 1 hit to die
+ if (e2 instanceof FastEnemy) {
+ e2.setState(2);
+ e2.fadeTimer = 0;
+ LK.getSound('enemy_down').play();
+ score += 2;
+ scoreTxt.setText(score);
+ if (score > highScore) {
+ highScore = score;
+ storage.highScore = highScore;
+ highScoreTxt.setText('En Yüksek: ' + highScore);
+ }
+ anyLaserHit = true;
+ continue;
+ }
+ // Tank enemy: 3 hits to die
+ if (e2 instanceof TankEnemy) {
+ if (e2.state !== 2) {
+ e2.tankHits += 1;
+ if (e2.tankHits < 3) {
+ e2.setState(0);
+ LK.getSound('laser_hit').play();
+ } else {
+ e2.setState(2);
+ e2.fadeTimer = 0;
+ LK.getSound('enemy_down').play();
+ score += 4;
+ scoreTxt.setText(score);
+ if (score > highScore) {
+ highScore = score;
+ storage.highScore = highScore;
+ highScoreTxt.setText('En Yüksek: ' + highScore);
+ }
+ }
+ anyLaserHit = true;
+ continue;
+ }
+ }
+ // Exploder enemy: 1 hit to die, but will explode (handled in removeEnemy)
+ if (e2 instanceof ExploderEnemy) {
+ e2.setState(2);
+ e2.fadeTimer = 0;
+ LK.getSound('enemy_down').play();
+ score += 3;
+ scoreTxt.setText(score);
+ if (score > highScore) {
+ highScore = score;
+ storage.highScore = highScore;
+ highScoreTxt.setText('En Yüksek: ' + highScore);
+ }
+ anyLaserHit = true;
+ continue;
+ }
// Normal enemy: 2 hits to die
if (e2.state === 0) {
e2.setState(1);
LK.getSound('laser_hit').play();
@@ -529,9 +750,8 @@
e2.fadeTimer = 0;
LK.getSound('enemy_down').play();
score += 1;
scoreTxt.setText(score);
- // Update high score if needed
if (score > highScore) {
highScore = score;
storage.highScore = highScore;
highScoreTxt.setText('En Yüksek: ' + highScore);
@@ -547,9 +767,22 @@
}
// Remove dead enemies
for (var k = enemies.length - 1; k >= 0; --k) {
var e3 = enemies[k];
- if (e3.state === 2 && e3.fadeTimer > 30) {
+ // Exploder enemy: explode on death
+ if (e3 instanceof ExploderEnemy && e3.state === 2 && e3.fadeTimer === 22) {
+ // Check if player is close to explosion
+ var dx = e3.x - CENTER_X;
+ var dy = e3.y - CENTER_Y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist < 220) {
+ LK.effects.flashScreen(0xff6600, 1000);
+ LK.showGameOver();
+ return;
+ }
+ // Optionally, damage other enemies in radius (not implemented for simplicity)
+ }
+ if (e3.state === 2 && (e3 instanceof FastEnemy && e3.fadeTimer > 18 || e3 instanceof TankEnemy && e3.fadeTimer > 40 || e3 instanceof ExploderEnemy && e3.fadeTimer > 22 || !(e3 instanceof FastEnemy) && !(e3 instanceof TankEnemy) && !(e3 instanceof ExploderEnemy) && e3.fadeTimer > 30)) {
removeEnemy(e3);
}
}
// If all enemies gone, spawn next wave